
目錄預(yù)覽
1. 概述
2. 問題描述與分析
3. 問題解決
4. 總結(jié)
1.概述
客戶在使用 STM32G070 的時候,KEIL MDK 為編譯工具,當(dāng)編譯優(yōu)化選項(xiàng)設(shè)置為Level0 的時候,程序會出現(xiàn) Hard Fault 異常,而當(dāng)編譯優(yōu)化選項(xiàng)設(shè)置為 Level1 的時候,則程序運(yùn)行正常。
表面上看,這似乎是 KEIL MDK 的問題,通過分析,導(dǎo)致這個問題的本質(zhì)原因是內(nèi)存地址沒有對齊引起的,下面章節(jié)將詳細(xì)分析該問題的來龍去脈以及解決方法。
問題描述與分析
根據(jù)客戶的反饋,引起問題的代碼很簡單,客戶定義了幾個全局?jǐn)?shù)組,在主程序中訪問這幾個數(shù)組就會出現(xiàn) Hard Fault 異常,參考代碼如下。

把客戶提供的代碼片段移植到 NUCLEO-G070RB 開發(fā)板上,問題很容易就復(fù)現(xiàn)了,代碼本身功能簡單,寫法上也沒有錯誤,所以從代碼片段本身上看,無法確定問題出在哪里,通過 KEIL 調(diào)試器,在匯編窗口單步調(diào)試下,最終發(fā)現(xiàn)導(dǎo)致 HardFault 異常的語句為下圖所示語句。

根據(jù)單步調(diào)試得知出現(xiàn)問題的語句為 LDR 指令,參考 Cortex M0 編程手冊 PM0223 得知 LDR 指令的作用是從內(nèi)存地址中加載一個 WORD 數(shù)據(jù)到目的寄存器 Rt 中,其中內(nèi)存地址根據(jù) Rn 或者 SP 寄存器的值以及立即數(shù) imm 得到。

根據(jù)指令的描述,使用 LDR 指令的時候,通過 Rn 和 imm 計(jì)算得到的內(nèi)存地址必須是讀取字節(jié)數(shù)的倍數(shù),LDR 每次讀取一個 WORD,所以使用 LDR 指令時,內(nèi)存地址必須 4字節(jié)對齊。如果地址沒有對齊,則會導(dǎo)致 HardFault 異常。
結(jié)合 LDR 指令的描述,在調(diào)試狀態(tài)下,通過查看寄存器值,圖 2 出錯語句中根據(jù) Rn和 imm 計(jì)算得到的內(nèi)存地址為 R0=0x2000000B,imm=4 所以內(nèi)存地址為 0x2000000F,很顯然這個地址不是 4 字節(jié)對齊的。

而當(dāng)我們改變編譯優(yōu)化選項(xiàng)為 Level1 時,得到的內(nèi)存地址為R0=0x20000000,imm=0x04 顯然這個地址是按照 4 字節(jié)對齊的,所以這種情況下是不會出現(xiàn) HardFault 異常的,印證了客戶的問題現(xiàn)象。

3.問題解決
通過上一節(jié)的分析,明確了導(dǎo)致該問題的本質(zhì)原因是內(nèi)存地址沒有對齊,這個內(nèi)存地址實(shí)際上是代碼中定義的全局變量 g_curPlaySound_app 指向的地址,也就是全局?jǐn)?shù)組變量 SoundFile 的地址,在編譯器不同的優(yōu)化選項(xiàng)下,分配給 SoundFile 變量的地址是不一樣的,在本案例中,編譯優(yōu)化選項(xiàng) Level0 條件下,SoundFile 分配的地址沒有按照WORD 對齊,而在優(yōu)化選項(xiàng) Level1 條件下,SoundFile 分配的地址是 WORD 對齊,所以在兩種優(yōu)化選項(xiàng)下,出現(xiàn)了不一樣的運(yùn)行結(jié)果。
所以要保證程序不出錯,當(dāng)通過指針訪問變量的時候,要確保指針指向的地址是 4 字節(jié)對齊的,在 Keil 環(huán)境下,可以通過__attribute__((aligned (4))) 關(guān)鍵字實(shí)現(xiàn),如下圖所示,通過該關(guān)鍵字,對齊了地址,也就不會出現(xiàn) HardFault 異常了。
圖6 確保地址對齊

4.總結(jié)
地址未對齊是嵌入式系統(tǒng)中容易忽視的一個細(xì)節(jié),忽視這點(diǎn)往往會導(dǎo)致一些奇怪的問題,所以在開發(fā)過程中,注意這些細(xì)節(jié)還是很有必要的。

長按掃碼關(guān)注公眾號
更多資訊,盡在STM32
▽點(diǎn)擊“閱讀原文”,可下載原文檔
-
單片機(jī)
+關(guān)注
關(guān)注
6059文章
44828瀏覽量
645036 -
STM32
+關(guān)注
關(guān)注
2285文章
10987瀏覽量
361477
原文標(biāo)題:工程師筆記|一個地址未對齊引起的 HardFault 異常
文章出處:【微信號:STM32_STM8_MCU,微信公眾號:STM32單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄

(仰天長嘯)為什么受傷的總是硬件工程師...#MDD#MDD辰達(dá)半導(dǎo)體 #電子工程師



STM32H7 0x00000000地址的內(nèi)容引發(fā)hardfault怎么解決?

硬件工程師的終極幻想:焊板子焊上人生巔峰!#半導(dǎo)體器件 #硬件工程師 #MDD辰達(dá)半導(dǎo)體

不同時期的硬件工程師,最怕發(fā)生的事 #電子工程師 #硬件工程師 #內(nèi)容過于真實(shí) #YXC晶振 #揚(yáng)興科技


當(dāng)你的工程師朋友失聯(lián)時,別氣,ta真的是在忙工作 #搞笑 #電子愛好者 #硬件工程師 #晶振 #揚(yáng)興科技

硬件工程師VS軟件工程師|硬件工程師看到這都淚目了!#硬件設(shè)計(jì) #硬件工程師 #電子工程師 #軟件工程師
FPGA算法工程師、邏輯工程師、原型驗(yàn)證工程師有什么區(qū)別?


干硬件這一行,各種辛酸只有同行才懂吧 ? #電路設(shè)計(jì) #電子愛好者 #硬件工程師 #電子工程師
嵌入式軟件工程師和硬件工程師的區(qū)別?

評論