ARM核結(jié)構(gòu)采用了一個簡單的雙中斷機制,處理器內(nèi)核有兩個中斷接口IRQ(標(biāo)準(zhǔn)中斷接口)和FIQ(快速中斷接口),而AT91SAM9261片內(nèi)的先進中斷控制器(AIC)利用這兩個接口將外設(shè)的中斷請求有序的傳遞到內(nèi)核。如下圖所示:
AT91SAM9261的先進中斷控制器(AIC)是一個8優(yōu)先級,可獨立屏蔽中斷的向量中斷控制器,可處理32個中斷源。它的設(shè)計思想是從本質(zhì)上減少在處理內(nèi)部和外部中斷時的軟件和實時系統(tǒng)開銷。AIC驅(qū)動ARM內(nèi)核的nIRQ和nFIQ,它的輸入來自內(nèi)部外設(shè)中斷或產(chǎn)品引腳的外部中斷。
AIC的8優(yōu)先級控制器允許用戶對每個中斷源定義優(yōu)先級。即使一個低優(yōu)先級中斷正在被處理,也允許高優(yōu)先級的中斷被服務(wù)。
內(nèi)部中斷源可被編程為電平有效或者邊沿觸發(fā),外部中斷源可被編程為上升沿或下降沿觸發(fā)或者高電平或低電平有效。
快速強制特性可重定向任何內(nèi)部或外部中斷源為一個快速中斷而不是一個普通中斷。
AIC的詳細方塊圖如下所示:
二、AIC的向量中斷機制
AIC 采用“向量中斷”的中斷跳轉(zhuǎn)機制,這種機制與三星的S3C2410芯片的中斷控制器有很大不同。2410在有中斷觸發(fā)之后,首先會進入異常向量表,然后跳轉(zhuǎn)到IRQ或FIQ服務(wù)程序,這段代碼負責(zé)解析具體是哪一個中斷源產(chǎn)生了中斷,然后才跳轉(zhuǎn)到具體的處理函數(shù)去執(zhí)行。而向量中斷的中斷跳轉(zhuǎn)機制則不需要軟件來識別中斷源,也就是不需要IRQ或FIQ服務(wù)程序,而完全由硬件自動跳轉(zhuǎn)到對應(yīng)的中斷地址,相當(dāng)于硬件幫助我們完成了一些必要的處理,減小了中斷響應(yīng)延時。
也就是說,AIC對于各個中斷源的管理是采用硬件和軟件兩個方面的分發(fā)處理來完成的。首先AIC為每一個中斷源向量寄存器(AIC_SVR0~ AIC_SVR31),在配置使能相應(yīng)外設(shè)時用戶將設(shè)備的中斷處理函數(shù)地址寫入對應(yīng)的中斷源向量寄存器,而當(dāng)中斷請求發(fā)生時AIC將對應(yīng)的源向量寄存器中的地址復(fù)制到中斷向量寄存器(AIC_IVR)并向內(nèi)核發(fā)出IRQ請求,以上都是硬件實現(xiàn)的中斷分發(fā)過程;在軟件層面也必須做相應(yīng)的處理才能完成IRQ的分發(fā)處理,對于ARM內(nèi)核來講,IRQ只是一個中斷向量,當(dāng)IRQ中斷請求時內(nèi)核會跳到其在異常向量表中所處的位置去處理請求,ARM的啟動代碼必須在這個IRQ中斷處理程序中分發(fā)處理才能分辨不同設(shè)備的中斷請求,但有了上面的硬件的預(yù)處理過程,軟件分發(fā)變得十分簡單,一條語句就夠了:即將AIC中斷向量寄存器(AIC_IVR)里的值賦給PC就可以了。下面是AT91SAM9261的啟動代碼中定義的異常向量表:
Vectors LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,Dabt_Addr
; Reserved vector is used as size information for 2-nd level
; bootloader to use when copying program code to External SDRAM
IF :DEF:SIZE_INFO
DCD ||Image$$ER_ROM1$$RO$$Length||+\
||Image$$RW_RAM1$$RW$$Length||
ELSE
NOP
ENDIF
LDR PC,[PC,#-0xF20] ; Vector From AIC_IVR
LDR PC,[PC,#-0xF20] ; Vector From AIC_FVR
可以看到:IRQ對應(yīng)異常處理指令是LDR PC,[PC,#-0xF20],當(dāng)執(zhí)行這條指令時,由ARM流水線結(jié)構(gòu),此時的PC = 0x18 + 2*4 = 0x20,因此執(zhí)行之后PC被賦予地址:0x20 – 0xF20 = 0xFFFFF100里的內(nèi)容,即IRQ向量寄存器AIC_IVR的內(nèi)容,程序跳轉(zhuǎn)到相應(yīng)的中斷例程中。
對比一下S3C2410的啟動代碼:
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP ; Reserved Vector
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
IF IntVT_SETUP <> 0
IRQ_Handler B IRQ_Entry
ENDIF
FIQ_Handler B FIQ_Handler
在異常向量表中,IRQ對應(yīng)的處理指令是:LDR PC, IRQ_Addr,最終PC會跳到IRQ_Entry去執(zhí)行。IRQ_Entry里面做了相應(yīng)處理,即找到中斷源,跳轉(zhuǎn)到中斷向量表的合適位置去執(zhí)行具體的中斷處理程序(當(dāng)然之前要定義中斷向量入口表)。如下所示:
;Interrupt Vector Table Address
HandleEINT0 EQU IntVTAddress
HandleEINT1 EQU IntVTAddress +4
HandleEINT2 EQU IntVTAddress +4*2
HandleEINT3 EQU IntVTAddress +4*3
HandleEINT4_7 EQU IntVTAddress +4*4
HandleEINT8_23 EQU IntVTAddress +4*5
HandleReserved EQU IntVTAddress +4*6
HandleBATFLT EQU IntVTAddress +4*7
HandleTICK EQU IntVTAddress +4*8
HandleWDT EQU IntVTAddress +4*9
HandleTIMER0 EQU IntVTAddress +4*10
HandleTIMER1 EQU IntVTAddress +4*11
HandleTIMER2 EQU IntVTAddress +4*12
HandleTIMER3 EQU IntVTAddress +4*13
HandleTIMER4 EQU IntVTAddress +4*14
HandleUART2 EQU IntVTAddress +4*15
HandleLCD EQU IntVTAddress +4*16
HandleDMA0 EQU IntVTAddress +4*17
HandleDMA1 EQU IntVTAddress +4*18
HandleDMA2 EQU IntVTAddress +4*19
HandleDMA3 EQU IntVTAddress +4*20
HandleMMC EQU IntVTAddress +4*21
HandleSPI0 EQU IntVTAddress +4*22
HandleUART1 EQU IntVTAddress +4*23
;HandleReserved EQU IntVTAddress +4*24
HandleUSBD EQU IntVTAddress +4*25
HandleUSBH EQU IntVTAddress +4*26
HandleIIC EQU IntVTAddress +4*27
HandleUART0 EQU IntVTAddress +4*28
HandleSPI1 EQU IntVTAddress +4*39
HandleRTC EQU IntVTAddress +4*30
HandleADC EQU IntVTAddress +4*31
IRQ_Entry
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}
ENDIF
AT91SAM9261和S3C2410兩款芯片對中斷處理的過程可以用下圖來說明,我們可以更加清晰的看到兩種中斷處理過程的異同:
三、AT91SAM9261按鍵中斷示例
下面以按鍵中斷為例,具體解析AT91SAM9261的中斷處理。
1、首先查看硬件原理圖,確定按鍵和CPU的連接方式:
硬件原理圖顯示:按鍵SW7和PB27連接,PB27是由PIO(Perihepheral Input/Output)Controller管理的。我們由芯片手冊可知:每個PIO Controller管理的引腳可以配置為通用I/O口線,或復(fù)用為外設(shè)I/O。中斷信號FIQ和IRQ0~IRQn通過PIO控制器多路復(fù)用。然而,由于PIO控制器對于輸入無效并且中斷口線僅被用為輸入,所以沒有必要分配I/O口線給中斷功能。因此我們需要將PB27配置為輸入模式
2、使能PIO控制器的時鐘
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOB ) ;
只有PIO控制器時鐘被使能才能產(chǎn)生PIO控制器中斷。
3、配置PB27為輸入模式
AT91F_PIO_CfgInput( AT91C_BASE_PIOB, SW_MASK ) ;
這里的SW_MASK = 1<<27,因為我們配置的是PB27,所以沒有必要改變其他引腳的屬性。
4、使能PB27的上拉電阻
AT91F_PIO_CfgPullup( AT91C_BASE_PIOA, SW_MASK ) ;
使能相應(yīng)管腳的上拉電阻,提高輸出電平,從而提高芯片輸入信號的噪聲容限增強抗干擾能力。
5、暫時禁止PIO中斷
AT91F_AIC_DisableIt(AT91C_BASE_AIC ,AT91C_ID_PIOA);
暫時禁止PIO中斷,等到配置結(jié)束之后再使能中斷。
6、配置AIC相應(yīng)寄存器
AT91C_BASE_AIC->AIC_IDCR = 0x1 << AT91C_ID_PIOB;
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOB] = (unsigned int) SW_Handler;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOB]= AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE ;
AT91C_BASE_AIC->AIC_ICCR = 0x1 << AT91C_ID_PIOB;
通過寫中斷源向量寄存器AIC_SV
R[AT91C_ID_PIOB]注冊中斷處理函數(shù)SW_Handler。通過寫源模式寄存器AIC_SMR[AT91C_ID_PIOB]來設(shè)定中斷觸發(fā)方式和優(yōu)先級。
7、使能PIO中斷
AT91C_BASE_AIC->AIC_IECR = (1<
AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA, SW_MASK);
重新使能PIO中斷,這里需要設(shè)置兩個地方,一個是AIC的中斷使能命令寄存器,另一個還要使能PIO相應(yīng)的寄存器來使能中斷。
8、填寫中斷服務(wù)程序:SW_Handler
__irq void SW_Handler (void)
{
AT91F_DBGU_Printk("SW1 Was Pressed...\r\n");
*AT91C_AIC_EOICR = AT91C_BASE_PIOB->PIO_ISR;
}
注意在中斷服務(wù)程序的最后,一定要向AIC的中斷結(jié)束命令寄存器里寫相應(yīng)中斷狀態(tài)的值,以告訴AIC當(dāng)前中斷以完成,否則CPU不會再一次相應(yīng)中斷。
到此為止,一個按鍵中斷軟件部分的編寫就結(jié)束了。寫這種代碼主要是要弄清楚中斷處理的流程以及各個寄存器的作用,這樣寫起來就比較容易了。
評論
查看更多