打印
[其它产品/技术]

嵌入式编码规范

[复制链接]
1001|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
OKAKAKO|  楼主 | 2023-12-22 15:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、文件头申明
◎ 新增.c必须添加注释,标注公司名称、文件功能说明,创建日期、作者,后续修改说明 范例如下:

/*********************************************************************     
* Copyright (c)  Hehe,Ltd. All rights reserved.
* Description:用于详细说明此程序文件完成的主要功能,
*             与其他模块或函数的接口依赖等关系           
*
* History:修改历史记录列表,包括修改日期、修改者及修改内容简述                    
* Date               Author                Modification:                                                                     
* 2023-11-25        embedded-system        create v1.0
*********************************************************************/

可配置Source Insight 自动生成模板。



使用特权

评论回复
沙发
OKAKAKO|  楼主 | 2023-12-22 15:24 | 只看该作者
本帖最后由 OKAKAKO 于 2023-12-22 15:26 编辑

2、文件
◎ 所有.h头文件必须采取阻止内容被包含多于一次的机制。
#ifndef __XXX__

#define __XXX__

#endif  /*__XXX__*/
◎ 头文件对外接口,应放置对外部的声明,如对外提供的函数声明、宏定义、类型定义等。
◎ 内部使用的函数声明不应放在头文件中。
◎ 内部使用的宏、枚举、结构定义不应放入头文件中。
◎ 变量定义禁止在头文件中,应放在.c文件中。
◎ 模块内使用的全局变量,不应通过在头文件中声明的方式直接暴露给外部。
◎ 头文件中只包含接口的声明,不含实现。
◎ 头文件应当职责单一,头文件过于复杂,依赖过于复杂是导致编译时间过长的主要原因。
◎ 每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口。
◎ 禁止头文件循环依赖,禁止包含用不到的头文件。
◎ 每个.c源文件内容片段按如下顺序,文件注释-包含头文件-宏定义-数据结构定义-变量定义-引用外部变量-引用外部函数-本地函数-全局函数。




使用特权

评论回复
板凳
OKAKAKO|  楼主 | 2023-12-22 15:25 | 只看该作者
3、函数

◎ 一个函数仅完成一件功能。

◎ 重复代码应该尽可能提炼成函数(说明:重复代码提炼成函数可以带来维护成本的降低。重复代码是不良代码最典型的特征之一。在“代码能用就不改”的指导原则之下,新需求增加带来的代码拷贝和修改,随着时间的迁移,产品中堆砌着许多类似或者重复的代码。)

◎ 避免递归函数的代码块嵌套过深。

◎ 对函数的错误返回码要全面处理(说明:一个函数(标准库中的函数/第三方库函数/用户定义的函数)能够提供一些指示错误发生的方法,可以通过使用错误标记、特殊的返回数据或者其他手段,调用程序应该在函数返回时立刻检查错误指示。)

◎ 废弃函数要及时清除(说明:程序中的废弃代码不仅占用额外的空间,而且还常常影响程序的功能与性能,很可能给程序的测试、维护等造成不必要的麻烦。)

◎ 函数传入的不变参数使用const限制。

◎ 函数的参数个数不超过5个,检查输入参数的有效性(说明:函数的参数过多,会使得该函数易于受外部(其他部分的代码)变化的影响,从而影响维护工作。函数的参数过多同时也会增大测试的工作量。函数的参数个数不要超过5个,如果超过了建议拆分为不同函数;函数的输入主要有两种:一种是参数输入;另一种是全局变量、数据文件的输入,即非参数输入。函数在使用输入参数之前,应进行有效性检查。)

◎ 源文件范围内声明和定义的所有函数,除非外部可见,否则增加static关键字,针对单元测试的特殊情况,对这类函数尽量封装一层再使用。

◎ 传入参数表意有3种以上的禁止使用魔法数,必须使用枚举值且附带注释。

◎ 函数内部要对参数的合法性进行检查(说明:函数的输入主要有两种:一种是参数输入;另一种是全局变量、数据文件的输入,即非参数输入。函数在使用输入参数之前,应进行有效性检查。)

◎ 除打印类函数外,不要使用可变长函数(说明:可变长参函数的处理过程比较复杂容易引入错误,而且性能也比较低,使用过多的可变长参函数将导致函数的维护难度大大增加。)

◎ 每个函数都要返回错误码,调用程序必须在函数返回时检查错误码。

◎ 标识符的命名要清晰明了,有明确含义,使用完整的单词,尽量避免名字中出现数字编号或特殊符号。

