ARM 的異常處理學習筆記
這部分比較不好理解。
當異常中斷發(fā)生時,系統(tǒng)執(zhí)行完當前指令后,將跳轉(zhuǎn)到相應的異常中斷處理程序處執(zhí)行。當異常中斷處理程序執(zhí)行完成后,程序返回到發(fā)生中斷指令的下條指令處執(zhí) 行。在進入異常中斷處理程序時,要保存被中斷程序的執(zhí)行現(xiàn)場,從異常中斷處理程序退出時,要恢復被中斷程序的執(zhí)行現(xiàn)場。
1、引起異常的原因
(1)、指令執(zhí)行引起的異常
軟件中斷、未定義指令(包括所要求的協(xié)處理器不存在是的協(xié)處理器指令)、預取址中止(存儲器故障)、數(shù)據(jù)中止。
(2)、外部產(chǎn)生的中斷
復位、FIQ、IRQ。
(1)、指令執(zhí)行引起的異常
軟件中斷、未定義指令(包括所要求的協(xié)處理器不存在是的協(xié)處理器指令)、預取址中止(存儲器故障)、數(shù)據(jù)中止。
(2)、外部產(chǎn)生的中斷
復位、FIQ、IRQ。
2、ARM中異常中斷的種類
(1)、復位(RESET)
a、當處理器復位引腳有效時,系統(tǒng)產(chǎn)生復位異常中斷,程序跳轉(zhuǎn)到復位異常中斷處理程序處執(zhí)行,包括系統(tǒng)加電和系統(tǒng)復位。
b、通過設置PC跳轉(zhuǎn)到復位中斷向量處執(zhí)行稱為軟復位。
a、當處理器復位引腳有效時,系統(tǒng)產(chǎn)生復位異常中斷,程序跳轉(zhuǎn)到復位異常中斷處理程序處執(zhí)行,包括系統(tǒng)加電和系統(tǒng)復位。
b、通過設置PC跳轉(zhuǎn)到復位中斷向量處執(zhí)行稱為軟復位。
(2)、未定義的指令
當ARM處理器或者是系統(tǒng)中的協(xié)處理器認為當前指令未定義時,產(chǎn)生未定義的指令異常中斷,可以通過改異常中斷機制仿真浮點向量運算。
當ARM處理器或者是系統(tǒng)中的協(xié)處理器認為當前指令未定義時,產(chǎn)生未定義的指令異常中斷,可以通過改異常中斷機制仿真浮點向量運算。
(3)、軟件中斷
這是一個由用戶定義的中斷指令(SWI)。可用于用戶模式下的程序調(diào)用特權操作指令。在實時操作系統(tǒng)中可以通過該機制實現(xiàn)系統(tǒng)功能調(diào)用。
這是一個由用戶定義的中斷指令(SWI)。可用于用戶模式下的程序調(diào)用特權操作指令。在實時操作系統(tǒng)中可以通過該機制實現(xiàn)系統(tǒng)功能調(diào)用。
(4)、指令與取終止(Prefech Abort)
如果處理器預取的指令的地址不存在,或者該地址不允許當前指令訪問,當被預取的指令執(zhí)行時,處理器產(chǎn)生指令預取終止異常中斷。
如果處理器預取的指令的地址不存在,或者該地址不允許當前指令訪問,當被預取的指令執(zhí)行時,處理器產(chǎn)生指令預取終止異常中斷。
(5)、數(shù)據(jù)訪問終止(DATAABORT)
如果數(shù)據(jù)訪問指令的目標地址不存在,或者該地址不允許當前指令訪問,處理器產(chǎn)生數(shù)據(jù)訪問終止異常中斷。
如果數(shù)據(jù)訪問指令的目標地址不存在,或者該地址不允許當前指令訪問,處理器產(chǎn)生數(shù)據(jù)訪問終止異常中斷。
(6)、外部中斷請求(IRQ)
當處理器的外部中斷請求引腳有效,而且CPSR的寄存器的I控制位被清除時,處理器產(chǎn)生外部中斷請求異常中斷。系統(tǒng)中個外設通過該異常中斷請求處理服務。
當處理器的外部中斷請求引腳有效,而且CPSR的寄存器的I控制位被清除時,處理器產(chǎn)生外部中斷請求異常中斷。系統(tǒng)中個外設通過該異常中斷請求處理服務。
(7)、快速中斷請求(FIQ)
當處理器的外部快速中斷請求引腳有效,而且CPSR的F控制位被清除時,處理器產(chǎn)生外部中斷請求異常中斷。
當處理器的外部快速中斷請求引腳有效,而且CPSR的F控制位被清除時,處理器產(chǎn)生外部中斷請求異常中斷。
3、異常的響應過程
除了復位異常外,當異常發(fā)生時,ARM處理器盡可能完成當前指令(除了復位異常)后,再去處理異常。并執(zhí)行如下動作:
除了復位異常外,當異常發(fā)生時,ARM處理器盡可能完成當前指令(除了復位異常)后,再去處理異常。并執(zhí)行如下動作:
(1)、將引起異常指令的下一條指令的地址保存到新模式的R14中,若異常是從ARM狀態(tài)進入,LR寄存器中保存的是下一條指令的地址(當前PC+4或 PC+8,與異常的類型有關);若異常是從Thumb狀態(tài)進入,則在LR寄存器中保存當前PC的偏移量,這樣,異常處理程序就不需要確定異常是從何種狀態(tài) 進入的。例如:在軟件中斷異常SWI,指令MOV PC,R14_svc總是返回到下一條指令,不管SWI是在ARM狀態(tài)執(zhí)行,還是在Thumb狀
態(tài)執(zhí)行。
(2)、將CPSR的內(nèi)容保存到要執(zhí)行異常中斷模式的SPSR中。(注意:如果通過程序修改CPSR進入異常模式,硬件將不會將CPSR保存到SPSR中)
(3)、設置CPSR相應的位進入相應的中斷模式。
(4)、通過設置CPSR的第7位來禁止IRQ。如果異常為快速中斷和復位。則還要設置CPSR的第6位來禁止快速中斷。
(5)、給PC強制賦向量地址值。
(2)、將CPSR的內(nèi)容保存到要執(zhí)行異常中斷模式的SPSR中。(注意:如果通過程序修改CPSR進入異常模式,硬件將不會將CPSR保存到SPSR中)
(3)、設置CPSR相應的位進入相應的中斷模式。
(4)、通過設置CPSR的第7位來禁止IRQ。如果異常為快速中斷和復位。則還要設置CPSR的第6位來禁止快速中斷。
(5)、給PC強制賦向量地址值。
ARM處理器內(nèi)核會自動執(zhí)行以上幾步,程序計數(shù)器PC總是跳轉(zhuǎn)到相應的固定地址。
如果異常發(fā)生時,處理器處于Thumb狀態(tài),則當異常向量地址加載入PC時,處理器自動切換到ARM狀態(tài),則異常處理返回時,自動切換到Thumb狀態(tài),即中斷處理只在ARM狀態(tài)下處理。
4、異常中斷處理返回/**下面引用了http://www.mcu16.com/embed/arm/中的內(nèi)容**/
異常處理完畢之后,ARM微處理器會執(zhí)行以下幾步操作從異常返回:
異常處理完畢之后,ARM微處理器會執(zhí)行以下幾步操作從異常返回:
(1)、將所有修改過的用戶寄存器從處理程序的保護棧中恢復。
(2)、將SPSR復制回CPSR中,將連接寄存器LR的值減去相應的偏移量后送到PC中。
(3)、若在進入異常處理時設置了中斷禁止位,要在此清除。
(2)、將SPSR復制回CPSR中,將連接寄存器LR的值減去相應的偏移量后送到PC中。
(3)、若在進入異常處理時設置了中斷禁止位,要在此清除。
復位異常處理程序不需要返回。
5、程序示例分析
下面結合Samsung公司基于ARM7TDMI內(nèi)核的S3C44B0微控制器的啟動代碼詳細說明關于異常處理中的Reset、IRQ和FIQ處理過程及實現(xiàn)方法,
下面結合Samsung公司基于ARM7TDMI內(nèi)核的S3C44B0微控制器的啟動代碼詳細說明關于異常處理中的Reset、IRQ和FIQ處理過程及實現(xiàn)方法,
以下代碼均在Embest IDE 集成開發(fā)環(huán)境下能夠編譯運行并經(jīng)過實際驗證。
.text
#Embest IDE集成開發(fā)環(huán)境可以通過鏈接腳本文件將下面的語句定位在零起始地址,系統(tǒng)上
#加電后CPU從此處開始執(zhí)行。
ENTRY:
b ResetHandler /*0x00000000; for debug*/
b HandlerUndef /*0x00000004; handlerUndef*/
b HandlerSWI /*0x00000008; SWI interrupt handler*/
b HandlerPabort /* 0x0000000C;handlerPAbort*/
b HandlerDabort /*0x00000010; handlerDAbort*/
b . /* handlerReserved */
b HandlerIRQ /* 0x00000018*/
b HandlerFIQ /*0x0000001C */
上面的代碼用于在出現(xiàn)異常時,CPU根據(jù)不同情況利用標號自動跳轉(zhuǎn)到對應的異常處理程序處,分別對應于處理器的7種不同工作模式。當復位后,由零地址的跳 轉(zhuǎn)指令使CPU轉(zhuǎn)去執(zhí)行啟動代碼,它是用于初始化CPU內(nèi)部特殊功能寄存器和外圍電路以及用來為高級語言寫的軟件做好運行前準備的一小段匯編語言,這部分 匯編代碼也可以被成為嵌入式系統(tǒng)的Bootloader。運行完bootloader代碼后,會自動跳轉(zhuǎn)至利用高級語言編寫的系統(tǒng)應用程序或是開始運行操 作 系統(tǒng)內(nèi)核。而對于中斷的處理在系統(tǒng)啟動代碼中對于初學者是較難理解的。
當CPU接收到中斷請求信號之后且允許CPU響應中斷請求,則對于FIQ和非矢量IRQ中斷CPU會根據(jù)中斷控制器設定的工作模式去自動執(zhí)行
.text
#Embest IDE集成開發(fā)環(huán)境可以通過鏈接腳本文件將下面的語句定位在零起始地址,系統(tǒng)上
#加電后CPU從此處開始執(zhí)行。
ENTRY:
b ResetHandler /*0x00000000; for debug*/
b HandlerUndef /*0x00000004; handlerUndef*/
b HandlerSWI /*0x00000008; SWI interrupt handler*/
b HandlerPabort /* 0x0000000C;handlerPAbort*/
b HandlerDabort /*0x00000010; handlerDAbort*/
b . /* handlerReserved */
b HandlerIRQ /* 0x00000018*/
b HandlerFIQ /*0x0000001C */
上面的代碼用于在出現(xiàn)異常時,CPU根據(jù)不同情況利用標號自動跳轉(zhuǎn)到對應的異常處理程序處,分別對應于處理器的7種不同工作模式。當復位后,由零地址的跳 轉(zhuǎn)指令使CPU轉(zhuǎn)去執(zhí)行啟動代碼,它是用于初始化CPU內(nèi)部特殊功能寄存器和外圍電路以及用來為高級語言寫的軟件做好運行前準備的一小段匯編語言,這部分 匯編代碼也可以被成為嵌入式系統(tǒng)的Bootloader。運行完bootloader代碼后,會自動跳轉(zhuǎn)至利用高級語言編寫的系統(tǒng)應用程序或是開始運行操 作 系統(tǒng)內(nèi)核。而對于中斷的處理在系統(tǒng)啟動代碼中對于初學者是較難理解的。
當CPU接收到中斷請求信號之后且允許CPU響應中斷請求,則對于FIQ和非矢量IRQ中斷CPU會根據(jù)中斷控制器設定的工作模式去自動執(zhí)行
0x0000001C 或0x00000018處的跳轉(zhuǎn)指令。執(zhí)行
b HandlerIRQ
#跳轉(zhuǎn)到
HandlerIRQ HANDLER HandleIRQ
#這個宏定義的動作是要跳轉(zhuǎn)到HandleIRQ中存放的地址去運行。
#然后在復位初始化代碼(ResetHandler)中會看到有:
/* Setup IRQ handler*/
ldr r0,=HandleIRQ
ldr r1,=IsrIRQ
str r1,[r0]
這里是把IsrIRQ的地址放到了HandleIRQ中。因此程序會跳轉(zhuǎn)到IsrIRQ去執(zhí)行。
#ARM7TDMI 內(nèi)核只支持FIQ和IRQ兩個中斷請求,當有多個中斷請求信號同時有效的時#候,是利用軟件的方式來完成優(yōu)先級判定,然后再跳轉(zhuǎn)到相應的中斷服務程序。在 IsrIRQ中,CPU會讀取中斷掛起寄存器的數(shù)值來判定中斷來源和優(yōu)先級。而S3C44B0中集成的中斷控制器提供了一種更為快速有效的中斷響應方式: 矢量中斷利用中斷控制器的硬件方式直接提供對中斷服務的快速響應:當多重中斷請求信號發(fā)生時,由硬件優(yōu)先級判定邏輯確定哪個中斷請求將被響應,同時硬件邏 輯還利用向量表中的跳轉(zhuǎn)指令使CPU直接跳轉(zhuǎn)到相應的中斷服務程序入口出。這樣在很大程度上減小了中斷響應的延遲。
那么在程序設計上,就需要我們在矢量中斷表中對應的地址上放置各個中斷請求對應的服務程序入口地址,如:
VECTOR_BRANCH:
ldr pc,=HandlerEINT0 /*0x00000020*/
ldr pc,=HandlerEINT1 /*0x00000024*/
ldr pc,=HandlerEINT2 /*0x00000028*/
ldr pc,=HandlerEINT3 /*0x0000002C*/
ldr pc,=HandlerEINT4567 /*0x00000030*/
ldr pc,=HandlerTICK /*0x00000034 */
b .
b .
ldr pc,=HandlerZDMA0 /*0x00000040*/
ldr pc,=HandlerZDMA1 /*0x00000044*/
……
b HandlerIRQ
#跳轉(zhuǎn)到
HandlerIRQ HANDLER HandleIRQ
#這個宏定義的動作是要跳轉(zhuǎn)到HandleIRQ中存放的地址去運行。
#然后在復位初始化代碼(ResetHandler)中會看到有:
/* Setup IRQ handler*/
ldr r0,=HandleIRQ
ldr r1,=IsrIRQ
str r1,[r0]
這里是把IsrIRQ的地址放到了HandleIRQ中。因此程序會跳轉(zhuǎn)到IsrIRQ去執(zhí)行。
#ARM7TDMI 內(nèi)核只支持FIQ和IRQ兩個中斷請求,當有多個中斷請求信號同時有效的時#候,是利用軟件的方式來完成優(yōu)先級判定,然后再跳轉(zhuǎn)到相應的中斷服務程序。在 IsrIRQ中,CPU會讀取中斷掛起寄存器的數(shù)值來判定中斷來源和優(yōu)先級。而S3C44B0中集成的中斷控制器提供了一種更為快速有效的中斷響應方式: 矢量中斷利用中斷控制器的硬件方式直接提供對中斷服務的快速響應:當多重中斷請求信號發(fā)生時,由硬件優(yōu)先級判定邏輯確定哪個中斷請求將被響應,同時硬件邏 輯還利用向量表中的跳轉(zhuǎn)指令使CPU直接跳轉(zhuǎn)到相應的中斷服務程序入口出。這樣在很大程度上減小了中斷響應的延遲。
那么在程序設計上,就需要我們在矢量中斷表中對應的地址上放置各個中斷請求對應的服務程序入口地址,如:
VECTOR_BRANCH:
ldr pc,=HandlerEINT0 /*0x00000020*/
ldr pc,=HandlerEINT1 /*0x00000024*/
ldr pc,=HandlerEINT2 /*0x00000028*/
ldr pc,=HandlerEINT3 /*0x0000002C*/
ldr pc,=HandlerEINT4567 /*0x00000030*/
ldr pc,=HandlerTICK /*0x00000034 */
b .
b .
ldr pc,=HandlerZDMA0 /*0x00000040*/
ldr pc,=HandlerZDMA1 /*0x00000044*/
……
6、中斷向量表http://www.mcu16.com/embed/arm/arm593.htm
a、中斷向量表指定了個異常中斷及其處理程序的對應關系。他通常存放在存儲地址的低端。在ARM體系中,異常中斷向量表的大小為32字節(jié),其中每個異常中斷占據(jù)4個字節(jié)大小,保留了4個字節(jié)空間。
b、每個異常中斷對應的中斷向量表中的4個字節(jié)的空間中存放了一個跳轉(zhuǎn)指令或者一個向PC寄存器中賦值的數(shù)據(jù)訪問指令。通過這兩種指令,程序?qū)⑻D(zhuǎn)到相應的異常中斷處理程序處執(zhí)行。
c、當幾個異常中斷同時發(fā)生時,系統(tǒng)并不能按照一定的次序來處理這些異常中斷,例如:當FIQ、IRQ和第三個其他中斷同時發(fā)生,F(xiàn)IQ比IRQ優(yōu)先級高,IRQ會忽略,直到FIQ返回到用戶代碼為止。
各個異常中斷的中斷向量地址以及中斷的處理優(yōu)先級
——————————————————————————————————————
中斷向量地址 | 異常中斷類型 | 異常中斷模式 | 優(yōu)先級(6最低) |
—————————|—— ——————|—————————|———— —————|
0x00 | 復位 | 特權模式 | 1 |
0x04 | 未定義的指令 | UND終止模式 | 6 |
0x08 | 軟件中斷 | 特權模式 | 6 |
0x0C | 指令預取終止 | 終止模式 | 5 |
0x10 | 數(shù)據(jù)訪問終止 | 終止模式 | 2 |
0x14 | 保留 | 未使用 | 未使用 |
0x18 | 外部中斷請求 | IRQ模式 | 4 |
0x1C | 快速中斷請求 | FIQ模式 | 3 |
——————————————————————————————————————
7、總結
S3C44B0利用兩個向量表高效而可靠的實現(xiàn)了對異常的處理,掌握了S3C44B0微處理器的異常模式以及對異常處理中復位、FIQ和IRQ響應的過 程,可以在很大程度上幫助我們理解ARM7TDMI內(nèi)核對異常處理的工作原理,有利于理解S3C44B0的啟動代碼(或Bootloader),還可以更 有效的利用芯片的硬件資源編寫出精簡而由高效的嵌入式程序代碼。對嵌入式系統(tǒng)整體設計會起到很大的幫助,是進行嵌入式系統(tǒng)開發(fā)的基礎。
b、每個異常中斷對應的中斷向量表中的4個字節(jié)的空間中存放了一個跳轉(zhuǎn)指令或者一個向PC寄存器中賦值的數(shù)據(jù)訪問指令。通過這兩種指令,程序?qū)⑻D(zhuǎn)到相應的異常中斷處理程序處執(zhí)行。
c、當幾個異常中斷同時發(fā)生時,系統(tǒng)并不能按照一定的次序來處理這些異常中斷,例如:當FIQ、IRQ和第三個其他中斷同時發(fā)生,F(xiàn)IQ比IRQ優(yōu)先級高,IRQ會忽略,直到FIQ返回到用戶代碼為止。
各個異常中斷的中斷向量地址以及中斷的處理優(yōu)先級
——————————————————————————————————————
中斷向量地址 | 異常中斷類型 | 異常中斷模式 | 優(yōu)先級(6最低) |
—————————|—— ——————|—————————|———— —————|
0x00 | 復位 | 特權模式 | 1 |
0x04 | 未定義的指令 | UND終止模式 | 6 |
0x08 | 軟件中斷 | 特權模式 | 6 |
0x0C | 指令預取終止 | 終止模式 | 5 |
0x10 | 數(shù)據(jù)訪問終止 | 終止模式 | 2 |
0x14 | 保留 | 未使用 | 未使用 |
0x18 | 外部中斷請求 | IRQ模式 | 4 |
0x1C | 快速中斷請求 | FIQ模式 | 3 |
——————————————————————————————————————
7、總結
S3C44B0利用兩個向量表高效而可靠的實現(xiàn)了對異常的處理,掌握了S3C44B0微處理器的異常模式以及對異常處理中復位、FIQ和IRQ響應的過 程,可以在很大程度上幫助我們理解ARM7TDMI內(nèi)核對異常處理的工作原理,有利于理解S3C44B0的啟動代碼(或Bootloader),還可以更 有效的利用芯片的硬件資源編寫出精簡而由高效的嵌入式程序代碼。對嵌入式系統(tǒng)整體設計會起到很大的幫助,是進行嵌入式系統(tǒng)開發(fā)的基礎。
評論