超詳細(xì)的2440中斷機(jī)制分析!
中斷向量
b HandlerIRQ ;handler for IRQ interrupt
很自然,因?yàn)樗械膯纹瑱C(jī)都是那樣,中斷向量一般放在開頭,用過單片機(jī)的人都會(huì)很熟悉,那就不多說了。
異常服務(wù)程序
這里不用中斷(interrupt)而用異常(exception),畢竟中斷只是異常的一種情況,
下面主要分析的是“中斷異常”說白了,就是我們平時(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)號(hào),我們找到了
HandlerIRQ HANDLER HandleIRQ
這里是一個(gè)宏定義,我們?cè)僬业竭@個(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)號(hào),IRQ異常向量就是跳轉(zhuǎn)到這里執(zhí)行的,這里粗略看一下,應(yīng)該是保存現(xiàn)場(chǎng),然后跳轉(zhuǎn)到真正的處理函數(shù),那么很容易發(fā)現(xiàn)了這么一句 ldr r0,=HandleIRQ ,沒錯(cuò),我們又找到了一個(gè)標(biāo)號(hà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)號(hào),預(yù)留的空間為 4個(gè)字節(jié),也就是 32BIT,其實(shí)這里放的是真正的C寫的處理函數(shù)的地址,說白了,就是函數(shù)指針 - - 這樣做的話就很靈活了
接著,我們需要安裝IRQ處理句柄,說白了,就是設(shè)置處理函數(shù)的地址,讓PC指針可以正確的跳轉(zhuǎn)。
于是我們?cè)诮又恼业桨惭b句柄的語句
; Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there is not subs pc,lr,#4 at 0x18, 0x1c
str r1,[r0]
說白了就是將 IsrIRQ 的地址填到 HandleIRQ對(duì)應(yīng)的地址里面,前面說了 HandleIRQ 放的是中斷處理的函數(shù)的入口地址,我們繼續(xù)找 IsrIRQ
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
要理解這個(gè)代碼,得先學(xué)學(xué)2440的中斷系統(tǒng)了,INTOFFSET存放的是當(dāng)前中斷的偏移號(hào),根據(jù)偏移就知道當(dāng)前是哪個(gè)中斷源發(fā)生的中斷。
注意了,我們說的是中斷,而不是異常,看看原來的表是啥樣子的
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
.......
可以看到,前面幾個(gè)是異常,從 HandleEINT0 就是 IRQ異常的向量存放的地方了,這樣就可以理解為什么上面 IsrIRQ 里面里面要執(zhí)行那條指令
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
道理很簡(jiǎn)單, HandleEINT0 就是所有IRQ中斷向量表的入口,在這個(gè)地址上面,加上一個(gè)適當(dāng)?shù)钠屏浚琁NTOFFSET ,那么我們知道現(xiàn)在,到底是哪個(gè)IRQ在申請(qǐng)中斷了。
關(guān)鍵詞:
2440中斷機(jī)
相關(guān)推薦
技術(shù)專區(qū)
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機(jī)
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線
- 開關(guān)電源
- 單片機(jī)
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩(wěn)壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機(jī)控制
- 藍(lán)牙
- PLC
- PWM
- 汽車電子
- 轉(zhuǎn)換器
- 電源管理
- 信號(hào)放大器
評(píng)論