<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 設計應用 > 汽車(chē)電子行業(yè)的C語(yǔ)言編程標準

汽車(chē)電子行業(yè)的C語(yǔ)言編程標準

作者: 時(shí)間:2024-01-16 來(lái)源: 收藏

前言

本文引用地址:http://dyxdggzs.com/article/202401/454884.htm

之前分享了一些規范相關(guān)的文章,有位讀者提到了行業(yè)的 C標準,說(shuō)這個(gè)很不錯。

本次給大家找來(lái)了一篇行業(yè)的 C標準的文章一同學(xué)習下。

什么是?

MISRA (The Motor Industry Software Reliability Association),中文名稱(chēng)為汽車(chē)工業(yè)軟件可靠性聯(lián)會(huì ),是英國的一個(gè)跨國汽車(chē)工業(yè)協(xié)會(huì ),其成員包括了大部分歐美汽車(chē)生產(chǎn)商。

其核心使命是為汽車(chē)工業(yè)提供服務(wù)和協(xié)助,幫助廠(chǎng)方開(kāi)發(fā)安全的、高可靠性的嵌入式軟件。MISRA C則是由MISRA提出的針對嵌入式開(kāi)發(fā)標準,目的是提高嵌入式系統的安全性、可讀性和可移植性。

MISRA C一開(kāi)始主要是針對汽車(chē)產(chǎn)業(yè),后面他產(chǎn)業(yè)也逐漸開(kāi)始使用MISRA C,包括航天、電信、國防、醫療設備、鐵路等領(lǐng)域中都已有廠(chǎng)商使用MISRA C。通常認為,如果能夠完全遵守這些標準,則該嵌入式C代碼就是易讀、可靠、可移植和易于維護的。

因此,很多嵌入式開(kāi)發(fā)者都以MISRA C來(lái)衡量自己的編碼風(fēng)格,比如著(zhù)名的uC/OS就稱(chēng)自己99%的代碼遵循MISRA C編碼規范標準。

因此,作為嵌入式開(kāi)發(fā)者,不論哪個(gè)行業(yè),都應以產(chǎn)品安全性為前提,保證可靠性、可讀性、可移植性,也就是保證自身代碼盡可能符合MISRA C。

MISRA C應用在越來(lái)越多領(lǐng)域,作為嵌入式開(kāi)發(fā)者,編碼過(guò)程規范應該盡可能遵循MISRA C規則,但也分特殊情況,有的時(shí)候為了嚴格按規范做可能會(huì )嚴重提高工作量或者降低系統性能,此時(shí)需要衡量一個(gè)平衡點(diǎn)。

關(guān)于MISRA C,本人的幾點(diǎn)體會(huì )。

1)編碼過(guò)程盡可能遵循MISRA C規范,提高代碼可靠性、可讀性、可移植??煽啃裕ǚ€定性)是前提,可讀性、可移植是衡量一個(gè)程序員編碼水平的因素之一。

特別是對于嵌入式程序員,與硬件相關(guān)的,考慮到成本、供應鏈等問(wèn)題,硬件可能會(huì )經(jīng)常變動(dòng)或者需要兼容多種硬件,此時(shí),可移植性就體現出優(yōu)勢了,大大減少重復的編碼工作。

2)特殊情況下,是可以打破規則的。比如,其中禁止使用goto語(yǔ)句,也是相關(guān)標準要求禁止的。有些時(shí)候是可以使用的,而且使用其他會(huì )使得程序邏輯更清晰。但,如果“特殊情況”出現非常頻繁,那就得考慮自身的程序架構是否合理了。

3)可以借助一些工具進(jìn)行MISRA C檢查。如IAR中,就有支持MISRA C規則檢查。以下為MISRA C 2004規范標準。

環(huán)境

規則1.1(強制):所有的代碼應該遵守 ISO 9899:1990“Programming Language C”

規則1.2(強制):只有當具備統一接口的目標代碼的時(shí)候才可以采用多種編譯器和語(yǔ)言。

規則1.4(強制):檢查編譯器 / 連接器以確保支持 31 一個(gè)有效字符,支持大小寫(xiě)敏感。

語(yǔ)言擴展

Rule 2.1(強制):匯編語(yǔ)言應該封裝起來(lái)并且隔離。

例如:#define NOP asm (“NOP”)

