世界播報(bào):為什么MISRA要求你不要使用位域-本文告訴你真相
做過嵌入式開發(fā)的一般會看到一條編程規(guī)范:”不要使用位域”,一般都是
本文轉(zhuǎn)自公眾號,歡迎關(guān)注
為什么MISRA要求你不要使用位域-本文告訴你真相 (qq.com)
一.前言做過嵌入式開發(fā)的一般會看到一條編程規(guī)范:”不要使用位域”,一般都是知其然不其所以然,了解的多一點(diǎn)的可能知道位域是實(shí)現(xiàn)相關(guān)不具備可移植性,那么繼續(xù)追問哪些行為是實(shí)現(xiàn)相關(guān)哪些行為導(dǎo)致移植性問題? 或者還有人知道,存儲布局,對齊等行為是實(shí)現(xiàn)相關(guān)會導(dǎo)致不可移植性。如果再追問位域產(chǎn)生的匯編代碼是什么樣的,怎么進(jìn)行讀-修改-寫操作的?知道這些內(nèi)容的就更加少之又少了。 讀寫肯定不能讀指定位數(shù),只能字節(jié),或者16位,32位這種,那么編譯器到底讀寫用什么寬度? 這時(shí)基本大部分人都不知道了。
(相關(guān)資料圖)
知其然知其所以然,尤其是嵌入式開發(fā)和硬件結(jié)合比較緊密,所以一定要了解細(xì)節(jié),我們這一篇從一個(gè)問題引出然后去分析查找原因,只有遇到問題然后去分析解決它才會有更深刻的映像。
二.問題分析過程問題是驅(qū)動程序中一個(gè)寄存器的某個(gè)位域修改,導(dǎo)致其他位域的值被修改了。
關(guān)鍵代碼如下,
1.typedefunionnfc_ena_union{
2. uint32_tw;
3. struct{
4. /*spienable,oncethespitransiscompleted,thisbitwillbeclearedbyHWautomaticlly*/
5. uint32_tnfc_ena:1; //[0]
6. uint32_treserved_0:3; //[1,3]
7. /*swrequesttousedp*/
8. uint32_tnfc_dp_req:1; //[4]
9. uint32_treserved_1:3; //[5,7]
10. /*duetodelayinreceivingdata,nfcdelayonebeattorx*/
11. uint32_tnfc_rx_delay_en:1; //[8]
12. uint32_treserved_2:7; //[9,15]
13. /*spitransdatalength,unitisbyte,oncethespitransiscompleted,thisbitwillbeclearedbyHWautomaticlly*/
14. uint32_tnfc_data_len:16; //[16,31]
15.}_b;
16.}nfc_ena_u;
1./**
2.*fnintnfc_set_datalen(uint8_tid,uint16_tlen)
3.*param[in]idportid
4.*param[in]lendatalen
5.*retval0ok
6.*retval<0paramerr
7.*
8.*/
9.NFC_INLINEintnfc_set_datalen(uint8_tid,uint16_tlen)
10.{
11. if(id>=HW_NFC_PORT_MAX)
12.{
13. return-1;
14.}
15.nfc_base[id]->nfc_ena._b.nfc_data_len=len;
16. return0;
17.}
執(zhí)行之前該寄存器值為0x00020100
nfc_base[id]->nfc_ena._b.nfc_data_len= len
匯編代碼被優(yōu)化為了寫高16位
執(zhí)行完后寄存器低16位變?yōu)榱?
這是因?yàn)榧拇嫫饔布现恢С?2位的寫操作,所以寫高16位導(dǎo)致低16位清零了,這是硬件決定的。
二.驗(yàn)證一般想到的就是優(yōu)化相關(guān),加volatile等,我們分別驗(yàn)證下。
3.1不使能編譯器優(yōu)化編譯器優(yōu)化選項(xiàng)改為”-O0”
代碼不變
依然會按照16位訪問,導(dǎo)致低16位被清掉。
所以可以看到這個(gè)和編譯器行為有關(guān),編譯器顯然不是根據(jù)優(yōu)化等級決定位域的操作寬度,這里而是根據(jù)位域的寬度剛好是16位對齊,所以優(yōu)化為了16位操作指令。
3.2使用volatile避免編譯器優(yōu)化#ifndef__IOM
#define__IOM volatile
#endif
所有uint32_t替換為__IOM uint32_t
還是一樣的
顯然匯編代碼的訪問寬度也不受volatile影響。
3.3為什么指定了uint32_t和volatile還會優(yōu)化。問題來了為什么告訴了編譯器是uint32_t和volatile,為什么其還要一意孤行,要優(yōu)化為16位訪問指令呢,答案就是因?yàn)槭菢?biāo)準(zhǔn)沒有規(guī)定,這是編譯器實(shí)現(xiàn)行為決定的,所以編譯器設(shè)計(jì)者決定的(當(dāng)然也會有一些現(xiàn)實(shí)考慮的),可能不同編譯器行為不同,這里以GCC為例。
GCC編譯器文檔中可以找到答案
GCC的文檔可以看到如下內(nèi)容,也給出了最好是不使用位域的原因
另外也介紹了位域哪些行為也是編譯器實(shí)現(xiàn)相關(guān)的,所以嵌入式可移植性考慮不要使用位域
那么有沒有辦法指定編譯按照一定大小訪問呢,GCC有編譯選項(xiàng)可以控制見下一節(jié)。
3.4使用編譯器選項(xiàng)-fstrict-volatile-bitfields可以看到改為了sw指令,按照32位進(jìn)行了操作
四.一些廠家做法如下可見
4.1CMSIScore_cmxx.h中定義
CMSIS中進(jìn)行了定義,寄存器個(gè)別使用位域
1./*IOdefinitions(accessrestrictionstoperipheralregisters)*/2./**3.defgroupCMSIS_glob_defsCMSISGlobalDefines4.5.IOTypeQualifiersareused6.litospecifytheaccesstoperipheralvariables.7.liforautomaticgenerationofperipheralregisterdebuginformation.8.*/9.#ifdef__cplusplus10.#define__Ivolatile/*!
4.2ST1./**2.*@briefUniversalSerialBusFullSpeedDevice3.*/4.5.typedefstruct6.{7.__IOuint16_tEP0R;/*!4.3瑞薩__I,__O__ROM也是core_cmxx.h中定義,大量使用位域
1.#ifndef__IM/*!
五.總結(jié)結(jié)論就是正如很多嵌入式編程規(guī)范所描述的(比如MISRA),一般不建議使用位域,因?yàn)樯婕暗轿挥虻脑L問,存儲等行為都是實(shí)現(xiàn)定義的,不具備可移植性。
嵌入式領(lǐng)域寄存器的定義也最好不要使用位域,到寄存器級別以寄存器操作為單位即可,每個(gè)寄存器都要使用__IM,__OM,__IOM描述。
如果一定要使用位域可以使用-fstrict-volatile-bitfields選項(xiàng),使用GCC測試可以保證按照固定指定大小訪問,但是不保證其他編譯器也支持該選項(xiàng),最好能不使用就不使用位域。
審核編輯黃宇
關(guān)鍵詞:
[ 相關(guān)文章 ]
做過嵌入式開發(fā)的一般會看到一條編程規(guī)范:”不要使用位域”,一般都是
1、額!C0M50Y100K0只調(diào)節(jié)M和Y值就可!!沒有所謂的橘黃色準(zhǔn)確的值。2、因
圖為王旭把涼墊固定在座位上。本報(bào)記者王津通訊員李玫攝 天津北方網(wǎng)
6月19日,浙江世寶(002703)融資買入3108 64萬元,融資償還3462 06萬
發(fā)行商FlyhighWorks宣布,像素戰(zhàn)旗新游《史萊姆的大野望》確定將于7月2
6月18日,第一屆海外華裔青少年中華文化實(shí)踐大屆文賽巴西賽區(qū)選手在圣
歐洲戰(zhàn)略小金屬銻錠(99 65%)報(bào)價(jià)11950美元 噸,較前一交易日下調(diào)100美元 噸。
“交融匯聚——新疆精品歷史文物展”近日在國家博物館開幕。展覽展出新
沒有人可以真的毀掉你的人生除非那個(gè)人是經(jīng)過你授權(quán)的也等于是說你的生
近年來,滬上銀行機(jī)構(gòu)主動作為,通過紓困融資、無還本續(xù)貸、延期還本付
第三十二屆哈爾濱國際經(jīng)濟(jì)貿(mào)易洽談會昨天(6月19日)順利閉幕。本屆哈
【環(huán)球時(shí)報(bào)綜合報(bào)道】朝鮮官方媒體朝中社19日發(fā)文,對朝鮮勞動黨第八屆
豆來為大家解答以上的問題。臨床指南醫(yī)脈通,念佛氣脈通了12種感覺這個(gè)
1、代練平臺如下。2、代練通代練通app是一個(gè)游戲代練應(yīng)用,代練通app為
《非份之想》?♀?主唱:何嘉莉作曲:伍樂城丨填詞:梁芷珊編曲:伍樂
叫邁克的更牛逼。邁克喬丹,邁克杰克遜,邁克泰森,邁克奧赫,邁克約翰
早晨,沿著親水棧道晨跑;午間,在村里的“不晚”咖啡館點(diǎn)杯咖啡、看看
抄寫作文網(wǎng)小編為大家提供哪些是描寫長城的古詩1 描寫長城的詩句有哪些
撰文|李巖《解放軍報(bào)》今天(19日)頭版刊發(fā)報(bào)道披露,經(jīng)中央軍委批準(zhǔn)
人民網(wǎng)南昌6月19日電(記者時(shí)雨)據(jù)預(yù)測,6月底前梅雨帶將在長江流域到華
[ 相關(guān)新聞 ]
Copyright 2015-2022 太平洋醫(yī)院網(wǎng) 版權(quán)所有 備案號:豫ICP備2022016495號-17 聯(lián)系郵箱:93 96 74 66 9@qq.com