RM新时代网站-首页

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

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

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

一個地址未對齊引起的HardFault異常

jf_pJlTbmA9 ? 來源:STM32單片機 ? 作者:STM32單片機 ? 2023-09-18 10:57 ? 次閱讀

1.概述

客戶在使用 STM32G070 的時候,KEIL MDK 為編譯工具,當編譯優(yōu)化選項設(shè)置為Level0 的時候,程序會出現(xiàn) Hard Fault 異常,而當編譯優(yōu)化選項設(shè)置為 Level1 的時候,則程序運行正常。

表面上看,這似乎是 KEIL MDK 的問題,通過分析,導致這個問題的本質(zhì)原因是內(nèi)存地址沒有對齊引起的,下面章節(jié)將詳細分析該問題的來龍去脈以及解決方法。

2.問題描述與分析

根據(jù)客戶的反饋,引起問題的代碼很簡單,客戶定義了幾個全局數(shù)組,在主程序中訪問這幾個數(shù)組就會出現(xiàn) Hard Fault 異常,參考代碼如下。

wKgaomUDzW-ASSFXAAKMO7qO1zU016.png

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

wKgaomUDzXSAKy7hAAIJqOIWXwQ854.png

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

wKgZomUDzXaAfhbqAAFcPh7FuT4672.png

根據(jù)指令的描述,使用 LDR 指令的時候,通過 Rn 和 imm 計算得到的內(nèi)存地址必須是讀取字節(jié)數(shù)的倍數(shù),LDR 每次讀取一個 WORD,所以使用 LDR 指令時,內(nèi)存地址必須 4字節(jié)對齊。如果地址沒有對齊,則會導致 HardFault 異常。

結(jié)合 LDR 指令的描述,在調(diào)試狀態(tài)下,通過查看寄存器值,圖 2 出錯語句中根據(jù) Rn和 imm 計算得到的內(nèi)存地址為 R0=0x2000000B,imm=4 所以內(nèi)存地址為 0x2000000F,很顯然這個地址不是 4 字節(jié)對齊的。

wKgaomUDzXiAXrhKAAHpxnz5tEs892.png

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

wKgZomUDzXyAA6YsAAH2kOHpX_o908.png

3.問題解決

通過上一節(jié)的分析,明確了導致該問題的本質(zhì)原因是內(nèi)存地址沒有對齊,這個內(nèi)存地址實際上是代碼中定義的全局變量 g_curPlaySound_app 指向的地址,也就是全局數(shù)組變量 SoundFile 的地址,在編譯器不同的優(yōu)化選項下,分配給 SoundFile 變量的地址是不一樣的,在本案例中,編譯優(yōu)化選項 Level0 條件下,SoundFile 分配的地址沒有按照WORD 對齊,而在優(yōu)化選項 Level1 條件下,SoundFile 分配的地址是 WORD 對齊,所以在兩種優(yōu)化選項下,出現(xiàn)了不一樣的運行結(jié)果。

所以要保證程序不出錯,當通過指針訪問變量的時候,要確保指針指向的地址是 4 字節(jié)對齊的,在 Keil 環(huán)境下,可以通過__attribute__((aligned (4))) 關(guān)鍵字實現(xiàn),如下圖所示,通過該關(guān)鍵字,對齊了地址,也就不會出現(xiàn) HardFault 異常了。

圖6 確保地址對齊

wKgaomUDzX6AMKw_AALxznUvPqE621.png

4.總結(jié)

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

來源:STM32單片機

審核編輯:湯梓紅

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

    關(guān)注

    6035

    文章

    44554

    瀏覽量

    634631
  • 嵌入式系統(tǒng)
    +關(guān)注

    關(guān)注

    41

    文章

    3587

    瀏覽量

    129435
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10895

    瀏覽量

    355729
  • MDK
    MDK
    +關(guān)注

    關(guān)注

    4

    文章

    209

    瀏覽量

    32063
