0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

遇見(jiàn)一個(gè)編譯優(yōu)化導(dǎo)致的bug

魚(yú)鷹談單片機(jī) ? 來(lái)源:魚(yú)鷹談單片機(jī) ? 2024-08-12 17:26 ? 次閱讀

來(lái)源:公眾號(hào)【魚(yú)鷹談單片機(jī)

作者:魚(yú)鷹Osprey

ID :emOsprey

最近在調(diào)試 can 通信,因?yàn)?c8t6 flash 很小,而魚(yú)鷹培訓(xùn)工程完成的驅(qū)動(dòng)越來(lái)越多,導(dǎo)致 flash 不足,因此把 bsp 的優(yōu)化級(jí)別設(shè)置成-O2,誰(shuí)知道在串口輸入數(shù)據(jù)時(shí)直接 hardfault 了:

圖片

進(jìn)一步跟蹤發(fā)現(xiàn)問(wèn)題出在這條代碼中:

uint32_tcnt=*((uint32_t*)pinfo->pdma_cnt_rx);// 出錯(cuò)代碼
.....
pinfo->last_dma_cnt = cnt;

這條代碼最開(kāi)始是這樣

uint16_tcnt=*((uint16_t*)pinfo->pdma_cnt_rx);

因?yàn)槲业膌ast_dma_cnt 變量是 16 bit,我想節(jié)省一下 ram 空間,因?yàn)閷?shí)際上 DMA 的計(jì)數(shù)器也只使用了 16 bit。

uint16_t        last_dma_cnt;       // used in dma

但是測(cè)試時(shí)發(fā)現(xiàn)出現(xiàn) hardfault 了,通過(guò)匯編分析發(fā)現(xiàn)是非四字節(jié)對(duì)齊訪問(wèn) dma 外設(shè),后面通過(guò)修改代碼,強(qiáng)制使用 32 bit 訪問(wèn),就再也沒(méi)出現(xiàn)問(wèn)題了。

uint32_t cnt = *(( uint32_t*)pinfo->pdma_cnt_rx);

但昨天修改完編譯優(yōu)化級(jí)別后,又一次出現(xiàn)了,匯編分析發(fā)現(xiàn)還是對(duì)齊問(wèn)題,因?yàn)?x4002005c 這個(gè)地址確實(shí)是 DMA 的計(jì)數(shù)器地址。

只是再優(yōu)化后,沒(méi)按我的要求 32bit 訪問(wèn),而是自作主張使用16bit訪問(wèn),因?yàn)樗l(fā)現(xiàn) cnt 這個(gè)變量操作的地方都是 16 bit,想當(dāng)然的給我在取值時(shí)也給我直接優(yōu)化成 16 bit 訪問(wèn)。

圖片

這樣一來(lái),由于 DMA 不支持 2 字節(jié)訪問(wèn)指令,因此直接 hardfault 了。為了解決這個(gè)優(yōu)化問(wèn)題,可以直接使用 volatile 關(guān)鍵字,保證編譯器在取值時(shí)按照 4 字節(jié)對(duì)齊訪問(wèn),如下:

