查看: 1378|回复: 2

恩智浦SDK驱动代码风格、模板、检查工具

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3301

    主题

    6548

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32040
    最后登录
    2024-4-28
    发表于 2020-3-17 10:27:40 | 显示全部楼层 |阅读模式
    恩智浦SDK驱动代码风格、模板、检查工具


    上周痞子衡受领导指示,给 SE 同事做了一个关于 SDK 代码风格的分享。随着组内新人的增多,这样的培训还是很有必要的。一是可以让新同事通过代码风格来快速了解 SDK 驱动代码结构,另一方面也有利于新同事养成良好的编码习惯。
      痞子衡刚毕业时曾经也整理过一篇代码风格 《飞思卡尔软件开发C语言编码规范》,如今虽已是恩智浦纪元,但规范大多还是相似的,仅有微小更新。这次痞子衡将新版规范的要点提取了出来,并且还提供了标准模板,这样大家学习起来更加方便。
      另外鉴于领导指定我作为组内同事代码风格人肉审查员(大家写好的代码需要由我人肉审查风格),这样的工作如果真的完全是人工去做,可想而言有多枯燥和低效,因此痞子衡计划写一个配套的自动化检查工具,暂且叫 MCUXpresso SDK Coding Style Checker,欢迎大家来围观这个项目。

    项目地址:http://github.com/JayHeng/MCUX-SDK-Coding-Style

    mcux_sdk_coding_style
    1.命名
    1.1 变量
    变量命名使用 CamelCase (小骆驼峰法),即第一个单词以小写字母开始,第二个单词以及后面的每一个单词的首字母大写,例如 myVariableName

    作用域可在文件外的全局变量加 g_ 前缀,如 g_myVariableName

    使用 static 修饰的全局变量加 s_ 前缀,如 s_myVariableName

    局部变量不加任何前缀,如 myVariableName

    其他如 volatile, const 修饰或指针型变量,无需任何特殊表示

    命名中的大部分单词都不要缩写,除非是相当流行的缩写,如 init 或 config

    1.2 宏
    宏命名使用下划线命名法,单词全大写,例如 MY_MACRO_NAME

    1.3 枚举
    枚举类型的命名混合了多种命名法,且加了一些特殊前后缀

    枚举类型名使用下划线命名法,单词全小写,且以下划线开头

    枚举元素名使用小骆驼峰法,但统一加 k 前缀

    可用 typedef 重命名枚举类型名,使用下划线命名法,但需加 _t 后缀

    枚举变量名使用小骆驼峰法
    1. <font size="3" face="微软雅黑">typedef enum _my_enumeration_name
    2. {
    3.     kMyEnumerator0     = 0x00U,
    4.     kMyEnumerator1     = 0x01U,

    5.     kMyEnumeratorEnd   = 0x02U,
    6. } my_enumeration_name_t;

    7. static my_enumeration_name_t s_myEnumVariableName;</font>
    复制代码
    1.4 结构体
    结构体类型的命名混合了多种命名法,且加了一些特殊前后缀

    结构体类型名使用下划线命名法,单词全小写,且以下划线开头

    结构体成员名使用小骆驼峰法

    可用 typedef 重命名结构体类型名,使用下划线命名法,但需加 _t 后缀

    结构体变量名使用小骆驼峰法
    1. <font size="3" face="微软雅黑">typedef struct _my_struct_name
    2. {
    3.     uint32_t myStructMember0;
    4.     uint32_t myStructMember1;
    5. } my_struct_name_t;

    6. static my_struct_name_t s_myStructVariableName;</font>
    复制代码
    1.5 函数
    函数命名使用 Pascal (大骆驼峰法),即把变量名称的第一个字母也大写,例如 MyFunctionName

    函数命名可由 [Action][Module][Feature] 组成,动作在前,特性在后。如 InitDeviceClock()

    一系列同类函数,可加 MODULE_ 前缀,前缀单词全大写。如 SD 卡操作的系列函数,可为 SD_PowerOnCard()、SD_PowerOffCard()

    2.代码体
    2.1 排版
    永远不要使用 Tab 键(使用 4 个空格代替 Tab),需要以 4 个空格为单位的缩进

    换行符应使用 "unix"(LF),而不是windows(CR + LF)

    文件结尾需空一行

    2.2 花括号
    不使用 K&R 风格花括号,左右括号都需要独占一行

    2.3 局部变量定义
    局部变量定义应总是放在所在最小作用域(即最近的 {} 内)里的最前面,并且一行代码仅定义一个变量
    1. <font size="3" face="微软雅黑">void MyFunctionName(void)
    2. {
    3.     uint8_t myVariableName0;
    4.     uint8_t myVariableName1;

    5.     /* 代码体 */

    6.     for (;;)
    7.     {
    8.         uint8_t myVariableName2;

    9.         /* 代码体 */
    10.     }
    11. }</font>
    复制代码
    2.4 数字
    代码中所有无符号整型数字,均应加 "U" 后缀
    1. <font size="3" face="微软雅黑">Hex: 0x1234ABCDU
    2. Dec: 1234U
    3. </font>
    复制代码
    2.5 注释
    仅使用 /* */ 来注释
    1. <font size="3" face="微软雅黑">/* 注释风格1,单独占一行 */
    2. uint8_t i = 0;

    3. for (; i < 5;)
    4. {
    5.     i++; /* 注释风格2,与代码共享一行 */
    6. }</font>
    复制代码
    2.6 条件编译
    #endif 后面需要加如下注释
    1. <font size="3" face="微软雅黑">#if MY_MACRO_NAME

    2. /* 代码体 */

    3. #endif /* MY_MACRO_NAME */</font>
    复制代码
    2.7 头文件保护宏
    任何一个 .h 文件都需要包含下面格式的头文件保护宏代码,宏的命名与头文件名保持一致。如文件名为 hello_world.h,则宏名为 _HELLO_WORLD_H_
    1. <font size="3" face="微软雅黑">#ifndef _HEADER_FILENAME_
    2. #define _HEADER_FILENAME_

    3. /* 头文件内容 */

    4. #endif /* _HEADER_FILENAME_ */</font>
    复制代码
    3.整体模板3.1 源文件(.c)
    1. <font size="3" face="微软雅黑">/* 包含头文件代码 */

    2. #include "template.h"

    3. /*******************************************************************************
    4. * Definitions
    5. ******************************************************************************/

    6. /* 私有(仅本源文件内使用)宏、枚举、结构体的定义 */

    7. #define MAX_DEVICES  (128U)

    8. /*******************************************************************************
    9. * Variables
    10. ******************************************************************************/

    11. /* 所有全局变量(外部,静态,常量,指针)的定义 */

    12. uint32_t g_deviceIndex = 0;

    13. static device_config_t s_deviceConfig;

    14. const uint32_t g_maxDevices = MAX_DEVICES;

    15. static volatile uint8_t *s_deviceData;

    16. /*******************************************************************************
    17. * Prototypes
    18. ******************************************************************************/

    19. /* 内部函数(即 static 修饰)的声明 */

    20. static uint32_t GetDeviceIndex(void);

    21. /*******************************************************************************
    22. * Code
    23. ******************************************************************************/

    24. /* 所有函数(外部,内部)的定义 */

    25. void InitDevice(void)
    26. {
    27.     s_deviceConfig.index = 1;
    28.     s_deviceConfig.mode = kDeviceMode1;
    29.     memset(s_deviceConfig.data, 5, sizeof(s_deviceConfig.data));
    30.     s_deviceConfig.isEnabled = true;
    31. }

    32. static uint32_t GetDeviceIndex(void)
    33. {
    34.     return s_deviceConfig.index;
    35. }

    36. int main(void)
    37. {
    38.     InitDevice();
    39.     g_deviceIndex = GetDeviceIndex();

    40.     while (1)
    41.     {
    42.     }
    43. }</font>
    复制代码
    3.2 头文件(.h)
    1. <font size="3" face="微软雅黑">/*
    2. * Copyright xxx
    3. * All rights reserved.
    4. *
    5. * xxx License
    6. *
    7. * Revision History:
    8. * v1.0 - Description
    9. */

    10. #ifndef _TEMPLATE_H_
    11. #define _TEMPLATE_H_

    12. /* 包含头文件代码 */

    13. #include <stdbool.h>
    14. #include <stdint.h>
    15. #include <string.h>

    16. /*******************************************************************************
    17. * Definitions
    18. ******************************************************************************/

    19. /* 公共(可被其他源文件使用)宏、枚举、结构体的定义 */

    20. enum _device_mode
    21. {
    22.     kDeviceMode0    = 0x00U,
    23.     kDeviceMode1    = 0x01U,

    24.     kDeviceModeEnd  = 0x02U,
    25. };

    26. typedef struct _device_config
    27. {
    28.     uint32_t index;
    29.     uint32_t mode;
    30.     uint8_t data[16];
    31.     bool isEnabled;
    32. } device_config_t;

    33. /* 外部全局变量的声明 */

    34. extern uint32_t g_deviceIndex;

    35. extern const uint32_t g_maxDevices;

    36. /*******************************************************************************
    37. * API
    38. ******************************************************************************/

    39. #if defined(__cplusplus)
    40. extern "C" {
    41. #endif /*_cplusplus*/

    42. /* 外部函数(可加 extern 修饰)的声明 */

    43. void InitDevice(void);

    44. #if defined(__cplusplus)
    45. }
    46. #endif /*_cplusplus*/

    47. #endif /* _TEMPLATE_H_ */</font>
    复制代码




    作者:痞子衡      文章出处:痞子衡嵌入式

    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-10 22:38
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2020-3-17 14:42:11 | 显示全部楼层
    我们现在使用IDE提供的code style来自动排版。
    我可没有精力处理这些事情。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-5-25 16:03
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    8

    主题

    718

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    3395
    最后登录
    2024-3-5
    发表于 2020-3-17 18:35:54 | 显示全部楼层
    很有用
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-29 02:04 , Processed in 0.111637 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表