收藏 人收藏

    評論

    相關(guān)推薦

    RISC-V對齊導致問題案例

    本文介紹對齊導致問題案例
    的頭像 發(fā)表于 06-08 10:04 ?1691次閱讀
    RISC-V<b class='flag-5'>未</b><b class='flag-5'>對齊</b>導致問題案例

    基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的堆(內(nèi)存池)對齊導致問題的案例分享

    本文轉(zhuǎn)自公眾號歡迎關(guān)注 https://mp.weixin.qq.com/s/ErIa2ss2YZLGYbSwoJEzog .?前言 內(nèi)存對齊訪問問題這個已經(jīng)是老生常談的問題了, 由于LWIP
    的頭像 發(fā)表于 09-09 08:44 ?1719次閱讀
    基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的堆(內(nèi)存池)<b class='flag-5'>未</b><b class='flag-5'>對齊</b>導致問題的案例分享

    HardFault_Handler異常

    請教各位,最近用MDK5.11編寫STM32F103RC的程序,但是卻莫名其妙進入HardFault_Handler異常中斷,現(xiàn)在本人完全頭霧水,還請大神指點迷津!
    發(fā)表于 11-07 17:51

    靈動微課堂 (第173講) | HardFault定位方法和步驟

    復位之外的任何異常搶占。 HardFault HardFault 是由于在正常操作過程中或在異常處理過程中出現(xiàn)錯誤而出現(xiàn)的
    發(fā)表于 07-02 15:20

    為什么要進行內(nèi)存對齊操作呢

    地址上的任意數(shù)據(jù)的;某些硬件平臺只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。性能原因:數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應該盡可能地在自然邊界上對齊。原因在于,為了訪問
    發(fā)表于 12-17 06:34

    導致STM32進入HardFault異常的原因

    圖所示程序進入HardFault異常。如下所示我們找到SP寄存器,0x200045B8即為棧地址,棧里面的值依次為R0~R3、R12、PC(Return address)、xPSR(CPS...
    發(fā)表于 01-07 06:52

    ARM處理器是否曾經(jīng)為指令或數(shù)據(jù)訪問生成對齊的突發(fā)

    節(jié))數(shù)據(jù)包與32位邊界對齊。然后顯示了對齊的第一個字節(jié)的突發(fā)示例。我還看到了有關(guān)在突發(fā)寫
    發(fā)表于 08-19 15:43

    iMXRT1170的cortex M7上的HardFault異常是怎么回事?

    HardFault 異常)。下面是來自 IAR EW 的錯誤圖像。代碼行僅執(zhí)行從結(jié)構(gòu)到另一個結(jié)構(gòu)變量的賦值操作。 誰能告訴我們?yōu)槭裁磿?/div>
    發(fā)表于 04-04 07:42

    RISC-V對齊訪問導致問題案例

    轉(zhuǎn)自公眾號,歡迎關(guān)注 參考https://mp.weixin.qq.com/s/8wfRFg1XcBsXw5gMq-cKaQ前言 本文以實例,講解RISC-V對齊訪問導致的問題.
    發(fā)表于 05-06 19:14

    MRS_關(guān)于HardFault問題查找思路

    ,MTVAL=20000ca1。由表可知該案例的報錯原因為Load指令訪存地址對齊,結(jié)合MTVAL的情況1可知異常時存儲器訪問的地址為0
    發(fā)表于 08-24 10:57

    異常向量表重映射

    異常向量表重映射 向量表是異常產(chǎn)生時內(nèi)核獲取異常處理函數(shù)入口地址塊連續(xù)內(nèi)存,每一個
    發(fā)表于 03-26 09:34 ?20次下載

    地址對齊有關(guān)的應用異常案例

    也就是說,基于CortexM3內(nèi)核的芯片,它支持部分指令的非對齊訪問,但非對齊訪問要慢于對齊訪問。即非對齊訪問是需要代價的,訪問效率會受到影響。所以,我們在應用中要盡量遵循
    的頭像 發(fā)表于 02-04 15:20 ?2560次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>個</b>跟<b class='flag-5'>地址</b><b class='flag-5'>對齊</b>有關(guān)的應用<b class='flag-5'>異常</b>案例

    解決STM32因字節(jié)對齊問題導致讀寫Flash失敗進入HardFault的問題

    ,獲取升級包的文件所有結(jié)構(gòu)體采用字節(jié)對齊,解析升級包采用指針偏移的方式。進入Flash未進行擦除操作前的參數(shù)如下:要寫入的長度和地址都是沒問題的,但是buf指針的在RAM中的地址為0
    發(fā)表于 12-02 09:06 ?15次下載
    解決STM32因字節(jié)<b class='flag-5'>對齊</b>問題導致讀寫Flash失敗進入<b class='flag-5'>HardFault</b>的問題

    工程師筆記|地址對齊引起的 HardFault 異常

    關(guān)鍵詞:地址對齊,Hardfault,STM32G0 目錄預覽 1. 概述 2. 問題描述與分析 3. 問題解決 4. 總結(jié) 1.概述 客戶在使用 STM32G070 的時候,KEIL MDK 為
    的頭像 發(fā)表于 02-10 11:05 ?2235次閱讀

    ES32F36xx芯片發(fā)生HardFault異常時的函數(shù)調(diào)用關(guān)系及問題定位

    ES32F36xx芯片發(fā)生HardFault異常時的函數(shù)調(diào)用關(guān)系及問題定位
    的頭像 發(fā)表于 11-06 17:13 ?762次閱讀
    ES32F36xx芯片發(fā)生<b class='flag-5'>HardFault</b><b class='flag-5'>異常</b>時的函數(shù)調(diào)用關(guān)系及問題定位
    RM新时代网站-首页