ARM中斷學(xué)習(xí),講的十分到位值得一看._第1頁(yè)
ARM中斷學(xué)習(xí),講的十分到位值得一看._第2頁(yè)
ARM中斷學(xué)習(xí),講的十分到位值得一看._第3頁(yè)
ARM中斷學(xué)習(xí),講的十分到位值得一看._第4頁(yè)
ARM中斷學(xué)習(xí),講的十分到位值得一看._第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余2頁(yè)可下載查看

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、ARM 中斷學(xué)習(xí),講的十分到位。值得一看。中斷向量b HandlerIRQ ;handler for IRQ interrupt很自然,因?yàn)樗械膯纹瑱C(jī)都是那樣,中斷向量一般放在開(kāi)頭,用過(guò)單片機(jī)的人都會(huì)很熟悉,那就不多說(shuō)了。異常服務(wù)程序這里不用中斷( interrupt )而用異常( exception ),畢竟中斷只是異常的一種情況,下面主要分析的是 “中斷異常 ”說(shuō)白了,就是我們平時(shí)單片機(jī)里面用的中斷! !所有由器件引起的中斷, 例如 TIMER 中斷, UART中斷,外部中斷等等,都有一個(gè)統(tǒng)一的入口,那就是中斷異常IRQ !然后從IRQ的服務(wù)函數(shù)里面分辨出,當(dāng)前究竟是什么中斷,再跳轉(zhuǎn)到相

2、應(yīng)的中斷服務(wù)程序。這樣看來(lái), ARM 比單片機(jī)要復(fù)雜一些了,不過(guò)原理是不變的。上面說(shuō)的就是思路,跟著這個(gè)思路來(lái)接著分析。HandlerIRQ 很明顯是一個(gè)標(biāo)號(hào), 我們找到了HandlerIRQ HANDLER HandleIRQ這里是一個(gè)宏定義,我們?cè)僬业竭@個(gè)宏,看他是怎么定義的:MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsub sp,sp,#4;decrement sp(to store jump address)stmfd sp!,r0;PUSH the work register to stack(lr does not pu

3、sh because it return to originaladdress)ldr r0,=$HandleLabel ;load the address of HandleXXX to r0ldr r0,r0 ;load the contents(service routine start address) of HandleXXXstr r0,sp,#4 ;store the contents(ISR) of HandleXXX to stackldmfd sp!,r0,pc ;POP the work register and pc(jump to ISR)MEND用 HandlerI

4、RQ 將這個(gè)宏展開(kāi)之后得到的結(jié)果實(shí)際是這樣的HandlerIRQsub 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 originaladdress)ldr r0,=HandleIRQ ;load the address of HandleXXX to r0ldr r0,r0 ;load the contents(service routine start address) of Hand

5、leXXXstr r0,sp,#4 ;store the contents(ISR) of HandleXXX to stackldmfd sp!,r0,pc ;POP the work register and pc(jump to ISR )至于具體的跳轉(zhuǎn)原理下面再說(shuō),好了,這樣的話就容易看的多了,很明顯,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 ,沒(méi)錯(cuò),我們又找到了一個(gè)標(biāo)號(hào) HandleIRQ ,看來(lái)真正的處理函數(shù)應(yīng)該是這個(gè) Handle

6、IRQ ,繼續(xù)尋找AREA RamData, DATA, READWRITEA ISR STARTADDRESS;_ISR_STARTADDRESS=0x33FF_FF00HandleResetHandleUndefHandleSWIHandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ對(duì)應(yīng)上面第二個(gè)標(biāo)號(hào)最后我們發(fā)現(xiàn)在這里找到了 HandleIRQ , A 其實(shí)就是 MAP ,這段程序的意思是,從 _ISR_STARTADDRESS 開(kāi)始,預(yù)留一個(gè)變量,每個(gè)變量一個(gè)標(biāo)號(hào),預(yù)留的空間為4個(gè)字節(jié),也就是32BIT,其實(shí)這里放的是真正的

7、 C寫的處理函數(shù)的地址,說(shuō)白了,就是函數(shù)指針這樣做的話就很靈活了PC 指針可以正確的跳轉(zhuǎn)。接著,我們需要安裝 IRQ 處理句柄,說(shuō)白了,就是設(shè)置處理函數(shù)的地址,讓 于是我們?cè)诮又恼业桨惭b句柄的語(yǔ)句ldrr0,=HandleIRQ ;This routine is neededldrr1,=IsrIRQ;if there is not ''subs pc,lr,#4'' at 0x18, 0x1cstrr1,r0說(shuō)白了就是將 IsrIRQ 的地址填到 HandleIRQ 對(duì)應(yīng)的地址里面,前面說(shuō)了 HandleIRQ們繼續(xù)找IsrIRQIsrIRQsubsp,sp

