當(dāng)前位置:首頁 > 單片機 > 單片機
[導(dǎo)讀] 在項目處于調(diào)試期間,F(xiàn)ault處理程序可能只是一個斷點指令,調(diào)試器遇到這個指令后停止程序的運行。默認(rèn)情況下,由于非硬Fault被禁能,所有發(fā)生的非Fault都會上訪成硬Fault,因此只要在硬Fault處理程序中設(shè)置一個斷

在項目處于調(diào)試期間,F(xiàn)ault處理程序可能只是一個斷點指令,調(diào)試器遇到這個指令后停止程序的運行。默認(rèn)情況下,由于非硬Fault被禁能,所有發(fā)生的非Fault都會上訪成硬Fault,因此只要在硬Fault處理程序中設(shè)置一個斷點,就可以觀察所有Fault信息。當(dāng)使用MDK-ARM的RealView編譯器時,你可以用下面的C代碼替代默認(rèn)硬Fault處理程序,這段代碼檢測產(chǎn)品是否連接到一個調(diào)試器,只有在連接到一個調(diào)試器的情況下,才會執(zhí)行斷點指令。

voidHardFault_Handler(void){if(CoreDebug->DHCSR&1){//checkC_DEBUGEN==1->DebuggerConnected__breakpoint(0);//haltprogramexecutionhere}while(1);//enterendlessloopotherwise}

說明一下,在這段代碼中,關(guān)于這個CoreDebug->DHCSR也可以在core_cm3.h中找到;__breakpoint()函數(shù)是ARM編譯器所支持的內(nèi)部指令,這個函數(shù)的作用是在指令流中插入一個斷點指令(BKTP)。詳細可以查看編譯器手冊Compiler Reference Guide – Compiler-specific Features - __breakpoint。

為了使能除數(shù)為零以及未對齊內(nèi)存訪問產(chǎn)生Fault,應(yīng)用程序初始化代碼要設(shè)置SCB->CCR寄存器,下面的C代碼清單用于使能除數(shù)為零以及未對齊內(nèi)存訪問產(chǎn)生Fault。

SCB->CCR|=0x18;/*enablediv-by-0andunalignedfault*/

對于最終的應(yīng)用程序,F(xiàn)ault處理程序或許會按照下面所說的實現(xiàn):

系統(tǒng)復(fù)位:通過置一SCB->AIRCR(應(yīng)用程序中斷和復(fù)位控制寄存器)的位2(SYSRESETREQ)。這樣將會強制對調(diào)試設(shè)備之外的所有主要設(shè)備進行一次大的系統(tǒng)復(fù)位。如果你不想復(fù)位整個系統(tǒng),你可以只置一SCB->AIRCR寄存器的位0.(注:LPC1778/88不支持這個位)

恢復(fù):在某些情況下,還是有希望解決產(chǎn)生Fault的問題的。例如,如果程序嘗試訪問了協(xié)處理器,可以通過一個協(xié)處理器的軟件模擬器來解決。

終止任務(wù):如果系統(tǒng)運行了一個RTOS,則相關(guān)的任務(wù)可以被終結(jié)或者重新開始。

注:下面的C代碼清單可以用來使能用法、存儲器管理和總線Fault:

SCB->SHCSR|=0x00007000;//enableUsageFault,BusFault,andMMUFault

利用串口上報Fault異常信息

在調(diào)試期間,最主要的是要弄清楚觸發(fā)了哪類Fault,什么原因觸發(fā)了Fault以及定位到觸發(fā)Fault的代碼,可以利用一份空閑串口當(dāng)作調(diào)試用,將以上信息發(fā)給PC,通過串口調(diào)試助手接收這些Fault信息。

主要步驟如下:

1.如有必要,使能非硬Fault(用法、存儲器管理和總線Fault)

2.如果有必要使能捕獲除法為零和未對齊內(nèi)存訪問

3.編寫Fault處理程序

4.將啟動代碼中默認(rèn)的Fault處理程序更換成自己需要的Fault處理程序

補充一些基礎(chǔ)知識,有利于理解下面的代碼:

堆棧:

Cortex-M3的堆棧是使用“向下生長的滿?!蹦P?,SP指針指向最后一個被壓入堆棧的32位數(shù)值。在下一次壓棧時,SP先自減4,再存入新的數(shù)值。POP操作正好相反,先彈出當(dāng)前SP指針處的32位數(shù)值,再將SP的值增4.

Cortex-M3的異常/中斷過程:

1. 入棧:硬件自動把8個寄存器的值壓入堆棧(8個寄存器依次為:xPSR、PC、LR、R12以及R3~R0)。如果異常發(fā)生時,當(dāng)前的代碼正在使用PSP(進程堆棧),則上面8個寄存器壓入PSP;否則就壓入MSP(主堆棧)。一旦進入服務(wù)例程,就將一直使用MSP。Cortex-M3內(nèi)核響應(yīng)中斷/異常的延時固定為12個時鐘周期。以上操作使用Cortex-M3的數(shù)據(jù)總線。

2.取向量:與入棧同時,Cortex-M3內(nèi)核從向量表中找出正確的異常向量,然后在服務(wù)程序的入口地址欲取指。以上操作使用Cortex-M3的指令總線

3.更新寄存器:入棧和取向量操作完成后,在執(zhí)行服務(wù)例程之前,還要更新一些列寄存器:

SP:在入棧操作后,會把堆棧指針(PSP或MSP)更新到新的位置。在執(zhí)行中斷/異常服務(wù)例程時,一定是使用MSP。

PSR:更新IPSR位段(PSR最低部分)的值為新響應(yīng)的異常編號。

PC:在取向量完成后,PC將指向服務(wù)例程的入口地址。

LR:在出入ISR的時候,LR保存一些在異常返回時用到的特殊位。

寄存器:

1.通用寄存器:R0~R3、R12,C函數(shù)調(diào)用標(biāo)準(zhǔn)會使用R0~R3用來傳遞參數(shù),R12(用于子程序保存SP指針,不太清楚)

2.LR:連接寄存器。LR用于在調(diào)用子程序時存儲返回地址。

3.PC:程序計數(shù)器,CM3內(nèi)部使用了指令流水線,讀PC時返回的值是當(dāng)前指令的地址+4.

4.xPSR程序狀態(tài)寄存器

下面以硬Fault處理為例,介紹一下如何將Fault信息上報到PC的調(diào)試助手上。

1. 在程序初始化代碼中,使能非硬Fault(使用Keil MDK編譯器,必須包含core_cm3.h頭文件)

static__INLINEvoidEnableFault(void){SCB->SHCSR|=(SCB_SHCSR_USGFAULTENA_Msk|SCB_SHCSR_BUSFAULTENA_Msk|SCB_SHCSR_MEMFAULTENA_Msk);}

2. 編寫硬Fault處理程序

/**截獲硬Fault異常*arg:堆棧指針*/voidHardFaultHandle(unsignedint*arg){unsignedintstacked_r0,stacked_r1,stacked_r2,stacked_r3,stacked_r12,stacked_lr,stacked_pc,stacked_psr;stacked_r0=((unsignedlong)arg[0]);stacked_r1=((unsignedlong)arg[1]);stacked_r2=((unsignedlong)arg[2]);stacked_r3=((unsignedlong)arg[3]);stacked_r12=((unsignedlong)arg[4]);stacked_lr=((unsignedlong)arg[5]);stacked_pc=((unsignedlong)arg[6]);stacked_psr=((unsignedlong)arg[7]);PLC_DEBUGF(TEST_DEBUG,("致命錯誤:系統(tǒng)發(fā)生硬Fault!!n"));PLC_DEBUGF(TEST_DEBUG,("捕獲錯誤發(fā)生時的環(huán)境,上報Fault狀態(tài)寄存器:n"));PLC_DEBUGF(TEST_DEBUG,("R0=0x%xn",stacked_r0));PLC_DEBUGF(TEST_DEBUG,("R1=0x%xn",stacked_r1));PLC_DEBUGF(TEST_DEBUG,("R2=0x%xn",stacked_r2));PLC_DEBUGF(TEST_DEBUG,("R3=0x%xn",stacked_r3));PLC_DEBUGF(TEST_DEBUG,("R12=0x%xn",stacked_r12));PLC_DEBUGF(TEST_DEBUG,("LR=0x%xn",stacked_lr));PLC_DEBUGF(TEST_DEBUG,("PC=0x%xn",stacked_pc));PLC_DEBUGF(TEST_DEBUG,("PSR=0x%xn",stacked_psr));PLC_DEBUGF(TEST_DEBUG,("HFSR=0x%xn",HFSR));PLC_DEBUGF(TEST_DEBUG,("BFSR=0x%xn",BFSR));PLC_DEBUGF(TEST_DEBUG,("BFAR=0x%xn",BFAR));PLC_DEBUGF(TEST_DEBUG,("MMSR=0x%xn",MMSR));PLC_DEBUGF(TEST_DEBUG,("MMAR=0x%xn",MMAR));PLC_DEBUGF(TEST_DEBUG,("UFSR=0x%xn",UFSR));HFSR=0xFFFFFFFF;BFSR=0xFF;MMSR=0xFF;UFSR=0xFFFF;while(1);}

3. 在啟動代碼中,將默認(rèn)硬Fault處理程序更換為自己需要的Fault處理程序

HardFault_HandlerPROCIMPORTHardFaultHandleTSTLR,#4ITEEQMRSEQR0,MSPMRSNER0,PSPBHardFaultHandleENDP

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