- 論壇徽章:
- 0
|
最近項目剛了結(jié),是關(guān)于adi blackfin平臺的,資料還沒有整理好,由于比較著急,所以也沒有時間寫出來。這幾天可以輕松點啦。所以把以前的arm板拿出來,琢磨琢磨。今天理解2440的啟動部分了,有很多不解的地方。上網(wǎng)也查詢了好多資料,還是很有收獲的。主要來說說ARM BOOT的啟動時候的關(guān)于中斷向量的一點理解。
;=======================================================================================
;下面這個宏是用于第一次查表過程的實現(xiàn)中斷向量的重定向,如果你比較細心的話就是發(fā)現(xiàn)
;在_ISR_STARTADDRESS=0x33FF_FF00里定義的第一級中斷向量表是采用型如Handle***的方式的.
;而在程序的ENTRY處(程序開始處)采用的是b Handler***的方式.
;在這里Handler***就是通過HANDLER這個宏和Handle***進立聯(lián)系的.
;這種方式的優(yōu)點就是正真定義的向量數(shù)據(jù)在內(nèi)存空間里,而不是在ENTRY處的ROM(FLASH)空間里,
;這樣,我們就可以在程序里靈活的改動向量的數(shù)據(jù)了.
;========================================================================================
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;減少sp(用于存放轉(zhuǎn)跳地址)
stmfd sp!,{r0} ;把工作寄存器壓入棧(lr does not push because it return to original address)
ldr r0,=$HandleLabel;將HandleXXX的址址放入r0
ldr r0,[r0] ;把HandleXXX所指向的內(nèi)容(也就是中斷程序的入口)放入r0
str r0,[sp,#4] ;把中斷服務程序(ISR)壓入棧
ldmfd sp!,{r0,pc} ;用出棧的方式恢復r0的原值和為pc設定新值(也就完成了到ISR的轉(zhuǎn)跳)
MEND
===================================================================
b ResetHandler ;設成FALSE的話就來到這了,轉(zhuǎn)跳到復位程序入口
b HandlerUndef ;轉(zhuǎn)跳到Undefined mode程序入口
b HandlerSWI ;轉(zhuǎn)跳到SWI 中斷程序入口
b HandlerPabort ;轉(zhuǎn)跳到PAbort(指令異常)程序入口
b HandlerDabort ;轉(zhuǎn)跳到DAbort(數(shù)據(jù)異常)程序入口
b . ;保留
b HandlerIRQ ;轉(zhuǎn)跳到IRQ 中斷程序入口
b HandlerFIQ ;轉(zhuǎn)跳到FIQ 中斷程序入口
=================================================================
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
關(guān)于以上三部分,我是這樣理解的,不知道是否正確,只是希望大家共同學習。
b HandlerUndef ,我認為類似B要跳轉(zhuǎn)的這個函數(shù)是需要我們自己來寫的。而我們要實現(xiàn)的中斷函數(shù)的首地址放在哪呢?放在HandleUndef(注意沒有“r”)定義的地方,一般在sdram的高地址。而執(zhí)行 b HandlerUndef命令,就跳到我們定義的中斷函數(shù)了。為什么呢?原因應該就是關(guān)于那個很煩人的宏定義。也就是以下這段:
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;減少sp(用于存放轉(zhuǎn)跳地址)
stmfd sp!,{r0} ;把工作寄存器壓入棧(lr does not push because it return to original address)
ldr r0,=$HandleLabel;將HandleXXX的址址放入r0
ldr r0,[r0] ;把HandleXXX所指向的內(nèi)容(也就是中斷程序的入口)放入r0
str r0,[sp,#4] ;把中斷服務程序(ISR)壓入棧
ldmfd sp!,{r0,pc} ;用出棧的方式恢復r0的原值和為pc設定新值(也就完成了到ISR的轉(zhuǎn)跳)
MEND
具體怎么跳,我也說不清楚,但是就是找到函數(shù)了。
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u3/95243/showart_1912155.html |
|