◎ 函数名称需体现出函数具体功能,均由功能单词拼接组成,绝不允许出现中文拼音。

◎ 函数命名应以函数要执行的动作命名,一般采用动词或者动词+名词的结构。



使用特权

评论回复
地板
两只袜子| | 2023-12-22 15:27 | 只看该作者
嵌入式入门必学

使用特权

评论回复
5
OKAKAKO|  楼主 | 2023-12-22 15:29 | 只看该作者
4、变量
◎ 不用或者少用全局变量(说明:单个文件内部可以使用static的全局变量,可以将其理解为类的私有成员变量。全局变量应该是模块的私有数据,不能作用对外的接口使用,使用static类型定义,可以有效防止外部文件的非正常访问。直接使用其他模块的私有数据,将使模块间的关系逐渐走向“剪不断理还乱”的耦合状态,这种情形是不允许的。)
◎ 避免局部变量与全局变量同名(说明:尽管局部变量和全局变量的作用域不同而不会发生语法错误,但容易使人误解。)
◎ 严禁使用未经初始化的变量。
◎ 明确全局变量的初始化顺序,避免跨模块的初始化依赖(说明:系统启动阶段,使用全局变量前,要考虑到该全局变量在什么时候初始化,两者之间的时序关系,谁先谁后,一定要分析清楚,不然后果往往是低级而又灾难性的。)
◎ 数据必须对外开放时,应封装接口函数来读写,同时注意全局数据的访问互斥(说明:避免直接暴露内部数据给外部模型使用,是防止模块间耦合最简单有效的方法。)
◎ 一个变量只有一个功能,不能把一个变量用作多种用途(说明:一个变量只用来表示一个特定功能,不能把一个变量作多种用途,即同一变量取值不同时,其代表的意义也不同。)
◎ 数据结构功能单一,不要设计面面俱到的数据结构(说明:相关的一组信息才是构成一个结构体的基础,结构的定义应该可以明确的描述一个对象,而不是一组相关性不强的数据的集合。设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构体中。)
◎ 尽量减少没有必要的数据类型默认转换与强制转换(说明:当进行数据类型强制转换时,其数据的意义、转换后的取值等都有可能发生变化,而这些细节若考虑不周,就很有可能留下隐患。)
示例:如下赋值,多数编译器不产生告警,但值的含义有变化。
<p>char ch; </p><p>unsigned short int exam;  </p><p>ch = -1;</p><p>exam = ch; // 编译器不产生告警,此时exam为0xFFFF。 </p>
◎ 确认未使用的变量应当删除。
◎ 对于变量自增++和自减--,禁止在宏定义中使用,禁止和其他语句复合,因拆分单独执行。
示例:if(++i>10) 错误写法,必须改为i++;if(i>10)

使用特权

评论回复
6
OKAKAKO|  楼主 | 2023-12-22 15:29 | 只看该作者
5、宏和常量
◎ 宏定义和常量使用大写字母或下划线。
◎ 用宏定义表达式时,要使用完备的括号,如下:
#define HEHE_AREA(a, b) ((a) * (b)) 

◎ 宏定义中尽量不要使用return、goto、continue、break等改变程序流程的语句。
◎ 常量建议使用const定义代替宏,如下:
#define ASPECT_RATIO 1.653 替换成 const double ASPECT_RATIO = 1.653; 

◎ 除非必要,应尽可能使用函数代替宏 。
◎ 将宏定义的多条表达式放在大括号中。
◎ 使用宏时,不允许参数发生变化。
◎ 尽量少用魔法数,或者必须加注释说明,或者修改方案,如内存长度操作禁止使用常数,非特殊情况必须使用sizeof自动处理。

使用特权

评论回复
7
OKAKAKO|  楼主 | 2023-12-22 15:30 | 只看该作者
6、命名

命名采用unix like风格,单词用小写字母,每个单词之间用下划线分割,引用的第三方的代码可保持原有风格,命名尽量使用通用英文单词或缩写。

文件:文件名命名可根据平台自有规则命名,一般采用小写字符,字段之间使用下划线分隔;相同功能的 .c和.h文件名相同。

枚举:宏定义和枚举值禁止使用小写字母,不能以下划线开头,字段之间使用下划线分隔,若逻辑中要标注多种状态,状态不允许用数字表示。

结构体:若同一功能所使用到的参数,尽量用结构体来定义表示,便于相关参数获取和设置。纯业务逻辑代码,与平台无关的,必须使用小写字符和下划线分隔。

