在线观看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測試可以保證按照固定指定大小訪問,但是不保證其他編譯器也支持該選項,最好能不使用就不使用位域。


審核編輯黃宇

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

    關注

    5143

    文章

    19561

    瀏覽量

    315443
  • 寄存器
    +關注

    關注

    31

    文章

    5425

    瀏覽量

    123533
  • 編譯器
    +關注

    關注

    1

    文章

    1657

    瀏覽量

    49927
  • MISRA
    +關注

    關注

    0

    文章

    22

    瀏覽量

    7184
  • 嵌入式編程
    +關注

    關注

    0

    文章

    27

    瀏覽量

    10520
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    電子硬件設計牛人張飛告訴“11個不要

    我們不知道抄來的電路優點在哪,缺點是什么。不要隨便的去抄別人的電路,一定要根據自己的知識來設計這樣一個電路。即使看到別人電路時,也要能夠分析和理解別人的電路,把電路中的問題找出來,然后變成
    發表于 07-22 21:47

    使用問題

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    原標題:圖文告訴關于UPS電源的一些基礎知識UPS - Uninterrupted Power System利用電池化學能作為后備能量,在市電斷電等電網故障時,不間斷地為用戶設備提供(交流)電能
    發表于 11-08 19:21 ?8次下載
    服務器ups運行時間,圖<b class='flag-5'>文告訴</b><b class='flag-5'>你</b>關于UPS電源的一些基礎知識
    主站蜘蛛池模板: 久久久久久久国产精品影院 | 亚洲欧美一区二区三区麻豆 | 色婷综合| 夜夜se | 成人欧美另类人妖 | 91正在 播放| 午夜影院一级片 | 久久久久国产免费 | 乱小说录目伦200篇将曲勒 | 色爱综合网 | 天天澡天天摸天天添视频 | 欧美视频三区 | 午夜在线视频观看 | 国模精品 | 亚洲一区二区三区在线播放 | 国产精欧美一区二区三区 | 曰本女人一级毛片看一级毛 | 国产精品久久久久久久免费 | 97人人在线 | 4hu影院最新地址www | 99久久免费精品国产免费高清 | 天天操天天艹 | 丁香花小说| 亚洲系列中文字幕一区二区 | 1024手机看片国产旧版你懂的 | 日韩亚射吧 | a级毛片免费观看网站 | 国产一级片免费看 | 天天躁日日2018躁狠狠躁 | 亚洲操操操 | 中文字幕天天躁夜夜狠狠综合 | 日本三级香港三级三级人!妇久 | 日日操操干干 | 天堂资源在线 | 免费一级特黄特色大片 | 久久婷婷影院 | 青青导航 | 一级在线观看 | 免费人成网ww777kkk手机 | 日本黄大乳片免费观看 | 一级大片免费观看 |