8、,#4 ;reserved for PCstmfdsp!,r8-r9ldrr9,=INTOFFSETldrr9,r9ldrr8,=HandleEINT0addr8,r8,r9,lsl #2ldrr8,r8strr8,sp,#8ldmfdsp!,r8-r9,pc要理解這個(gè)代碼,得先學(xué)學(xué) 2440 的中斷系統(tǒng)了, INTOFFSET 存放的是當(dāng)前中斷的偏移號(hào); Setup IRQ handler發(fā)生的中斷。放的是中斷處理的函數(shù)的入口地址,我,根據(jù)偏移就知道當(dāng)前是哪個(gè)中斷源注意了,我們說(shuō)的是中斷,而不是異常,看看原來(lái)的表是啥樣子的A ISR STARTADDRESS;_ISR_STARTADDRES

9、S=0x33FF_FF00HandleReset# 4HandleUndef# 4HandleSWI# 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ# 4HandleFIQ# 4HandleEINT0# 4HandleEINT1# 4HandleEINT2# 4HandleEINT3# 4可以看到, 前面幾個(gè)是異常,HandleEINT0 就是 IRQ 異常的向量存放的地方了, 這樣就可以理解為什么上面 IsrIRQ 里面里面要執(zhí)行那條指令ldr r8,=HandleEINT0add r8,r8,r9,lsl #2道理

10、很簡(jiǎn)單, HandleEINT0就是所有 IRQ 中斷向量表的入口,在這個(gè)地址上面,加上一個(gè)適當(dāng)?shù)钠屏浚琁NTOFFSET ,那么我們知道現(xiàn)在,到底是哪個(gè)IRQ 在申請(qǐng)中斷了。至于具體怎么跳轉(zhuǎn)的?ARM 的體系的話,每個(gè)指針變首先,我們說(shuō)了, HandleEINT0 開(kāi)始的一段內(nèi)存里面,存放的就是中斷服務(wù)函數(shù)的函數(shù)指針, 量就是占 4 個(gè)字節(jié),這里就解釋了,為什么這里為每個(gè)標(biāo)號(hào)分配了 4 個(gè)字節(jié)的空間,里面放的就是函數(shù)指針!下面再看看怎么跳轉(zhuǎn),繼續(xù)看 IsrIRQ 里面就實(shí)現(xiàn)了跳轉(zhuǎn)了strr8,sp,#8R8 里面,然后出棧,彈出給 PC 那么 PC 很自然就ldmfd sp!,r8-r9,

11、pc其實(shí)最核心就是這兩句了,先查找到當(dāng)前中斷服務(wù)程序的地址,將他放到 跳到中斷服務(wù)程序了。 至于這里的堆棧問(wèn)題又是一個(gè)非常棘手的,需要好好的參透 ARM 的中斷架構(gòu), 需要了解的可以自己仔細(xì) 的閱讀 ARM 體系結(jié)構(gòu)與編程里面說(shuō)的很詳細(xì)。我們這里的重點(diǎn)是研究怎么跳轉(zhuǎn)。最后,我們看看在 C 代碼中是怎么安裝終端向量的,例如看 按鍵的外部中斷,是怎么具體設(shè)置的,參看 /src/keyscan.c 里面的 代碼很簡(jiǎn)單,里面只有 3 個(gè)函數(shù)KeyScan_Test 是按鍵測(cè)試的主函數(shù)Key_ISR 是按鍵中斷服務(wù)函數(shù) 在 KeyScan_Test 里面,我們發(fā)現(xiàn)了有這么一句pISR_EINT0 = p

12、ISR_EINT2 = pISR_EINT8_23 = (U32)Key_ISR;可以理解否? Key_ISR 就是上面提到的按鍵中斷服務(wù)函數(shù),函數(shù)的名字,代表的就是函數(shù)的地址!將中斷服務(wù)函數(shù)的地址,注意了,是地址,這是一個(gè)U32 型的變量。送到幾個(gè)變量,我們以pISR_EINT0 作為例子,查看頭文件定義,在 2440addr.h 里面找到/ Interrupt vector#define pISR_EINT0(*(unsigned *)(_ISR_STARTADDRESS+0x20)_ISR_STARTADDRESS 有沒(méi)有似曾相識(shí)的感覺(jué)?沒(méi)錯(cuò),剛才分析的匯編代碼里面就提到了A ISR S

13、TARTADDRESS;_ISR_STARTADDRESS=0x33FF_FF00HandIeReset # 4HandIeUndef # 4對(duì),地址就是這里,然后 _ISR_STARTADDRESS+0x20 就是跳過(guò)前面的異常向量,進(jìn)入IRQ 中斷向量的入口,所以說(shuō)到尾p ISR_EINT0 = (U32)Key_ISR;完成的操作就是,將 Key_ISR 的地址存放到HandleEINT0這個(gè) IRQ 向量表里面!當(dāng)按鍵中斷發(fā)生的時(shí)候,發(fā)生 IRQ 異常中斷當(dāng)前 PC 值-4 保存到LR_IRQ 里面,然后執(zhí)行b HandIerIRQ然后是執(zhí)行HandlerIRQsub sp,sp,#4