uint32_t cnt = *((volatile uint32_t*)pinfo->pdma_cnt_rx);  // must: volatile uint32_t
匯編代碼
0x0800BCA6 6800      LDR      r0,[r0,#0x00]

圖片

完結(jié)撒花!

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • CAN通信
    +關(guān)注

    關(guān)注

    5

    文章

    93

    瀏覽量

    17755
  • 串口
    +關(guān)注

    關(guān)注

    14

    文章

    1533

    瀏覽量

    75452
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4670

    瀏覽量

    67764
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    646

    瀏覽量

    32664

原文標(biāo)題:遇見(jiàn)一個(gè)編譯優(yōu)化導(dǎo)致的 bug

文章出處:【微信號(hào):emOsprey,微信公眾號(hào):魚(yú)鷹談單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【GCC編譯優(yōu)化系列】前后編譯的兩版本固件bin大小不樣?

    【GCC編譯優(yōu)化系列】前后編譯的兩個(gè)版本固件bin大小不樣,怎么辦?
    的頭像 發(fā)表于 09-09 09:01 ?4221次閱讀
    【GCC<b class='flag-5'>編譯</b><b class='flag-5'>優(yōu)化</b>系列】前后<b class='flag-5'>編譯</b>的兩版本固件bin大小不<b class='flag-5'>一</b>樣?

    RISC-V中個(gè)優(yōu)化導(dǎo)致的問(wèn)題案例

    本文介紹個(gè)優(yōu)化導(dǎo)致的問(wèn)題案例
    的頭像 發(fā)表于 06-08 10:02 ?581次閱讀
    RISC-V中<b class='flag-5'>一</b><b class='flag-5'>個(gè)</b><b class='flag-5'>優(yōu)化</b><b class='flag-5'>導(dǎo)致</b>的問(wèn)題案例

    IDF4.2.1的編譯優(yōu)化bug導(dǎo)致panic怎么處理?

    == 0) && (status.st_utx_out == 0));} 它是個(gè)inline函數(shù)。我們都認(rèn)為inline關(guān)鍵字,會(huì)告訴編譯器內(nèi)聯(lián)此函數(shù),于是它的代碼
    發(fā)表于 06-21 10:55

    推薦個(gè)時(shí)序優(yōu)化的軟件~~

    Hi,以前在學(xué)校的時(shí)候就經(jīng)常遇見(jiàn)時(shí)序收斂的問(wèn)題,尤其是改RTL好麻煩啊。工作以后和朋友們起做了個(gè)時(shí)序優(yōu)化的軟件,叫InTime,希望可以幫助有相同問(wèn)題的朋友。^_^我們搞了免費(fèi)試用的
    發(fā)表于 05-11 10:55

    編譯優(yōu)化導(dǎo)致USART波特率配置錯(cuò)誤,請(qǐng)問(wèn)這是為什么?如何解決?

    菜鳥(niǎo)枚,遇到問(wèn)題上網(wǎng)找不到答案,只好自己嘗試,請(qǐng)大神指教。 問(wèn)題描述:配置USART的波特率為38400,結(jié)果無(wú)法成功接收數(shù)據(jù),檢查后發(fā)現(xiàn)波特率配置寄存器BRR錯(cuò)誤, 編譯優(yōu)化導(dǎo)致
    發(fā)表于 07-06 03:05

    由于InnoDB MVCC導(dǎo)致的并發(fā)BUG介紹

    [原]記錄個(gè)由于InnoDB MVCC導(dǎo)致的并發(fā)BUG
    發(fā)表于 07-17 09:46

    IAR編譯優(yōu)化等級(jí)設(shè)置介紹

    有限時(shí)可選擇針對(duì)代碼大小進(jìn)行優(yōu)化,對(duì)應(yīng)用實(shí)時(shí)響應(yīng)要求較高的情形則應(yīng)選擇針對(duì)代碼運(yùn)行速度進(jìn)行優(yōu)化。且需注意在項(xiàng)目調(diào)試過(guò)程中不應(yīng)將優(yōu)化等級(jí)設(shè)置的過(guò)高,因高度優(yōu)化會(huì)
    發(fā)表于 11-21 17:36

    IAR9202編譯優(yōu)化導(dǎo)致代碼流程出錯(cuò)

    遇到個(gè)IAR編譯優(yōu)化的問(wèn)題:本想在profile中write callback中做特征值的有效性檢查,卻發(fā)現(xiàn)編譯
    發(fā)表于 03-05 07:46

    rt-studio bug導(dǎo)致編譯失敗如何解決

    我使用rt-studio 編譯工程 , 使用左上角的構(gòu)建功能 編譯成功,但是如果是由旁邊的重新構(gòu)建,就會(huì)報(bào)錯(cuò),錯(cuò)誤如下樣的文件,使用構(gòu)建就可以,重新構(gòu)建就不可以,而且在使用重新構(gòu)建后,再使用構(gòu)建
    發(fā)表于 11-08 10:19

    rt-studio bug導(dǎo)致編譯失敗如何處理?

    我使用rt-studio 編譯工程 , 使用左上角的構(gòu)建功能編譯成功,但是如果是由旁邊的重新構(gòu)建,就會(huì)報(bào)錯(cuò),錯(cuò)誤如下 樣的文件,使用構(gòu)建就可以,重新構(gòu)建就不可以,而且在使用重新構(gòu)建后,再使用構(gòu)建
    發(fā)表于 04-27 10:54

    編譯器_keil的優(yōu)化選項(xiàng)問(wèn)題

    keil編譯器的優(yōu)化選項(xiàng)針對(duì)ARM,對(duì)STM32編譯優(yōu)化的問(wèn)題
    發(fā)表于 02-25 14:18 ?3次下載

    微軟又證實(shí)Bug Windows 10或導(dǎo)致無(wú)法訪問(wèn)互聯(lián)網(wǎng)

    據(jù)外媒報(bào)道稱,微軟證實(shí)了個(gè)新的Bug,那就是Windows 10存在個(gè)可能導(dǎo)致無(wú)法訪問(wèn)互聯(lián)網(wǎng)
    的頭像 發(fā)表于 03-28 11:20 ?2209次閱讀

    個(gè)冗余電路導(dǎo)致BUG

      昨天解了個(gè)BUG,個(gè)低級(jí)錯(cuò)誤導(dǎo)致BUG
    的頭像 發(fā)表于 05-14 15:28 ?789次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>個(gè)</b>冗余電路<b class='flag-5'>導(dǎo)致</b>的<b class='flag-5'>BUG</b>

    編譯器的優(yōu)化選項(xiàng)

    個(gè)程序首先要保證正確性,在保證正確性的基礎(chǔ)上,性能也是個(gè)重要的考量。要編寫(xiě)高性能的程序,第,必須選擇合適的算法和數(shù)據(jù)結(jié)構(gòu);第二,應(yīng)該編
    的頭像 發(fā)表于 11-24 15:37 ?746次閱讀
    <b class='flag-5'>編譯</b>器的<b class='flag-5'>優(yōu)化</b>選項(xiàng)

    Android編譯優(yōu)化之混淆配置

    為了使用java8及后續(xù)java新版本的特性,Google增加了編譯過(guò)程—脫糖(desugaring),但這步會(huì)導(dǎo)致更長(zhǎng)的編譯時(shí)間,這
    的頭像 發(fā)表于 12-21 09:21 ?1637次閱讀
    Android<b class='flag-5'>編譯</b><b class='flag-5'>優(yōu)化</b>之混淆配置