嵌入式代碼編碼規(guī)范,用于規(guī)范自己的代碼,增強可讀性,非標準規(guī)范。最好能強制自己形成良好的編碼風格,有利于開發(fā)大規(guī)模程序而不顯得雜亂。參考STM32固件庫編碼風格和FreeRTOS編碼風格。
一、工程文件組織結(jié)構(gòu)
新建工程文件應包含以下全部或部分文件夾:
usrSrc:用戶源文件,用來存放.c文件和其他的源文件。main.c應放在這里。
usrInc:用戶頭文件,用來存放.h文件。
usrDoc:用戶說明文檔,用來存放用戶在開發(fā)過程中書寫的文檔,一般為.txt格式。例如Readme.txt,指令說明等。
Src:引用庫的源文件。
Inc:應用庫的頭文件。
Lib:引用的庫文件。
一個工程一定要包含一個main.c文件,只用來存放main函數(shù)。其余函數(shù)的定義應在相應的.c文件中,聲明在相應的.h文件中。
So can you help to prepare our suggest contents display in the page (e.g. tools intro, feature, which videos, which documents etc) to us first? We will then further discuss with Infineon if anything need to change / add.
二、源文件
文件頭,文件的簡介
/************************************************************************* * 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.*************************************************************************/
必要的注釋和說明
源文件應該只包含它自己的頭文件,其他的頭文件在他自己的頭文件中包含。
源文件中只聲明局部函數(shù),全局函數(shù)在頭文件中聲明。
全局變量在相應的源文件中定義,在頭文件中用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 ----------------------------------------------------*/
函數(shù)頭
/****************************************************** * 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 --------------------------------------------------------*/
四、命名規(guī)則
參考FreeRTOS命名規(guī)則,MISRA C規(guī)范。
定義變量時盡量使用uint8_t 、uint16_t 、uint32_t等。頭文件為stdint.h。
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;
uint32_t類型的變量使用前綴ul,這里’u’表示’unsigned’,’l’表示’long’
uint16_t類型的變量使用前綴us,這里’u’表示’unsigned’,’s’表示’short’
uint8_t類型的變量使用前綴uc,這里’u’表示’unsigned’,’c’表示’char’
枚舉類型變量使用前綴e
指針類型變量在類型基礎(chǔ)上附加前綴p,比如指向uint16_t的指針變量前綴為pus
與MISRA指南一致,char類型變量僅被允許保存ASCII字符,前綴為c
與MISRA指南一致,char *類型變量僅允許指向ASCII字符串,前綴為pc
宏定義全部使用大寫,兩個單詞之間用下劃線隔開。
具有文件作用域的對象盡量聲名為static的。
全局變量加前綴’g_’。整個工程都可以用的變量,不局限于文件作用域。
五、代碼風格
縮進:縮進使用制表符,一個制表符等于4個空格。
注釋:注釋單行不超過80列,特殊情況除外。
布局:源代碼應被設(shè)計成盡可能的易于查看和閱讀。
下面的代碼片中,第一部分展示文件布局,第二部分展示C代碼設(shè)計格式。
/* #defines, 在合理的位置添加括號. */#define A_DEFINITION ( 1 )/* * 隨后是Static (文件內(nèi)部的)函數(shù)原型, * 如果注釋有多行,參照本條注釋風格---每一行都以’*’起始. */static void prvAFunction( uint32_t ulParameter );/* 文件作用域變量(本文件內(nèi)部使用),要在函數(shù)體定義之前. */static BaseType_t xMyVariable./* 每一個函數(shù)的結(jié)束都有一行破折號,破折號與下面的第一個函數(shù)之間留一行空白。*//*-----------------------------------------------------------*/void vAFunction( void ){/* 函數(shù)體在此定義,注意要用大括號括住 */}/*-----------------------------------------------------------*/static UBaseType_t prvNextFunction( void ){/* 函數(shù)體在此定義. */}/*-----------------------------------------------------------*//* * 函數(shù)名字總是占一行,包括返回類型。左括號之前沒有空格左括號之后有一個空格, * 每個參數(shù)后面有一個空格,參數(shù)的命名應該具有一定的描述性. */void vAnExampleFunction( long lParameter1, unsigned short usParameter2 ){/* 變量聲明沒有縮進. */uint8_t ucByte;/* 代碼要對齊. 大括號占獨自一行. */for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ ) {/* 這里再次縮進. */ }}/* * for、while、do、if結(jié)構(gòu)具有相似的模式。這些關(guān)鍵字和左括號之間沒有空格。 * 左括號之后有一個空格,右括號前面也有一個空格,每個分號后面有一個空格。 * 每個運算符的前后各一個空格。使用圓括號明確運算符的優(yōu)先級。不允許有0 * 以外的數(shù)字(魔鬼數(shù))出現(xiàn),必要時將這些數(shù)字換成能表示出數(shù)字含義的常量或 * 宏定義。 */for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ ){}while( ucByte < fileBUFFER_LENGTH ){}/* * 由于運算符優(yōu)先級的復雜性,我們不能相信自己對運算符優(yōu)先級時刻保持警惕 * 并能正確的使用,因此對于多個表達式運算時,使用括號明確優(yōu)先級順序 */if( ( ucByte < fileBUFFER_LENGTH ) && ( ucByte != 0U ) ){ ulResult = ( ( ulValue1 + ulValue2 ) - ulValue3 ) * ulValue4;}/* 條件表達式也要像其它代碼那樣對齊。*/#if( configUSE_TRACE_FACILITY == 1 ){/* 向TCB增加一個用于跟蹤的計數(shù)器. */ pxNewTCB->uxTCBNumber = uxTaskNumber;}#endif/*方括號前后各留一個空格*/ucBuffer[ 0 ] = 0U;ucBuffer[ fileBUFFER_LENGTH - 1U ] = 0U;
六、編程思想
將特定功能的代碼封裝成函數(shù)。
七、C語言編程規(guī)則
參考MISRA
Rule1:不得使用三元操作符(? : )。
Rule2:不得殘留被注釋掉的廢代碼。
Rule3:所有標識符不超過31字符。
Rule4:不同名空間中的變量名不得相同。
例如:
typedef struct MyStruct {... } MyStruct; (違規(guī)) struct Person { char* name; ...};char name[32]; (違規(guī))
Rule5: 不得使用char, int, float, double, long等基本類型,應該用stdint.h中定義的類型顯示表示類型的大小,如uint16_t、int32_t等。
Rule6:禁止使用八進制數(shù)。(因為086U這樣的常數(shù)很容易引起誤解)。
Rule7:不得定義與外部作用域中某個標識符同名的對象,以避免遮蓋外部作用域中的標識符。
Rule8:具有文件作用域的對象盡量聲名為static的。
Rule9:自動對象(棧對象)使用前必須賦初值。
Rule10:操作符&&和||的右側(cè)表達式不得具有副作用(side-effect)。
也就是說,象 if (x == 20 && ++y == 19)這樣的表達式被禁止。
Rule11:不得對有符號數(shù)施加位操作,例如 1 << 4 將被禁止,必須寫 1UL << 4。
Rule12:不得對有副作用的表達式施加sizeof操作符。
Rule13:除了循環(huán)控制語句,不得使用逗號表達式。
Rule14:不得顯式判斷浮點數(shù)的相等性和不等性。
Rule15:不得遺留“永遠不會用到”的代碼。
Rule16:除了switch語句,不得使用標號(label)。
Rule17:不得使用goto。
Rule18:不得使用continue。
Rule19:除了switch語句,不得使用break
Rule20:if, else if, else, while, do..while, for語句塊必須使用{}括起。
Rule21:循環(huán)計數(shù)器的值不得在循環(huán)體內(nèi)修改。
Rule22:禁止任何直接和間接的遞歸函數(shù)調(diào)用。
Rule23:不應該使用#undef。
Rule24:不得將宏作為參數(shù)傳給宏函數(shù)。
Rule25:在一個宏定義中,#或##符號只能出現(xiàn)一次。
Rule26:禁止指針運算(代之以數(shù)組下標運算)。
Rule27:禁止超過兩級的指針。
Rule28:禁止使用指向函數(shù)的非常量指針。
Rule29:禁止使用setjmp, longjmp。
Rule30:禁止使用atoi, atof, atol。(這個我很贊成,建議使用strtol, strtod等函數(shù))
Rule31:禁止使用abort, exit, getenv。
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19126瀏覽量
305242 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4331瀏覽量
62622 -
工程
+關(guān)注
關(guān)注
0文章
165瀏覽量
27863
原文標題:如何增強代碼的可讀性?嵌入式代碼之編寫規(guī)范
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論