這個(gè) 2440test里面的中斷寫的向量有些隱蔽,兜了很多個(gè)圈,也難怪這么難理解,下面
就對這個(gè)東西抽絲剝繭,看清楚這究竟是一個(gè)怎么樣的過程。
中斷向量
b HandlerIRQ ;handler for IRQ interrupt
很自然,因?yàn)樗械膯纹瑱C(jī)都是那樣,中斷向量一般放在開頭,用過單片機(jī)的人都會很熟悉
那就不多說了。
異常服務(wù)程序
這里不用中斷(interrupt)而用異常(exception),畢竟中斷只是異常的一種情況,呵呵
下面主要分析的是“中斷異!闭f白了,就是我們平時(shí)單片機(jī)里面用的中斷。!所有有器件
引起的中斷,例如TIMER中斷,UART中斷,外部中斷等等,都有一個(gè)統(tǒng)一的入口,那就是中斷
異常 IRQ ! 然后從IRQ的服務(wù)函數(shù)里面分辨出,當(dāng)前究竟是什么中斷,再跳轉(zhuǎn)到相應(yīng)的中斷
服務(wù)程序。這樣看來,ARM比單片機(jī)要復(fù)雜一些了,不過原理是不變的。
上面說的就是思路,跟著這個(gè)思路來接著分析。
HandlerIRQ 很明顯是一個(gè)標(biāo)號,我們找到了
HandlerIRQ HANDLER HandleIRQ
這里是一個(gè)宏定義,我們再找到這個(gè)宏,看他是怎么定義的:
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original
address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
用 HandlerIRQ 將這個(gè)宏展開之后得到的結(jié)果實(shí)際是這樣的
HandlerIRQ
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original
address)
ldr r0,=HandleIRQ ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
至于具體的跳轉(zhuǎn)原理下面再說好了,這樣的話就容易看的多了,很明顯, HandlerIRQ 還是一個(gè)標(biāo)號,IRQ異常向量就是跳
轉(zhuǎn)到這里執(zhí)行的,這里粗略看一下,應(yīng)該是保存現(xiàn)場,然后跳轉(zhuǎn)到真正的處理函數(shù),那么很容易
發(fā)現(xiàn)了這么一句 ldr r0,=HandleIRQ ,沒錯(cuò),我們又找到了一個(gè)標(biāo)號 HandleIRQ ,看來真正的處理函數(shù)應(yīng)該是這個(gè) HandleIRQ ,繼續(xù)尋找
AREA RamData, DATA, READWRITE
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
最后我們發(fā)現(xiàn)在這里找到了 HandleIRQ ,^ 其實(shí)就是 MAP ,這段程序的意思是,從 _ISR_STARTADDRESS
開始,預(yù)留一個(gè)變量,每個(gè)變量一個(gè)標(biāo)號,預(yù)留的空間為 4個(gè)字節(jié),也就是 32BIT,其實(shí)這里放的是真正
的C寫的處理函數(shù)的地址,說白了,就是函數(shù)指針 - -
這樣做的話就很靈活了
好好學(xué)習(xí),天天向上作者: Hugo801122 時(shí)間: 2014-2-20 01:41
這個(gè) 2440test里面的中斷寫的向量有些隱蔽,兜了很多個(gè)圈,也難怪這么難理解,下面
就對這個(gè)東西抽絲剝繭,看清楚這究竟是一個(gè)怎么樣的過程。
中斷向量
b HandlerIRQ ;handler for IRQ interrupt
很自然,因?yàn)樗械膯纹瑱C(jī)都是那樣,中斷向量一般放在開頭,用過單片機(jī)的人都會很熟悉
那就不多說了。
異常服務(wù)程序
這里不用中斷(interrupt)而用異常(exception),畢竟中斷只是異常的一種情況,呵呵
下面主要分析的是“中斷異!闭f白了,就是我們平時(shí)單片機(jī)里面用的中斷。!所有有器件
引起的中斷,例如TIMER中斷,UART中斷,外部中斷等等,都有一個(gè)統(tǒng)一的入口,那就是中斷
異常 IRQ ! 然后從IRQ的服務(wù)函數(shù)里面分辨出,當(dāng)前究竟是什么中斷,再跳轉(zhuǎn)到相應(yīng)的中斷
服務(wù)程序。這樣看來,ARM比單片機(jī)要復(fù)雜一些了,不過原理是不變的。
上面說的就是思路,跟著這個(gè)思路來接著分析。
HandlerIRQ 很明顯是一個(gè)標(biāo)號,我們找到了
HandlerIRQ HANDLER HandleIRQ
這里是一個(gè)宏定義,我們再找到這個(gè)宏,看他是怎么定義的:
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} USH the work register to stack(lr does not push because it return to original
address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} OP the work register and pc(jump to ISR)
MEND
用 HandlerIRQ 將這個(gè)宏展開之后得到的結(jié)果實(shí)際是這樣的
HandlerIRQ
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} USH the work register to stack(lr does not push because it return to original
address)
ldr r0,=HandleIRQ ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} OP the work register and pc(jump to ISR)
至于具體的跳轉(zhuǎn)原理下面再說好了,這樣的話就容易看的多了,很明顯, HandlerIRQ 還是一個(gè)標(biāo)號,IRQ異常向量就是跳
轉(zhuǎn)到這里執(zhí)行的,這里粗略看一下,應(yīng)該是保存現(xiàn)場,然后跳轉(zhuǎn)到真正的處理函數(shù),那么很容易
發(fā)現(xiàn)了這么一句 ldr r0,=HandleIRQ ,沒錯(cuò),我們又找到了一個(gè)標(biāo)號 HandleIRQ ,看來真正的處理函數(shù)應(yīng)該是這個(gè) HandleIRQ ,繼續(xù)尋找
AREA RamData, DATA, READWRITE
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
最后我們發(fā)現(xiàn)在這里找到了 HandleIRQ ,^ 其實(shí)就是 MAP ,這段程序的意思是,從 _ISR_STARTADDRESS
開始,預(yù)留一個(gè)變量,每個(gè)變量一個(gè)標(biāo)號,預(yù)留的空間為 4個(gè)字節(jié),也就是 32BIT,其實(shí)這里放的是真正
的C寫的處理函數(shù)的地址,說白了,就是函數(shù)指針 - -
這樣做的話就很靈活了