在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

為什么MISRA要求你不要使用位域-本文告訴你真相

嵌入式USB開發 ? 來源:嵌入式Lee ? 作者:嵌入式Lee ? 2023-06-21 17:36 ? 次閱讀

本文轉自公眾號,歡迎關注

為什么MISRA要求你不要使用位域-本文告訴你真相 (qq.com)

一.前言

做過嵌入式開發的一般會看到一條編程規范:”不要使用位域”,一般都是知其然不其所以然,了解的多一點的可能知道位域是實現相關不具備可移植性,那么繼續追問哪些行為是實現相關哪些行為導致移植性問題? 或者還有人知道,存儲布局,對齊等行為是實現相關會導致不可移植性。如果再追問位域產生的匯編代碼是什么樣的,怎么進行讀-修改-寫操作的?知道這些內容的就更加少之又少了。 讀寫肯定不能讀指定位數,只能字節,或者16位,32位這種,那么編譯器到底讀寫用什么寬度? 這時基本大部分人都不知道了。

知其然知其所以然,尤其是嵌入式開發和硬件結合比較緊密,所以一定要了解細節,我們這一篇從一個問題引出然后去分析查找原因,只有遇到問題然后去分析解決它才會有更深刻的映像。

二.問題分析過程

問題是驅動程序中一個寄存器的某個位域修改,導致其他位域的值被修改了。

關鍵代碼如下,

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<0?param?err

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.}

執行之前該寄存器值為0x00020100

34b4c4c2-0f04-11ee-9c1d-dac502259ad0.png

nfc_base[id]->nfc_ena._b.nfc_data_len= len

匯編代碼被優化為了寫高16位

34d22efe-0f04-11ee-9c1d-dac502259ad0.png

執行完后寄存器低16位變為了0

34f0fab4-0f04-11ee-9c1d-dac502259ad0.png

這是因為寄存器硬件上只支持32位的寫操作,所以寫高16位導致低16位清零了,這是硬件決定的。

二.驗證

一般想到的就是優化相關,加volatile等,我們分別驗證下。

3.1不使能編譯器優化

編譯器優化選項改為”-O0”

代碼不變

依然會按照16位訪問,導致低16位被清掉。

所以可以看到這個和編譯器行為有關,編譯器顯然不是根據優化等級決定位域的操作寬度,這里而是根據位域的寬度剛好是16位對齊,所以優化為了16位操作指令。

3504cddc-0f04-11ee-9c1d-dac502259ad0.png351f3d70-0f04-11ee-9c1d-dac502259ad0.png

3.2使用volatile避免編譯器優化

#ifndef__IOM

#define__IOM volatile

#endif

所有uint32_t替換為__IOM uint32_t

還是一樣的

353ad710-0f04-11ee-9c1d-dac502259ad0.png

顯然匯編代碼的訪問寬度也不受volatile影響。

3.3為什么指定了uint32_t和volatile還會優化。

問題來了為什么告訴了編譯器是uint32_t和volatile,為什么其還要一意孤行,要優化為16位訪問指令呢,答案就是因為是標準沒有規定,這是編譯器實現行為決定的,所以編譯器設計者決定的(當然也會有一些現實考慮的),可能不同編譯器行為不同,這里以GCC為例。

GCC編譯器文檔中可以找到答案

GCC的文檔可以看到如下內容,也給出了最好是不使用位域的原因

354f86f6-0f04-11ee-9c1d-dac502259ad0.png

35645612-0f04-11ee-9c1d-dac502259ad0.png

另外也介紹了位域哪些行為也是編譯器實現相關的,所以嵌入式可移植性考慮不要使用位域

3576ae5c-0f04-11ee-9c1d-dac502259ad0.png

那么有沒有辦法指定編譯按照一定大小訪問呢,GCC有編譯選項可以控制見下一節。

3.4使用編譯器選項-fstrict-volatile-bitfields

358c8eca-0f04-11ee-9c1d-dac502259ad0.png

可以看到改為了sw指令,按照32位進行了操作

359dc4f6-0f04-11ee-9c1d-dac502259ad0.png

四.一些廠家做法

如下可見

4.1CMSIS

core_cmxx.h中定義

CMSIS中進行了定義,寄存器個別使用位域

