大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家讲的是恩智浦 SDK 驱动的代码风格

  上周痞子衡受领导指示,给 SE 同事做了一个关于 SDK 代码风格的分享。随着组内新人的增多,这样的培训还是很有必要的。一是可以让新同事通过代码风格来快速了解 SDK 驱动代码结构,另一方面也有利于新同事养成良好的编码习惯。

  痞子衡刚毕业时曾经也整理过一篇代码风格 《飞思卡尔软件开发C语言编码规范》,如今虽已是恩智浦纪元,但规范大多还是相似的,仅有微小更新。这次痞子衡将新版规范的要点提取了出来,并且还提供了标准模板,这样大家学习起来更加方便。

  另外鉴于领导指定我作为组内同事代码风格人肉审查员(大家写好的代码需要由我人肉审查风格),这样的工作如果真的完全是人工去做,可想而言有多枯燥和低效,因此痞子衡计划写一个配套的自动化检查工具,暂且叫 MCUXpresso SDK Coding Style Checker,欢迎大家来围观这个项目。

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 后缀
  • 枚举变量名使用小骆驼峰法
typedef enum _my_enumeration_name
{
kMyEnumerator0 = 0x00U,
kMyEnumerator1 = 0x01U, kMyEnumeratorEnd = 0x02U,
} my_enumeration_name_t; static my_enumeration_name_t s_myEnumVariableName;

1.4 结构体

结构体类型的命名混合了多种命名法,且加了一些特殊前后缀

  • 结构体类型名使用下划线命名法,单词全小写,且以下划线开头
  • 结构体成员名使用小骆驼峰法
  • 可用 typedef 重命名结构体类型名,使用下划线命名法,但需加 _t 后缀
  • 结构体变量名使用小骆驼峰法
typedef struct _my_struct_name
{
uint32_t myStructMember0;
uint32_t myStructMember1;
} my_struct_name_t; static my_struct_name_t s_myStructVariableName;

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 局部变量定义

局部变量定义应总是放在所在最小作用域(即最近的 {} 内)里的最前面,并且一行代码仅定义一个变量

void MyFunctionName(void)
{
uint8_t myVariableName0;
uint8_t myVariableName1; /* 代码体 */ for (;;)
{
uint8_t myVariableName2; /* 代码体 */
}
}

2.4 数字

代码中所有无符号整型数字,均应加 "U" 后缀

Hex: 0x1234ABCDU
Dec: 1234U

2.5 注释

仅使用 /* */ 来注释

/* 注释风格1,单独占一行 */
uint8_t i = 0; for (; i < 5;)
{
i++; /* 注释风格2,与代码共享一行 */
}

2.6 条件编译

#endif 后面需要加如下注释

#if MY_MACRO_NAME

/* 代码体 */

#endif /* MY_MACRO_NAME */

2.7 头文件保护宏

任何一个 .h 文件都需要包含下面格式的头文件保护宏代码,宏的命名与头文件名保持一致。如文件名为 hello_world.h,则宏名为 _HELLO_WORLD_H_

#ifndef _HEADER_FILENAME_
#define _HEADER_FILENAME_ /* 头文件内容 */ #endif /* _HEADER_FILENAME_ */

3.整体模板

3.1 源文件(.c)

/* 包含头文件代码 */

#include "template.h"

/*******************************************************************************
* Definitions
******************************************************************************/ /* 私有(仅本源文件内使用)宏、枚举、结构体的定义 */ #define MAX_DEVICES (128U) /*******************************************************************************
* Variables
******************************************************************************/ /* 所有全局变量(外部,静态,常量,指针)的定义 */ uint32_t g_deviceIndex = 0; static device_config_t s_deviceConfig; const uint32_t g_maxDevices = MAX_DEVICES; static volatile uint8_t *s_deviceData; /*******************************************************************************
* Prototypes
******************************************************************************/ /* 内部函数(即 static 修饰)的声明 */ static uint32_t GetDeviceIndex(void); /*******************************************************************************
* Code
******************************************************************************/ /* 所有函数(外部,内部)的定义 */ void InitDevice(void)
{
s_deviceConfig.index = 1;
s_deviceConfig.mode = kDeviceMode1;
memset(s_deviceConfig.data, 5, sizeof(s_deviceConfig.data));
s_deviceConfig.isEnabled = true;
} static uint32_t GetDeviceIndex(void)
{
return s_deviceConfig.index;
} int main(void)
{
InitDevice();
g_deviceIndex = GetDeviceIndex(); while (1)
{
}
}

3.2 头文件(.h)

