ARM的中斷分析

對于學(xué)習(xí)ARM的朋友來說,中斷處理是一塊硬骨頭,尤其是中斷向量表以及中斷的跳轉(zhuǎn)。下面主要對中斷向量表的建立問題及重映射問題進(jìn)行探討。近來做一些東西用到中斷時(shí),總會(huì)出現(xiàn)一些問題。

各種Bootloader的初始化相關(guān)代碼摘要,首先來看下面的程序:
DRAM_BASE //DRAM的基地址
HandleReset # 4 // 空留4個(gè)單元
HandleUndef # 4
HandleSwi # 4
HandlePrefetch # 4 //用于填充地址的
HandleAbort # 4
HandleReserv # 4
HandleIrq # 4
HandleFiq # 4
注: 這里的^是RMAP,#是FIELD,分配的意思
就是在SDARM的BANK0開始的地方定義了一個(gè)中斷向量表,相當(dāng)于0地址的FLASH??樟魡卧糜诖娣胖袛喑绦虻娜肟诘刂贰?br> ExceptionHandlerTable //實(shí)際的映射地址
DCD UserCodeArea
DCD SystemUndefinedHandler
DCD SystemSwiHandler
DCD SystemPrefetchHandler
DCD SystemAbortHandler
DCD SystemReserv
DCD SystemIrqHandler
DCD SystemFiqHandler
這個(gè)表中存放的是匯編程序中中斷處理函數(shù)的入口地址,每一項(xiàng)對應(yīng)一個(gè)中斷函數(shù)。這次的跳轉(zhuǎn)后就進(jìn)入了C服務(wù)程序。
從初始化程序的開始處來看:(各種Bootloader的初始化代碼)
AREA Init, CODE, READONLY //相當(dāng)于init進(jìn)程
ENTRY //入口
B Reset_Handler
B Undefined_Handler //無條件的跳轉(zhuǎn)
B SWI_Handler
B Prefetch_Handler
B Abort_Handler
NOP Reserved vector
B IRQ_Handler
B FIQ_Handler

FIQ_Handler
SUB sp, sp, #4
STMFD sp!, {r0} FD滿遞減堆棧 執(zhí)行寄存器壓棧操作.
LDR r0, =HandleFiq 匯編里的處理函數(shù)地址,然后跳到C中,在DRAM。
LDR r0, [r0] 中斷向量地址給R0.
STR r0, [sp, #4] 中斷向量地址給PC
LDMFD sp!, {r0, pc}

稍微解釋一下:
首先執(zhí)行了壓棧,然后給出了中斷入口地址.這個(gè)HandleFiq就是我們前面的在DRAM中建立的中斷向量其中一個(gè)的地址。
在HandleFiq開始的四個(gè)字節(jié)中,放著匯編中斷處理函數(shù)的入口地址。
那么匯編中斷處理函數(shù)的地址是如何放到DRAM中斷向量表里的呢?
上面的第一個(gè)表就起作用了??聪旅孢@段程序:
EXCEPTION_VECTOR_TABLE_SETUP
LDR r0, =HandleReset
LDR r1, =ExceptionHandlerTable
MOV r2, #8

ExceptLoop
LDR r3, [r1], #4
STR r3, [r0], #4
SUBS r2, r2, #1 //填充8個(gè)地址
BNE ExceptLoop //從表里取出來給了HandleReset后面的空間
這一段把ExceptionHandlerTable里的中斷處理函數(shù)的地址拷給了SDRAM里的中斷向量表。這樣兩者就聯(lián)系起來了。
在執(zhí)行程序開始的跳轉(zhuǎn)之后就自然跳到了*****Handler.真正的處理函數(shù)如下:
它實(shí)際上只調(diào)用了C語言的中斷處理函數(shù),其他什么也沒做。
SystemFiqHandler
IMPORT ISR_FiqHandler
STMFD sp!, {r0-r7, lr}
BL ISR_FiqHandler //真正的中斷處理服務(wù)函數(shù)
LDMFD sp!, {r0-r7, lr}
SUBS pc, lr, #4
它實(shí)際上只調(diào)用了C語言的中斷處理函數(shù),其他什么也沒做。寫中斷處理服務(wù)程序其實(shí)就只寫C中相應(yīng)的處理部分就好了。

void ISR_FiqHandler(void)
{
IntOffSet = (U32)INTOFFSET;
(IntOffSet>>2)
(*InterruptHandlers[IntOffSet>>2])(); // Call interrupt service routine
}

其實(shí)就是將中斷向量表重映射,以提高中斷的響應(yīng)速度。代碼在SDRAM的運(yùn)行速度要比在FLASH中運(yùn)行速度快。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容