規則2.2(強制):源代碼只能采用 /* …  * /風(fēng)格的注釋。

規則2.3(強制):字符序列 /* 不能在注釋中使用。

注: C 語(yǔ)言不支持注釋的嵌套即使一些編譯器支持這個(gè)語(yǔ)言擴展。

規則2.4(建議):代碼段不能注釋掉。

注:應采用 #if 或者 #ifdef 來(lái)構成一個(gè)注釋?zhuān)駝t代碼里如果有注釋會(huì )改變代碼的作用。

文檔化

規則3.3(建議):編譯器對于整數除法運算的實(shí)施應該寫(xiě)入文檔。

例:

-5/3 = -1 余-2 有些編譯器結果是 -2 于+1。

字符集

規則4.1(強制):只能使用 ISO 標準定義的字符集。

標識符

規則6.5 (強制):在內部范圍的標識符不能和外部的標識符用同樣的名字,因為會(huì )隱藏那個(gè)標識符。例:

int16_t i: void f() {     int16_t i;     i=3 ;}

規則5.2(強制):typedef 名稱(chēng)只能唯一,不能重復定義。

規則5.4(強制):標記名應該是唯一的標識符。

規則5.7(建議):標識符不能重復使用。

類(lèi)型

規則6.1(強制):char 類(lèi)型只能用來(lái)存儲使用字符。

規則6.2(強制):signed 和 unsigned char 只能用來(lái)存儲和使用數據值.

規則6.3(建議):對于基本數據類(lèi)型,必須使用 typedef 顯式標識出數據長(cháng)度。

例:

typedef signed char int8_t;typedef unsigned int uint16_t;

約束

規則7.1(強制):禁止使用八進(jìn)制數(0除外)或者八進(jìn)制轉義字符。

注:整型常數以 0 開(kāi)始會(huì )被認為是八進(jìn)制。例:

code[1]=109 code[2]=100 code[3]=052

如果是對總線(xiàn)消息初始化,會(huì )有危險。

聲明和定義

規則8.1(強制):函數都應該有原型聲明,且相對函數定義和調用可見(jiàn)。

規則8.2(強制):無(wú)論何時(shí)一個(gè)對象和函數聲明或者定義,它的類(lèi)型應該明確聲明 。

規則8.3(強制):函數聲明中的參數類(lèi)型應該和定義中的類(lèi)型一致。

規則8.4(強制):如果對象或函數被聲明了多次,那么它們的類(lèi)型應該是兼容的。

規則8.5(強制):頭文件中不應定義對象或者函數。

規則8.6(強制):函數應該聲明為具有文件作用域。

規則8.7(強制):如果對象的訪(fǎng)問(wèn)只是在單一的函數中,那么對象應該在塊范圍內聲明。

規則8.8(強制):外部變量或者函數只能聲明在一個(gè)文件中。

規則8.9(強制):具有外部鏈接的標識符應該具有準確的外部定義。

規則8.10(強制):在文件范圍內聲明和定義的所有對象或函數具有內部鏈接,除非是在需要外部鏈接的情況下。

規則8.11(強制):static 存儲類(lèi)標識符應該用于具有內部鏈接對象和函數的定義和聲明。

規則8.12(強制):數組聲明為外部,應該明確聲明大小或者直接初始化確定。

初始化

規則9.1(強制):所有變量在使用之前都應該賦值。

規則9.2(強制):應該使用大括號一指示和匹配數組和結構的非零初始化構造。

規則9.3(強制):在枚舉列表中,”=“不能顯式用于除首元素之外的元素上,除非所有的元素都是顯式初始化的。

數學(xué)類(lèi)型轉換(隱式)

規則10.1(強制):整型表達式不要隱式轉換為其他類(lèi)型。

1)轉換到更大的整型。

2)表達式太復雜。

3)表達式不是常數是一個(gè)函數。

4)表達式不是一個(gè)常數是一個(gè)返回表達式。

規則10.2(強制):浮點(diǎn)數表達式不要隱式轉換為其他類(lèi)型。

1)轉換到更大的浮點(diǎn)數。

2)表達式太復雜。

3)表達式是一個(gè)函數。

4)表達式是一個(gè)返回表達式。

數學(xué)類(lèi)型轉換(明確)

規則10.3(強制):整型表達式的值只能轉換到更窄小且是同樣符號類(lèi)型的表達式。

規則10.4(強制):浮點(diǎn)表達式的值只能轉換到更窄小的浮點(diǎn)表達式。

規則10.5(強制):如果位運算~和<<應用在基本類(lèi)型為 unsigned char 或 unsigned short 的操作數,結果應該立即強制轉換為預期操作數的基本類(lèi)型。例:

uint8_t a = 0x5a;uint8_t b;b = ((uint8_t)(~a))>>4;

數學(xué)類(lèi)型轉換

規則10.6(強制):所有的 unsigned 類(lèi)型都應該有后綴 “U”。

規則11.1(強制):指針不能轉換為函數或者整型以外的其他類(lèi)型。

表達式

規則12.2(強制):表達式的值應和標準允許的評估順序一致。例:

x=b[i] + i++;

不同的編譯器給出的結果不一樣,b[i] 是否先執行?應:x=b[i]; i++; 比如:

x=func(i++,i);

規則12.3(強制):sizeof 操作符不能用在包含邊界作用 (side effect) 的表達式上。例:

int32_t=i; int32_t=j; j=sizeof(i=1234);

表達式并沒(méi)有執行,只是得到表達式類(lèi)型int的size。

規則12.4(強制):邏輯操作符 && 或者||右邊不能包含邊界作用 (side effect)。

例:

if(ishight) && (x== i++))

如果 ishight=0 那么 i++ 不會(huì )評估

規則12.5(建議):++ 和 - - 不能和其他表達式用在一個(gè)表達式中。

例:

u8a=++u8b + u8c–;

控制語(yǔ)句表達式

規則13.1(強制):賦值語(yǔ)句不能用在一個(gè)產(chǎn)生布爾值的表達式中。

例:

if((x=y)!=0) … if (x=y) …

規則13.3(強制):浮點(diǎn)表達式不應該測試其是否相等或者不相等。

規則13.4(強制):for控制表達式中不要包含任何浮點(diǎn)類(lèi)型。

規則13.6(強制):數字變量作為for循環(huán)的循環(huán)計數不要在循環(huán)體內部被修改。

例:

flag=1; for(i=0;(i<5)&&(flag==1);i++) {     flag=0;     i=i+3; }

控制流

規則14.1(強制):不要有執行不到的代碼。

例:

swich(event) {     case 0;      do_wakeup();     break;     do_more(); … }

規則14.4(強制) :goto 語(yǔ)句不能使用。

規則14.5(強制):continue 不能使用。

規則14.6(強制):函數應在函數結束有一個(gè)出口。

規則14.7(強制):witch、while do 、while for 語(yǔ)句體應是一個(gè)混合語(yǔ)句。

規則14.10(強制):所有 if else if 結構都應該由 else 結束。

switch(x) { uint8_t var; /* 違反*/ case 0:  … }