函数:函数名称需体现出函数具体功能,均由功能单词拼接组成,使用小写字母和下划线拼接,其中全局函数必须以xx_为前缀,在.h里面申明全局函数,补充完整注释;局部函数使用static限制。

变量:注意事项如下:



◎ 禁止使用全大写字母命名变量,全局变量至少5个字母,使用高频次的全局变量尽量简短。

◎ 全局变量命名表达其作用,且以小写字母g_开头,后面拼接功能英文,如地址:g_addr。

◎ 变量名的拼接,全部使用小写字母和下划线拼接,函数内局部变量允许使用单个字母。

◎ 多个同类的变量封装成结构体。



推荐命名:



add/delete  begin/end  create/destroy  insert/delete



first/last  increment/decrement  get/set/release  up/down



lock/unlock  open/close  min/max  old/new



start/stop  next/previous  source/target  send/receive



使用特权

评论回复
8
OKAKAKO|  楼主 | 2023-12-22 15:31 | 只看该作者
7、注释



◎ 注释应放在其代码上方相邻位置或右方,不可放在下面。

◎ 注释的内容要清楚明了,防止注释二义性。

◎ 修改代码时同步更新注释,保证注释与代码的一致性。

◎ 函数声明处注释描述函数功能、性能及用法,提供参考范本如下:

/**



* [url=home.php?mod=space&uid=247401]@brief[/url]    函数功能



* @params



* @return



* @par history



*   xx create  @2023-xx-xx



*/



◎ 全局变量要有较详细的注释。

◎ 函数内部注释:函数内部不是注释越多越好,而是变量命名和逻辑清晰,自注释最好,特殊情况或者需要特别注意的地方才加注释,并且注释要放在代码行的上方。

◎ 基于SDK开发,在基线工程上改动代码,不允许删除源代码,修改代码必须增加注释,必须使用关键字“XX_CODE”标注修改原因,方便后续打补丁,范例如下:

/**** XX_CODE begin ****/



/*修改原因,作者,时间*/



<代码块>



/**** XX_CODE end ****/




对于非c源码的文件,在这个注释格式的基础上,每行添加对应的注释符号。

◎ 修改与外设驱动、通信协议、系统底层等相关的代码,具有特殊隐含限制的代码,必须提交详细的修改原因,便于后续版本回溯查找原因。

◎ 复杂且相对独立的功能,单独使用markdown文档说明开发方案、实现技术、应用场景、使用限制等,随代码提交。

8、排版与格式

◎ 程序块釆用缩进风格编写,每级缩进为4个空格。

◎ 相对独立的程序块之间、变量说明之后必须加空行。

◎ 多个短语句不允许写在同一行内,长语句不能拆分需要分行写。

◎ if、for、do、while、case、switch、default等语句独占一行,{换行且独占一行。

◎ 赋值语句不要写在if等语句中,或者作为函数的参数使用。

◎ 逻辑表达式每个子项都使用()。

◎ if与else if/else必须以’{}’分隔,且 ‘{’与‘}’各占一行,if-else分3层以上必须以else子句结束,即使操作为空,并增加注释://do nothing



if(var==xx)

{
  …
}

else if (var==yy)
{
  …

}

else if (var==zz)

{
  …

}

else

{
  //do nothing

}


◎ switch语句必须有default分支。

◎ 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时(如->),后面不应加空格。

◎ 文件编写完成后,统一使用Astyle自动格式化工具整理一遍再提交到版本库。



astyle.exe --style=allman -S -U -t -n -K -p -s4 -j -q -Y -xW -xV


使用特权

评论回复
9
MessageRing| | 2023-12-26 10:13 | 只看该作者
必须要掌握的知识点

使用特权

评论回复
10
LOVEEVER| | 2024-1-25 12:21 | 只看该作者
规范是前提

使用特权

评论回复
11
星辰大海不退缩| | 2024-1-28 15:50 | 只看该作者
嵌入式编码规范习惯很重要

使用特权

评论回复
12
小夏天的大西瓜| | 2024-1-28 16:02 | 只看该作者
各种规范才是通俗易懂的前提

使用特权

评论回复
13
代码输出机| | 2024-1-29 18:11 | 只看该作者
之前好像是华为出了一版的编程规范

使用特权

评论回复
14
szt1993| | 2024-1-29 22:23 | 只看该作者
编程规范都是基础的必学课程

使用特权

评论回复
15
jf101| | 2024-1-29 22:36 | 只看该作者
宏和常量一定要明显区别

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

209

主题

1446

帖子

4

粉丝