14、; 預(yù)留一個(gè)用來(lái)存放 PC 地址stmfd sp!,r0;保存R0,因?yàn)橄旅媸褂昧薼dr r0,=HandleIRQ ;將 HandleIRQ (服務(wù)程序)的地址裝載到R0ldr r0,r0str r0,sp,#4 ; 保存到剛才預(yù)留的地方Idmfd sp !,r0, pc;彈出堆棧,恢復(fù) R0,并且將剛才計(jì)算好的HandleIRQ 地址彈出到PC 堆棧是向下生長(zhǎng)的,所以 SUBSP,SP,#4就相當(dāng)于PUSH XX,但是這個(gè)XX這個(gè)時(shí)候并沒(méi)有用,因?yàn)檫@里用的是強(qiáng)制移動(dòng)SP 指針實(shí)現(xiàn)的。然后得到服務(wù)程序的地址,再將這個(gè)值放回剛才預(yù)留的棧的空位上面, 最后就是 POP 出 R0 恢復(fù),并且將剛才

15、得到的服務(wù)程序的地址送到PC,那么實(shí)現(xiàn)的效果就是跳轉(zhuǎn)到 HandIeIRQ 里面了。接著看剛才是怎么安裝的 HandIeIRQ 的; Setup IRQ handIerIdrIdrr0,=HandIeIRQ ;This routine is neededr1,=IsrIRQ ;if there is not ''subs pc,Ir,#4'' at 0x18, 0x1cstrr1,r0可以看出,這里將 IsrIRQ 的地址的值保存到 HandIeIRQ 中,也就是說(shuō),上面的 IRQ 服務(wù)程序,這個(gè)時(shí)候?qū)嶋H上就是指IsrIRQ ! 所以接著的事情就是轉(zhuǎn)移到 Isr

16、IRQ 中執(zhí)行:IsrIRQsubsp,sp,#4 ; 預(yù)留一個(gè)值來(lái)保存 PCstmfdsp!,r8-r9ldrr9,=INTOFFSET ; 計(jì)算偏移量,下面解釋ldrr9,r9ldrr8,=HandleEINT0addr8,r8,r9,lsl #2ldrr8,r8strr8,sp,#8 ; 因?yàn)楸4媪?2個(gè)寄存器 R8 R9 ,所以 SP 下移了ldmfdsp!,r8-r9,pc ; 恢復(fù)寄存器,彈出到 PC ,同上面的一樣8位怎么保存,操作 SP ,跟最后彈出到 PC 的部分和上面的例子一樣,下面說(shuō)說(shuō)中間的計(jì)算部分計(jì)算偏移量,其實(shí)原理很簡(jiǎn)單,首先 INTOFFSET 保存著當(dāng)前是哪個(gè) I

17、RQ 中斷, 例如 0 代表著 HandleEINT0 , 1 代表 HandleEINT1等等, 這不是亂來(lái), 有一個(gè)表的,這個(gè)是由 S3C2440 的 datasheet 說(shuō)的,自己可以去查看。然后得到 中斷處理函數(shù)的向量表,這個(gè)表的首地址就是 HandleEINT0 ,那么很自然的想到,怎么查表?那還不簡(jiǎn)單?HandleEINT0 + INTOFFSET 不就完了?基地址加偏移量就得到表中某項(xiàng)了,當(dāng)然,因?yàn)檫@里是中斷處理向量每一項(xiàng)占用 4個(gè)字節(jié),所以用 lsl #2 處理一下,左移 2位相當(dāng)于乘以 4 ,偏移量乘以 4,這應(yīng)該很好理解的。我們這個(gè)例子找到的就是 HandleEINT0 ,

18、將里面的值讀出來(lái),里面放的是 HandleEINT0服務(wù)函數(shù)的地址,這個(gè)地址怎么來(lái)的?是在 C 程序里面設(shè)置的。我們看 keyscan.c 程序,找到一個(gè) void KeyScan_Test(void)函數(shù),里面有這么一句:pISR_EINT0 = pISR_EINT2 = pISR_EINT8_23 = (U32)Key_ISR;這里是安裝了 3 個(gè)按鍵中斷服務(wù)程序,我們只關(guān)注 0 號(hào)中斷,也就是pISR_EINT0 = (U32)Key_ISR;這句話什么意思?先看看 pISR_EINT0 的定義,在 2440addr.h 中定義#define pISR_EINT0(*(unsigned *)(_ISR_STARTADDRESS+0x20)看到?jīng)]有? _ISR_STARTADDRESS 不就是剛才說(shuō)的那個(gè)異常向量的入口地址?加上一個(gè)0x20 之后實(shí)際上指向的,就是HandleEINT0 !這么說(shuō)來(lái),上面的意思就是,將 Key_I

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論