【嵌入式编程规范】仅供参考

一、背景与目标

  1. 背景
  • 代码规范的重要性
  • 代码能力
  1. 目标
  • 提升代码一致性
  • 提升代码可读性
  • 代码高内聚、低耦合

二、规范概览

1. 命名规则

  1. 文件命名规则(小写字母)
    业务相关文件:yj_ble_event.c
    解释:yj 公司名称缩写
    ble 所属模块
    event 功能内容
    业务无关:http_server_logs.h

  2. 函数命名规则
    - 函数名称可采用驼峰命名法
    - 首字母小写
    - 若命名过长可在字段中间加 _
    ble_otaStartHandle()
    setMotorSpeed()
    initHardware()
    publishLightValue()

  3. 变量命名规则

  • 全部小写,使用 _进行连接
  • 除非逻辑上需要,避免命名中出现数字编号。
    普通变量:
    int num_errors;
    int_num_conpleted_connections;
    不要使用缩写
    int error_count; //Good
    int error_cnt; //Bad
    全局变量:
    少用;加 g_
    常量:
    const int kDaysInAWeek = 7;
  1. 指针
    - 加前缀p/p_单词。全小写
  2. 宏定义
    - 全部大写,长字段使用_进行分割
    R_SPEED
    WIFI_SSID
    SYSTEM_VERSION
    CHINA_FOOTBALL
  3. 结构体
    - 单词首字母全大写,以_ST/_T结尾
    typedef struct{
    char *name;
    uint8_t name_len;
    uint8_t age;
    }Students_T
  4. 枚举
    - 单词首字母全大写,类型定义尾缀加_E

2. 编码方式

不同的编码方式会导致在工程合并时出现乱码的现象,限定公司的文件编码统一为UTF-8


3. 头文件

每个头文件的框架采用如下格式(举例的头文件名字为ESPJarvis.h)

#ifndef _ESPJARVIS_H 
#define _ESPJARVIS_H 
#ifdef __cplusplus
extern "C" {
#endif

头文件内容

#ifdef __cplusplus
}#endif
#endif        // _ESPJARVIS_H

使用 #ifdef __cplusplus 可以增加对C++项目引用的支持,当在一个C++项目引用这个头文件时,编译器能知道要按照C语言对此文件进行编译。

小贴士

使用 VSCode 开发的童鞋可以使用用户代码片段这个功能,新建的全局代码片段可以命名为snippet,每次创建新的头文件之后只需要输入def,IDE就能够自动提示选择插入相应的代码

{
    "#ifndef … #define … #endif":{
    "prefix": "def",
    "body": "#ifndef ${1:${TM_FILENAME_BASE/(.*)/_${1:/upcase}_H/i}} \n#define $1 \n#ifdef __cplusplus\nextern \"C\" {\n#endif\n${2:}\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif\t// $1"
}

全局代码片段功能 自动生成的代码效果如下 (创建的文件名称为test.h)

 #ifndef _TEST_H 
 #define _TEST_H 
 #ifdef __cplusplus
 extern "C" {
 #endif

 #ifdef __cplusplus
 }
 #endif
 #endif  // _TEST_H

以下是一些要点

  1. 头文件中放置接口的声明,不能放置实现
    每个.c文件应有一个同名.h文件,用于声明需对外公开的接口。
    只能通过包含.h文件的方式使用其他.c文件提供的接口,禁止在.c中extern使用外部接口。
  2. 头文件应尽可能少包含/依赖其他头文件
    接口声明与包含头文件过于复杂会导致编译时间过长。
    .c/.h文件禁止包含用不到的头文件。

4. 函数

  1. 一个功能函数仅实现一种功能
  • 一个功能函数尽可能具有通用性,不依赖函数输入外的变量。
  • 一般一个功能函数不能超过80-100行代码,如果过长要考虑功能拆分。
  • 一个函数尽可能不要依赖另一个函数去完成功能。
  • 一个函数内代码块嵌套不超过4层
  1. 冗余代码考虑提炼成函数(若一个处理流程重复了3次以上)
  • 编写函数时,逻辑与数据要分开。
  • 没有被调用的变量与函数要及时清除。
  1. 可重入函数不可使用共享变量
  • 若必须使用共享变量,应利用互斥手段(信号量、中断)进行保护。
  1. 内部函数应该增加 static 关键字
  • 声明源文件内可用,避免与其他文件或库中的相同标识符发生混淆。
  1. 函数内谨慎使用全局变量、静态局部变量和IO操作
  • 使用时需考虑函数可重入、函数功能可预测,以及IO操作混乱。
  1. 检查参数合法性由调用者还是接口函数完成,项目组应统一规定
  • 避免两者都进行参数的合法性检查,产生冗余代码。
  • 接口函数内应对全局变量、数据文件等非参数输入进行有效性的检查。

三、补充描述

质量保证

  1. 代码要具有正确性、简洁性、可维护、可测试、高性能、可移植性
  2. 操作符优先级不确定加括号
  3. 避免内存操作越界、内存泄露
    注意数组分配内存、数组下标、指针加减操作、字符串操作等。
    函数异常出口出要判断资源是否全部释放。
    禁止使用已经被释放的内存。
    代码编辑、编译
  4. 理解所有警告,修改代码消除所有警告
    降低警告级别从而消除警告是不可取的。
    要统一编译开关、静态检查选项和告警清除策略。
  5. 本地构建工具的配置与持续集成的一致
    通过本地构建的代码要及时签入版本控制系统。

如有纰漏、还请多多包涵、欢迎指正并补充

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值