welcome_sk的个人空间 https://bbs.21ic.com/?1592206 [收藏] [复制] [RSS]

日志

嵌入式编程规范

已有 5629 次阅读2019-2-22 09:43 |个人分类:GD32F103|系统分类:ARM

目的

        规范是经验的积累,需要慢慢用心去体会。

规范1. 原则
  1. 简洁明了,提高代码可读性,读的是代码而不是注释,注释永远都是辅助的。

  2. 零告警,严谨的语法才能保障代码表达和编译器理解的是一至的。

2. 排版
  1. 缩进4空格,杜绝tab键

  2. 程序块之间、变量声明之间,用空行分隔

  3. 突出语法关键字

  4. 一行不要太长,换行增加可读性

3. 注释
  1. 注释的目的是阐明意图目的,而不是翻译某行代码的动作

  2. 注释的原则是尽量代码自注释,代码越清晰,可读性越高

  3. 统一格式 /* 注释内容 */, *号与注释内容之间有一个空格

4. 定义
  1. 命名风格

    1. 模块名+文件名+功能描述,之间采用短下划线分隔

    2. 功能描述部分,采用驼峰风格

    例如,

    VOID OS_TASK_TaskDelay(IN U16 ms);
  2. 宏定义

    1. define 必须大写

    2. typedef 可以小写

    例如,

    #define OS_TASK_SWITCH_INTERVAL 10 /* 单位ms */
    typedef U32 StackSize_t;  /* 仅用于堆栈 */
  3. 类型定义

    统一使用下面的,编程最关心符号位和位宽

    #define U8  unsigned char
    #define S8  char
    #define U16 unsigned short
    #define S16 short
    #define U32 unsigned int
    #define S32 int
    #define U64 unsigned long long
    #define S64 long long
    #define VOID void
    #define BOOL unsigned char

    #define TRUE 1
    #define FALSE 0
    #define NULL 0
5. 变量
  1. 局部变量

    1. 在函数开始是全部定义,不允许在函数中间定义

    2. 命名必须能传达该变量使用的意图

    3. 必须初始化

  2. 全局变量

    1. 在C文件中,函数之前统一定义

    2. 命名必须能传达该变量的使用意图,且以g开头

    3. 本地全局变量必须用static关键字

    4. 开发给外部使用的全局变量,必须在头文件中声明,且使用extern关键字

    5. 必须初始化

6. 函数
  1. 函数名必须能够自注释,必要是需要增加注释写明意图

  2. 参数必须使用IN、OUT、INOUT指明出入参类型

  3. 内部函数必须使用static定义,命名可以不加模块名

  4. 外部函数

    1. 必须在头文件中声明,

    2. 必须使用extern关键字,

    3. 命名时必须带模块名,

    4. 必须给出带注释,并写明函数意图,参数说明,返回值

7. 文件
  1. 头文件

    1. 命名规则模块名+功能,小写,例如os_task.h

    2. 格式如下

      #ifndef __OS_TASK_H__
      #define __OS_TASK_H__

      ..../* 开放的宏定义 */
      ..../* 开放的全局变量声明 */
      ..../* 开放的函数声明 */

      #endif
  2. 源文件

    1. 命名规则模块名+功能,小写,例如os_task.c

    2. 格式如下,举例只为说明源文件中,各元素的顺序

      <- 1 - 引用头文件 ->
      #include "os_task.h"

      <- 2 - 定义本文件用到的宏 ->
      #define OS_TASK_SWITCH_INTERVAL 10 /* 单位ms */
      typedef U32 StackSize_t   /* 仅用于堆栈 */
      typedef enum{};
      typedef struct{};

      <- 3 - 静态全局变量 ->
      static StackSize_t *gTopStack = NULL;

      <- 4 - 本模块开放的全局变量 ->
      U32 gOsTaskEventBitMap = 0;

      <- 5 - 本地函数,仅在本文件使用 ->
      static VOID TASK_TaskSwitch(VOID)
      {
          return;
      }

      <- 6 - 本模块开放的函数 ->
      VOID OS_TASK_TaskDelay(IN U16 ms)
      {
         return;   
      }
8. 模块
  1. 模块必须具有封装性,且对外提供尽量少的必要接口,接口必须提供详细的注释描述

  2. 模块的组织形式可以是文件夹形式,也可以是文件形式

    例如:

    .
    ├── app /* 应用层代码 */
       ├── app.h
       ├── main.c /* 应用入口 */
       ├── test.c
       └── test.h
    ├── driver /* 设备驱动代码 */
       ├── drv_led.c
       ├── drv_led.h
       ├── drv_uart.c
       └── drv_uart.h
    ├── os  /* 操作系统代码 */
       ├── os_task.c
       ├── os_task.h
       └── os_type.h
    ├── sdk /* 芯片厂家提供的库代码 */
       ├── CMSIS
       └── Peripherals


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)