1./*IOdefinitions(accessrestrictionstoperipheralregisters)*/
2./**
3.defgroupCMSIS_glob_defsCMSISGlobalDefines
4.
5.IOTypeQualifiersareused
6.litospecifytheaccesstoperipheralvariables.
7.liforautomaticgenerationofperipheralregisterdebuginformation.
8.*/
9.#ifdef__cplusplus
10.#define__Ivolatile/*!

4.2ST

1./**
2.*@briefUniversalSerialBusFullSpeedDevice
3.*/
4.
5.typedefstruct
6.{
7.__IOuint16_tEP0R;/*!

4.3瑞薩

__I,__O__ROM也是core_cmxx.h中定義,大量使用位域

1.#ifndef__IM/*!

五.總結

結論就是正如很多嵌入式編程規范所描述的(比如MISRA),一般不建議使用位域,因為涉及到位域的訪問,存儲等行為都是實現定義的,不具備可移植性。

嵌入式領域寄存器的定義也最好不要使用位域,到寄存器級別以寄存器操作為單位即可,每個寄存器都要使用__IM,__OM,__IOM描述。

如果一定要使用位域可以使用-fstrict-volatile-bitfields選項,使用GCC測試可以保證按照固定指定大小訪問,但是不保證其他編譯器也支持該選項,最好能不使用就不使用位域。


審核編輯黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5082

    文章

    19123

    瀏覽量

    305151
  • 寄存器
    +關注

    關注

    31

    文章

    5343

    瀏覽量

    120348
  • 編譯器
    +關注

    關注

    1

    文章

    1634

    瀏覽量

    49129
  • MISRA
    +關注

    關注

    0

    文章

    21

    瀏覽量

    6968
  • 嵌入式編程
    +關注

    關注

    0

    文章

    27

    瀏覽量

    10314
收藏 人收藏

    評論

    相關推薦

    IC設計:ram的應用-異步時鐘寬轉換

    在進行模塊設計時,我們經常需要進行數據寬的轉換,常見的兩種轉換場景有同步時鐘寬轉換和異步時鐘寬轉換。
    的頭像 發表于 11-23 16:41 ?869次閱讀
    IC設計:ram的應用-異步時鐘<b class='flag-5'>域</b><b class='flag-5'>位</b>寬轉換

    使用問題

    在支持操作的單片機中,如C51,使用定義變量或者寄存器,操作方便并且節約空間。 問題1:但是很多單片機不支持操作,仍然使用
    發表于 09-16 22:25

    MISRA C編程規范標準有什么規則要求

    如何衡量代碼是否滿足某些標準?MISRA C編程規范標準有什么規則要求
    發表于 04-19 07:20

    所不知道的關于iPhone7的幾個真相,看完讓所有人震驚!

    Phone7發布這么久了,用的還好嗎?希望你的iPhone不要出現掉漆等不好的現象。你們在使用的過程中有沒有發現iPhone7什么不為人知的秘密呢?如果沒發現的話,下面我就來告訴大家關于iPhone7的一些
    發表于 02-23 09:40 ?3442次閱讀

    什么是分層架構的依據與原則?本文告訴答案!

    分層架構是運用最為廣泛的架構模式,幾乎每個軟件系統都需要通過層(Layer)來隔離不同的關注點(Concern Point),以此應對不同需求的變化,使得這種變化可以獨立進行;此外,分層架構模式還是隔離業務復雜度與技術復雜度的利器,《領域驅動設計模式、原理與實踐》寫道:
    發表于 07-27 14:16 ?7472次閱讀
    什么是分層架構的依據與原則?<b class='flag-5'>本文告訴</b><b class='flag-5'>你</b>答案!

    如何區分FPGA與CPLD?本文告訴答案!

    如何區分CPLD或FPGA和哪一個更適合自己?這是一個老生常談的問題,尤其是學生和初學者。如果您也在這個問題上很迷茫,那么就請聽小編為您區分FPGA與CPLD。
    發表于 09-04 14:16 ?2221次閱讀
    如何區分FPGA與CPLD?<b class='flag-5'>本文告訴</b><b class='flag-5'>你</b>答案!

    智能音箱究竟有哪些用處?本文告訴答案!

    在許多人心中一直以來都有個困惑,智能音箱到底有什么作用?無可否認,智能音箱能夠讓我們解放雙手,只通過語音就能夠進行操作。智能音箱也能夠打通許多智能家居通道,消費者能夠舒服的躺在沙發上控制家中燈光、電視、空調等電器是多么愜意的一件事。但這里有一個問題,能用智能音箱辦到的事情,使用智能手機也一樣可以做到,兩者似乎在這一點上有很多功能重合。
    發表于 09-20 16:46 ?2379次閱讀

    怎么分辨機器人種類 本文告訴答案

    自20世紀中期出現的第一臺現代機器人后,隨著相關技術的快速演進,時至今日,機器人已廣泛地被應用在許多不同的領域,來協助或取代人類完成各式各樣的工作。依照不同的需求,將機器人做出不同的分類,以達到有效區分或辨識他們的目的。
    發表于 01-14 15:41 ?5001次閱讀

    2018的量子計算是怎么跟AI一起兩開花的 本文告訴答案

    回首剛剛過去的2018,如果讓我回答一個“科技產業怎么看”的問題。那答案應該是這樣的:上看AI,下看IoT,近看5G,遠看量子計算,千萬不要看區塊鏈,因為太亂,看了容易上頭。
    發表于 01-15 10:16 ?856次閱讀

    怎么放置洗衣機最好 本文告訴答案

    洗衣機可以說是家里很重要的一種電器了,沒有洗衣機的時候,人們只能辛辛苦苦的用手來洗衣服,不僅傷手而且效率還很低,但是自從有了洗衣機,我們的生活的確是方便了很多。不過,通常人們喜歡把洗衣機放在陽臺上,但是小編不建議大家這樣做,最好還是放在衛生間。
    發表于 02-15 11:40 ?779次閱讀

    智慧城市該如何建設 本文告訴答案

    智慧城市建設興起于歐美地區,世界各國都將發展智慧城市定為未來幾年的目標。我國雖起步較晚,但在政府的支持和企業的參與下,智慧城市建設也取得階段性進展,在我國目前已有超過500個城市開展了相關建設。隨著人工智能、云計算、大數據等技術成熟,我國智慧城市發展將逐步向數據共享、萬物互聯、生態共贏邁進。
    發表于 05-29 08:53 ?1304次閱讀
    智慧城市該如何建設 <b class='flag-5'>本文告訴</b><b class='flag-5'>你</b>答案

    文告訴單相電機運轉無力該如何檢測

    本文小編告訴大家單相電機運轉無力的3個檢測方法。
    的頭像 發表于 12-14 21:28 ?1952次閱讀

    文告訴為什么電機過載保護元件常用熱繼電器?

    小編告訴大家電機過載保護元件常用的是熱繼電器,因為它能滿足一些要求
    的頭像 發表于 12-14 22:09 ?2692次閱讀

    文告訴什么是電機短時運行?

    本文小編告訴大家什么是電機短時運行。
    的頭像 發表于 12-14 22:12 ?3234次閱讀

    服務器ups運行時間,圖文告訴關于UPS電源的一些基礎知識

    原標題:圖文告訴關于UPS電源的一些基礎知識UPS - Uninterrupted Power System利用電池化學能作為后備能量,在市電斷電等電網故障時,不間斷地為用戶設備提供(交流)電能
    發表于 11-08 19:21 ?8次下載
    服務器ups運行時間,圖<b class='flag-5'>文告訴</b><b class='flag-5'>你</b>關于UPS電源的一些基礎知識
    主站蜘蛛池模板: 国产精品高清一区二区三区| 午夜视频在线| 久久精品亚洲| 欧美区一区| 日韩精品视频免费观看| 97影院午夜在线观看视频| 极品啪啪| 欧美三级成人| 精品精品国产自在久久高清| 欧美ww| 手机看片三级| 免费的黄视频| 久久偷窥视频| 久久亚洲精品国产亚洲老地址| 乱h亲女小说| 美女性色| 黄黄网| 午夜日| a欧美在线| 最新色站| 免费观看三级毛片| www.jizz中国| tube4欧美最新69| 人人爱人人射| 日本污污视频| 亚洲三级网| 又大又粗又爽黄毛片| 88xx成人永久免费观看| 欧美一二三区| 久久99国产亚洲高清观看首页| 亚洲免费视频在线观看| 成年毛片| 亚洲国产欧美在线人成aaa| 美国激情ap毛片| abc欧美成人影院| 日本三级2018亚洲视频| 免费福利影院| 特级片毛片| 深夜视频免费看| 午夜老司机永久免费看片| 午夜影皖|