1.HardFault介紹
在ARM處理器中,如果一個(gè)程序產(chǎn)生了錯(cuò)誤并且被處理器檢測到,就會(huì)產(chǎn)生錯(cuò)誤異常。Cortex-M0+處理器只有一種異常用以處理錯(cuò)誤:HardFault。
HardFault,可重復(fù)且不可能恢復(fù)的故障。當(dāng)它發(fā)生時(shí),意味著微控制器出現(xiàn)了問題,并且需要采取修復(fù)錯(cuò)誤。
2.HardFault錯(cuò)誤是如何產(chǎn)生的
Cortex-M0+產(chǎn)生HardFault錯(cuò)誤的類型主要有以下三種:
存儲(chǔ)器相關(guān):
-- 總線錯(cuò)誤(可以是程序訪問也可以是數(shù)據(jù)訪問),在總線傳輸中使用非法地址會(huì)產(chǎn)生error;
-- 試圖在標(biāo)記為不可執(zhí)行的存儲(chǔ)器區(qū)域內(nèi)執(zhí)行程序;
-- 試圖在系統(tǒng)控制空間中訪問非特權(quán)訪問等級的寄存器(非特權(quán)訪問功能在M0+處理器中為可選功能);
-- 存儲(chǔ)器訪問和定義在存儲(chǔ)器保護(hù)單元中的設(shè)置沖突(存儲(chǔ)器保護(hù)單元在M0+處理器中為可選功能);
程序錯(cuò)誤:
-- 未定義指令的執(zhí)行;
-- 試圖切換至ARM狀態(tài):Cortex-M0+處理器無ARM指令,正常情況下處理器不會(huì)切至ARM狀態(tài);
-- 試圖進(jìn)行非對齊存儲(chǔ)器訪問;
-- Cortex-M0+處理器支持的Thumb指令只能產(chǎn)生對齊訪問,也就是說傳輸?shù)刂分荒苁莻鬏敶笮〉恼麛?shù)倍; 如字傳輸(32位)只能訪問0x0/0x4/0x8/0xc之類的地址;
--通常情況下,使用C編譯器不會(huì)產(chǎn)生任何非對齊訪問(有編譯器自動(dòng)完成);如果C程序直接操作一個(gè)指針,則可能存在非對齊訪問;
-- 使用匯編編程時(shí),也可能會(huì)出現(xiàn)非對齊傳輸;
-- 當(dāng)SVC異常優(yōu)先級與當(dāng)前的優(yōu)先級相比相同或更小時(shí),試圖執(zhí)行SVC指令;
-- SVC只能運(yùn)行在線程模式或者比SVC自身優(yōu)先級低的異常處理中(SVC一般在OS環(huán)境中使用),否則會(huì)觸發(fā)硬件錯(cuò)誤異常;
-- 執(zhí)行異常返回時(shí)EXC_RETURN的值非法;
-- EXC_RETURN在Cortex-M0+處理器中的合法值為0xFFFFFFF1、0xFFFFFFF9、0xFFFFFFFD;
-- 當(dāng)調(diào)試未使能時(shí)(沒有連接調(diào)試器),試圖執(zhí)行斷點(diǎn)指令(BKPT);
-- BKPT指令為調(diào)試過程中提供斷點(diǎn)功能;
中穎芯片硬件模塊操作異常:
-- Flash解鎖寄存器寫入值錯(cuò)誤;
-- Flash解鎖后,重新解鎖;
-- DMA讀取保留地址區(qū)或非法讀寫;
3.如何定位HardFault錯(cuò)誤位置
當(dāng)異常產(chǎn)生時(shí),內(nèi)核會(huì)做如下動(dòng)作:
壓棧并且棧指針(SP)更新;
處理器取出異常向量(確定ISR的起始地址)并將其寫入R15(PC);
寄存器更新(LR、終端程序狀態(tài)寄存器(IPSR)、NVIC)
當(dāng)異常發(fā)生時(shí),8個(gè)寄存器會(huì)被自動(dòng)壓棧,這些寄存器包括R0~R3、R12、R14(LR)、返回地址/PC和xPSR,壓棧順序如下表:

可以通過解析進(jìn)入Hard Fault中斷后的寄存器值及入棧的寄存器值來定位出錯(cuò)位置,并找到問題點(diǎn)。
定位HardFault錯(cuò)誤位置步驟如下:

4.舉例說明如何定位HardFault錯(cuò)誤位置
使用調(diào)試器(以MDK編譯器為例)
--在工程中創(chuàng)建HardFault中斷處理函數(shù),并在其函數(shù)中添加硬件斷點(diǎn)或斷點(diǎn)指令(BKPT),當(dāng)發(fā)生HardFault錯(cuò)誤時(shí),處理器會(huì)自動(dòng)暫停到斷點(diǎn)或斷點(diǎn)指令處
;

-- 根據(jù)章節(jié)3中的HardFault錯(cuò)誤分析流程,找到發(fā)生HardFault錯(cuò)誤時(shí)的地址位置;

-- 結(jié)合程序分析具體出錯(cuò)原因。
無調(diào)試器 -- 當(dāng)仿真口被占用時(shí),需要通過串口或其他接口,提取并輸出發(fā)生HardFault錯(cuò)誤時(shí)的各調(diào)試信息; -- 下面以串口為例,說明如何實(shí)現(xiàn)調(diào)試信息的輸出: -- 在startup_xxx.s啟動(dòng)文件的“HardFault_Handler”中做如下處理:

-- 屏蔽C程序中的“HardFault_Handler”中斷服務(wù)程序,增加棧數(shù)據(jù)輸出函數(shù)“HardFault_Handler_c”,如下:

-- 發(fā)生HardFault錯(cuò)誤后,串口軟件會(huì)輸出當(dāng)前寄存器及棧內(nèi)的寄存器值,通過章節(jié)3中的HardFault錯(cuò)誤定位流程,進(jìn)一步分析錯(cuò)誤原因。

5、如何避免產(chǎn)生Hard Fault
?給棧預(yù)留足夠的空間:
-- 工程編譯后,在生成的編譯信息文件中,找到以工程名命名的.htm文件,此文件列出工程使用的棧最大長度(如下);
-- 一般在此基礎(chǔ)上增加至少0.5倍(預(yù)留給中斷服務(wù)程序及其臨時(shí)變量),配置為棧大??;
?在C語言嵌套匯編代碼時(shí),請注意匯編指令是否存在非對齊情況;若存在,請?jiān)黾覰OP指令使其對齊;
?程序中不使用斷點(diǎn)指令(BKPT);若調(diào)試過程中使用了斷點(diǎn)指令,請?jiān)诔绦騌elease時(shí)屏蔽此斷點(diǎn)指令;
?非OS應(yīng)用,不使用SVC指令;
?正確配置芯片的硬件模塊,避免引起HardFault錯(cuò)誤。
-
微控制器
+關(guān)注
關(guān)注
48文章
8196瀏覽量
160518 -
處理器
+關(guān)注
關(guān)注
68文章
20084瀏覽量
243891 -
ARM
+關(guān)注
關(guān)注
135文章
9467瀏覽量
386865 -
Cortex
+關(guān)注
關(guān)注
2文章
217瀏覽量
48192
原文標(biāo)題:Cortex-M0+ HardFault錯(cuò)誤介紹
文章出處:【微信號:SINO_25181447,微信公眾號:中穎電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
如何選擇正確的Cortex-M處理器?
ARM Cortex-M0+中斷機(jī)制和中斷編程步驟
ARM Cortex-M0+內(nèi)核定時(shí)器
ARM Cortex-M0+處理器數(shù)據(jù)表
Cortex-M0+——ARM推出全球最節(jié)能處理器
ARM發(fā)布Cortex-M0+處理器號稱世界最高效
飛思卡爾率先推出Cortex-M0+控制器,為何投入ARM懷抱?
關(guān)于最低功耗ARM Cortex-M0+的ARM處理器的介紹
Cortex-M0+指令集
cortex內(nèi)核hardfault錯(cuò)誤的定位方法實(shí)戰(zhàn)
Cortex M0 HardFault診斷應(yīng)用筆記
AN028 Cortex-M3內(nèi)核HardFault錯(cuò)誤調(diào)試定位方法
Cortex-M0+內(nèi)核介紹

Cortex-M0+處理器的HardFault錯(cuò)誤介紹
評論