吴鉴鹰单片机开发板地址 淘宝店铺:【吴鉴鹰的小铺】 地址:【https://item.taobao.com/item.htm?_u=ukgdp5a7629&id=524088004171】 该文章是小单在网上搜集的有关嵌入式代码编码规范,用于规范自己的代码,增强可读性,非标准规范。小单希望同学们能强制自己形成良好的编码风格,有利于开发大规模程序而不显得杂乱。 参考STM32固件库编码风格和FreeRTOS编码风格。 一、工程文件组织结构 新建工程文件应包含以下全部或部分文件夹:
一个工程一定要包含一个main.c文件,只用来存放main函数。其余函数的定义应在相应的.c文件中,声明在相应的.h文件中。 二、源文件 文件头,文件的简介 /************************************************************************* * Copyright (c) 2018, Xiaodan * All rights reserved. * * File name : USB_Ctrl.c * Brief : USB API source code. * Introduce the main function or content of this document briefly. * Revision : 1.01 * Author : Xiaodan * Date : 2018.11.06 * Update : Introduce the difference from previous version. *************************************************************************/
源文件应该只包含它自己的头文件,其他的头文件在他自己的头文件中包含。 源文件中只声明局部函数,全局函数在头文件中声明。 全局变量在相应的源文件中定义,在头文件中用extern声明。 类型定义在头文件中定义。 /* Includes -----------------------------------------------------------*/ /*only include it's own header file, the others header file included by USB_Ctrl.h*/ #include "USB_Ctrl.h" /* Declaration --------------------------------------------------------*/ /*here are the local function declare, global fuction declare in header file.*/ void delay( uint32_t n); /* Global variable ----------------------------------------------------*/
/****************************************************** * Brief : Delay n ms * Parameter : * n: the number of delay microsecond. * Return : None. *******************************************************/ void delay( uint32_t n) { for( i=0; i<110; i++) ; } 三、头文件
/************************************************************************* - Copyright (c) 2018, Xiaodan - All rights reserved. - - File name : USB_Ctrl.h - Brief : The header file of USB_Ctrl.c. - Revision : 1.01 - Author : Xiaodan - Date : 2018.11.06 - Update : Introduce the difference from previous version. *************************************************************************/
/* Includes -----------------------------------------------------------*/ /* Define -------------------------------------------------------------*/ /* Typedef ------------------------------------------------------------*/ typedef unsigned int apiStatus; //api return code /* Enume --------------------------------------------------------------*/ /* Extern -------------------------------------------------------------*/ /* Declaration --------------------------------------------------------*/ 四、命名规则
typedef signed char int8_t; typedef short int16_t; typedef int int32_t; typedef long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t;
五、代码风格
下面的代码片中,第一部分展示文件布局,第二部分展示C代码设计格式。 /* #defines, 在合理的位置添加括号. */ #define A_DEFINITION ( 1 ) /* * 随后是Static (文件内部的)函数原型, * 如果注释有多行,参照本条注释风格---每一行都以’*’起始. */ static void prvAFunction( uint32_t ulParameter ); /* 文件作用域变量(本文件内部使用),要在函数体定义之前. */ static BaseType_t xMyVariable. /* 每一个函数的结束都有一行破折号,破折号与下面的第一个函数之间留一行空白。*/ /*-----------------------------------------------------------*/ void vAFunction( void ) { /* 函数体在此定义,注意要用大括号括住 */ } /*-----------------------------------------------------------*/ static UBaseType_t prvNextFunction( void ) { /* 函数体在此定义. */ } /*-----------------------------------------------------------*/ /* * 函数名字总是占一行,包括返回类型。 左括号之前没有空格左括号之后有一个空格, * 每个参数后面有一个空格,参数的命名应该具有一定的描述性. */ void vAnExampleFunction( long lParameter1, unsigned short usParameter2 ) { /* 变量声明没有缩进. */ uint8_t ucByte; /* 代码要对齐. 大括号占独自一行. */ for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ ) { /* 这里再次缩进. */ } } /* * for、while、do、if结构具有相似的模式。这些关键字和左括号之间没有空格。 * 左括号之后有一个空格,右括号前面也有一个空格,每个分号后面有一个空格。 * 每个运算符的前后各一个空格。使用圆括号明确运算符的优先级。不允许有0 * 以外的数字(魔鬼数)出现,必要时将这些数字换成能表示出数字含义的常量或 * 宏定义。 */ for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ ) { } while( ucByte < fileBUFFER_LENGTH ) { } /* * 由于运算符优先级的复杂性,我们不能相信自己对运算符优先级时刻保持警惕 * 并能正确的使用,因此对于多个表达式运算时,使用括号明确优先级顺序 */ if( ( ucByte < fileBUFFER_LENGTH ) && ( ucByte != 0U ) ) { ulResult = ( ( ulValue1 + ulValue2 ) - ulValue3 ) * ulValue4; } /* 条件表达式也要像其它代码那样对齐。 */ #if( configUSE_TRACE_FACILITY == 1 ) { /* 向TCB增加一个用于跟踪的计数器. */ pxNewTCB->uxTCBNumber = uxTaskNumber; } #endif /*方括号前后各留一个空格*/ ucBuffer[ 0 ] = 0U; ucBuffer[ fileBUFFER_LENGTH - 1U ] = 0U; 六、编程思想
七、C语言编程规则 参考MISRA Rule1:不得使用三元操作符(? : )。 Rule2:不得残留被注释掉的废代码。 Rule3:所有标识符不超过31字符。 Rule4:不同名空间中的变量名不得相同。 例如: typedef struct MyStruct {... } MyStruct; (违规) struct Person { char* name; ... }; char name[32]; (违规) Rule5: 不得使用char, int, float, double, long等基本类型,应该用stdint.h中定义的类型显示表示类型的大小,如uint16_t、int32_t等。 Rule6:禁止使用八进制数。(因为086U这样的常数很容易引起误解)。 Rule7:不得定义与外部作用域中某个标识符同名的对象,以避免遮盖外部作用域中的标识符。 Rule8:具有文件作用域的对象尽量声名为static的。 Rule9:自动对象(栈对象)使用前必须赋初值。 Rule10:操作符&&和||的右侧表达式不得具有副作用(side-effect)。 也就是说,象 if (x == 20 && ++y == 19)这样的表达式被禁止。 Rule11:不得对有符号数施加位操作,例如 1 << 4 将被禁止,必须写 1UL << 4。 Rule12:不得对有副作用的表达式施加sizeof操作符。 Rule13: 除了循环控制语句,不得使用逗号表达式。 Rule14:不得显式判断浮点数的相等性和不等性。 Rule15:不得遗留“永远不会用到”的代码。 Rule16:除了switch语句,不得使用标号(label)。 Rule17:不得使用goto。 Rule18:不得使用continue。 Rule19:除了switch语句,不得使用break Rule20:if, else if, else, while, do..while, for语句块必须使用{}括起。 Rule21:循环计数器的值不得在循环体内修改。 Rule22:禁止任何直接和间接的递归函数调用。 Rule23:不应该使用#undef。 Rule24:不得将宏作为参数传给宏函数。 Rule25:在一个宏定义中,#或##符号只能出现一次。 Rule26:禁止指针运算(代之以数组下标运算)。 Rule27:禁止超过两级的指针。 Rule28:禁止使用指向函数的非常量指针。 Rule29:禁止使用setjmp, longjmp。 Rule30:禁止使用atoi, atof, atol。(这个我很赞成,建议使用strtol, strtod等函数) Rule31:禁止使用abort, exit, getenv。 本文章来源网络,如果原作者不支持咱们转发,请联系删除,谢谢! 喜欢本文的亲们,欢迎点赞
---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:单片机精讲吴鉴鹰,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ---------------------------------------------------------------------------------------------------------------------- |