函數

規則16.2(強制):函數不能直接或者間接的調用自己。

例:系統不能用遞歸,超出堆??臻g很危險。

規則16.8(強制):non-void 類(lèi)型函數的所有出口路徑都應該有一個(gè)明確的 return 語(yǔ)句表達式。

指針和數組

規則17.1(強制):指針的數學(xué)運算只能用在指向數組的地址上。

規則17.3(強制):>,>=,<,<= 不能用在指針類(lèi)型,除非指向同一個(gè)數組。

規則17.5(建議):禁止使用 2 級以上指針。

結構和聯(lián)合

規則18.4(強制):禁止使用 union(共用體)。

預處理指令

規則19.1(建議):#include 語(yǔ)句的前面只能有其他預處理指令和注釋。

規則19.2(建議):#include 指令中的頭文件名稱(chēng)不能包含非標準的字符。

規則19.5(強制):宏不能在函數體內定義。

規則19.8(強制):類(lèi)函數宏調用時(shí)不能沒(méi)有它的參數。

標準庫

規則20.1(強制):標準庫中的保留標識符,宏和函數不能定義,重定義和undefined。

規則20.4(強制):動(dòng)態(tài)內存分配不能使用。

例:不能使用malloc、calloc、free、realloc。

規則20.9(強制):輸入輸出庫 (stdio.h) 不能用在產(chǎn)生嵌入式系統中。

規則20.12(強制):時(shí)間處理函數 time.h 不能使用。

運行時(shí)故障

規則21.1(強制):通過(guò)使用以下手段確保把運行時(shí)故障最小化。

1)靜態(tài)分析工具/技術(shù)。

2)動(dòng)態(tài)分析工具/技術(shù)。

3)編寫(xiě)明確的代碼避免運行時(shí)錯誤。

文章來(lái)源于網(wǎng)絡(luò ),版權歸原作者所有,如有侵權,請聯(lián)系刪除。



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>