新聞中心

ARM的異常處理過程分析

作者: 時(shí)間:2016-12-01 來源:網(wǎng)絡(luò) 收藏
異常類型
Mode
異常向量
內(nèi)容
IRQ異常
IRQ
0x00000018
LDR PC,[PC,#0x18]或者0xE59FF018
IFQ異常
IFQ
0x0000001C
LDR PC,[PC,#0x18]
0xE59FF018
0x00000038
Address of OS_CPU_ARM_ExceptIrqHndlr()
0x0000003C
Address of OS_CPU_ARM_ExceptFiqHndlr()
有必要的討論一下,為什么在向量中存儲(chǔ)的是指令: LDR PC,[PC,#0x18],我們從上面的地址可以知道,IRQ異常處理函數(shù)地址被存儲(chǔ)到了0x00000038中,異常向量與該地址之間的差值是0x20,那么為什么在其中存儲(chǔ)的值只是0x18呢?這還要討論ARM的流水線結(jié)構(gòu),當(dāng)前執(zhí)行的命令相比PC指向的地址差0x08。也就是當(dāng)前執(zhí)行的指令的地址是PC-0x08.當(dāng)PC指向異常向量以后(取值),還需要等待一個(gè)時(shí)鐘(譯碼)之后才會(huì)被執(zhí)行(真正意義上的執(zhí)行操作),而這時(shí)PC值已經(jīng)被更新了。指向了Vector+0x8的位置,因此我們可以知道,當(dāng)執(zhí)行向量中的代碼時(shí),這時(shí)PC=Vector+0x8,而這時(shí)相對(duì)于固定的0x20-0x08=0x18,這也就是為什么是LDR PC,[PC,#0x18],而不是LDR PC,[PC,#0x20].
采用上面的例子說明IRQ的向量為0x00000018,而設(shè)定好的固定地址用來存儲(chǔ)對(duì)應(yīng)異常處理函數(shù)地址的地址是0x00000038,當(dāng)CPU執(zhí)行完P(guān)C = 0x00000018以后,還需要譯碼、才能被執(zhí)行,這時(shí)候PC值已經(jīng)更新為PC = 0x00000018 + 0x08;這時(shí)候固定地址距離PC的相對(duì)位置位0x00000038 – PC = 0x18,而該地址中保存了IRQ中斷的通用處理函數(shù)OS_CPU_ARM_ExceptIrqHndlr()的地址,LDR PC,[PC,#0x18]這條指令是指將PC+0x18地址處的內(nèi)容加載到PC中,實(shí)質(zhì)上也就完成跳轉(zhuǎn)到異常處理函數(shù)的操作。
這樣處理的好處是因?yàn)長DR的加載范圍是一個(gè)固定值+-32M,我們不能保證異常處理程序的地址剛好在+-32M左右,采用這種LDR PC, ADDR(固定地址)的形式就能實(shí)現(xiàn)大范圍的跳轉(zhuǎn)操作。
我們僅僅以FIQ中斷處理的形式進(jìn)行討論,其他的異常有一定的相似性,只是在返回地址上存在差別。這段代碼主要是完成寄存器的壓棧,返回地址的調(diào)整,保存等操作。具體的看下面的分析:
AREA CODE, CODE, READONLY
CODE32
OS_CPU_ARM_ExceptFiqHndlr
;修改中斷返回地址,這屬于進(jìn)入真正處理函數(shù)前的返回地址調(diào)整,具體的返回地址依據(jù)前面保存的R14進(jìn)行相應(yīng)的修改。
SUB LR, LR, #4 ; LR offset to return from this exception: -4.
;壓棧操作
STMFD SP!, {R0-R12, LR} ; Push working registers.
;保存鏈接寄存器
MOV R2, LR ; Save link register.
;設(shè)置好ID號(hào),這是非常必要的,只有這樣才能辨別屬于那種異常
MOV R0, #OS_CPU_ARM_EXCEPT_FIQ ; Set exception ID
/*跳轉(zhuǎn)到通用的異常處理函數(shù),傳遞的參數(shù)是異常ID號(hào)*/
BOS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
OS_CPU_ARM_ExceptHndlr(except_type)是一個(gè)通用的異常處理函數(shù),可以對(duì)除了IRQ以外的其他異常進(jìn)行控制操作。在這個(gè)通用處理函數(shù)中又調(diào)用了下面的函數(shù)OS_CPU_ARM_ExceptHndlr_BreakExcept()或者OS_CPU_ARM_ExceptHndlr_BreakTask()。這兩個(gè)函數(shù)中又調(diào)用了通用處理函數(shù)OS_CPU_ExceptHndlr(),然后OS_CPU_ExceptHndlr()中調(diào)用具體的中斷處理操作。
一般的OS_CPU_ExceptHndlr()處理形式,可以認(rèn)為是一個(gè)模板如下:
void OS_CPU_ExceptHndlr (INT32U except_type)
{
/* Determine behavior according to exception type (except_type) */
/* If an IRQ or FIQ,具體的可能要使用中斷向量等形式實(shí)現(xiàn)*/
while (there are interrupting devices) {
/* Clear interrupting device */
OS_CPU_SR_INT_En(); /* Enable nesting, if desired */
/* Handle interrupt */
}
}
這是其中的一段關(guān)于IRQ中斷的文字復(fù)述:
IRQ中斷的基本的流程圖如下:
以上的uC/OS-II異常處理就分析完了,這種方式的實(shí)現(xiàn)實(shí)質(zhì)上是采用了通用模板的形式,這樣實(shí)現(xiàn)出來的形式只需要控制一定的,具體的一些IRQ中斷處理函數(shù)(如定時(shí)器,GPIO等的中斷),與具體的廠商有很大的關(guān)系,有的廠商采用硬件寄存器的方式進(jìn)行設(shè)計(jì),有的采用軟件方式實(shí)現(xiàn),因此具體的中斷。
后面我再分析我們通常認(rèn)為的中斷(實(shí)質(zhì)上就是IRQ和IFQ中某一個(gè)具體中斷)處理方式
上一頁 1 2 3 下一頁

關(guān)鍵詞: ARM異常處理過程分

評(píng)論


技術(shù)專區(qū)

關(guān)閉