/*
* Copyright xxx
* All rights reserved.
*
* xxx License
*
* Revision History:
* v1.0 - Description
*/ #ifndef _TEMPLATE_H_
#define _TEMPLATE_H_ /* 包含头文件代码 */ #include <stdbool.h>
#include <stdint.h>
#include <string.h> /*******************************************************************************
* Definitions
******************************************************************************/ /* 公共(可被其他源文件使用)宏、枚举、结构体的定义 */ enum _device_mode
{
kDeviceMode0 = 0x00U,
kDeviceMode1 = 0x01U, kDeviceModeEnd = 0x02U,
}; typedef struct _device_config
{
uint32_t index;
uint32_t mode;
uint8_t data[16];
bool isEnabled;
} device_config_t; /* 外部全局变量的声明 */ extern uint32_t g_deviceIndex; extern const uint32_t g_maxDevices; /*******************************************************************************
* API
******************************************************************************/ #if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/ /* 外部函数(可加 extern 修饰)的声明 */ void InitDevice(void); #if defined(__cplusplus)
}
#endif /*_cplusplus*/ #endif /* _TEMPLATE_H_ */

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:恩智浦SDK驱动代码风格、模板、检查工具的更多相关文章

  1. 痞子衡嵌入式:恩智浦SDK驱动代码风格检查工具预览版

    大家好,我是痞子衡,是正经搞技术的痞子. 接上文 <恩智浦SDK驱动代码风格.模板.检查工具> 继续聊,是的,过去的三天里我花了一些时间做了一个基于 PyQt5 的 GUI 工具,可以帮助 ...

  2. javaScript语法和风格的检查工具

    一.JSLint. JSHint. JSCS. ESLint 1.JSLint是由Douglas Crockford开发的,可能是最早的JavaScript Lint工具.JSLint定义了一组编码约 ...

  3. 痞子衡嵌入式:恩智浦MCUX SDK在GitHub上线了

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是恩智浦MCUX SDK 在GitHub上线一事. 其实在差不多一个月前(2021年1月6日),恩智浦MCUX SDK就在GitHub悄悄上 ...

  4. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性介绍(2)- RT685EVKA性能实测(Dhrystone)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的性能. 在前面的文章 i.MXRTxxx微控制器概览 里,痞子衡给大家简介过恩智浦半导体在2018 ...

  5. 痞子衡嵌入式:基于恩智浦i.MXRT1060的MP4视频播放器(RT-Mp4Player)设计

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是基于i.MXRT1062的MP4播放器参考设计. i.MXRT1062是恩智浦i.MXRT四位数系列的中端型号,外设搭配上很均衡,辅以6 ...

  6. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.5)- 串行NOR Flash下载算法(IAR EWARM篇)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是IAR开发环境下i.MXRT的串行NOR Flash下载算法设计. 在i.MXRT硬件那些事系列之<在串行NOR Flash XI ...

  7. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.6)- 串行NOR Flash下载算法(MCUXpresso IDE篇)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE开发环境下i.MXRT的串行NOR Flash下载算法设计. 在i.MXRT硬件那些事系列之<在串行N ...

  8. 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(3) - 统一FlexSPI驱动访问

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(3)之统一FlexSPI驱动访问. 文接上篇 <超级下载算法(RT-UFL)开发笔记(2) - 识别当前i. ...

  9. 痞子衡嵌入式:恩智浦MCU安全加密启动一站式工具NXP-MCUBootUtility用户指南

    NXP MCU Boot Utility English | 中文 1 软件概览 1.1 介绍 NXP-MCUBootUtility是一个专为NXP MCU安全加密启动而设计的工具,其特性与NXP M ...

随机推荐

  1. Codeforces Roundd #573 (Div. 2)

    D. Tokitsukaze, CSL and Stone Game 题意:有n堆石头,每人每次只能去一颗石子,若轮到当前人没任何一堆石子可以取或当前人取到后剩下有俩堆石子个数相同则当前人输: 给定石 ...

  2. [Machine Learning] Andrew Ng on Coursera (Week 1)

    Week 1 的内容主要有: 机器学习的定义 监督式学习和无监督式学习 线性回归和成本函数 梯度下降算法 线性代数回归 主要是了解一下机器学习的基本概念,重点是学习线性回归模型,以及对应的成本函数和梯 ...

  3. PyCharm4.5 中文破解版破解步骤

    1.在下载之家下载PyCharm4.5中文版软件包,然后右击软件安装包选择解压到“pycharm4.5.3”. 2.在解压文件夹中找到pycharm-professional-4.5.3,右击打开. ...

  4. deeplearning.ai 改善深层神经网络 week1 深度学习的实用层面

    1. 应用机器学习是高度依赖迭代尝试的,不要指望一蹴而就,必须不断调参数看结果,根据结果再继续调参数. 2. 数据集分成训练集(training set).验证集(validation/develop ...

  5. 深入JVM内核--常用JVM配置参数

    Trace跟踪参数 -verbose:gc -XX:+printGC 可以打印GC的简要信息 [GC 4790K->374K(15872K), 0.0001606 secs] [GC 4790K ...

  6. Java POI导出Excel不弹框选择下载路径(下载文件不选择下载路径,默认) Chrome

    在Chrome浏览器中,Java导出Excel文件时,浏览器弹出提示框,需要选择下载路径 在Chrome中的高级设置中,把“下载前询问每个文件的保存位置”去掉就解决了 DEEPLOVE(LC)

  7. mac安装并配置nexus3.5.1版本

    一.安装nexus 前置条件 :已经安装了JDK 1:下载nexus(http://www.sonatype.com/download-oss-sonatype) 最新版本(我的是3.5.1). 2: ...

  8. Eclipse快速入门:远程调试Java应用

    Eclipse快速入门:远程调试Java应用 2012年03月27日00:00 it168网站原创 作者:皮丽华 编辑:皮丽华 我要评论(0) 标签: Eclipse , Java , Java框架, ...

  9. Kubernetes集群部署DNS插件

    准备 kube-dns 相关镜像 准备 kube-dns 相关 yaml 文件 系统预定义的 RoleBinding 配置 kube-dns 相关服务 检查 kube-dns 功能 kube-dns ...

  10. 一致性哈希算法(consistent hashing)PHP实现

    一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简单哈希 ...