ARM(920T)有四種異常(復位、未定義指令、預取指、數據中止)和三個中斷(軟件中斷、IRQ中斷、FIQ中斷)因此有七個向量,向量表如下:
本文引用地址:http://m.butianyuan.cn/article/201611/319024.htm
1.跳轉
Reset
bHandlerReset ;處理器默認運行模式是 中斷向量0x00000000
bHandlerUndef 中斷向量為0x00000004
bHandlerSWI中斷向量為0x00000008
bHandlerPabort中斷向量為0x0000000c
bHandlerDabort中斷向量為0x00000010
b. ;.表示當前地址,表示當前地址死循環(huán) 0x00000014保留
bHandlerIRQ 中斷向量為0x00000018
bHandlerFIQ 中斷向量為0x0000001c
CPU內核默認的中斷向量(VA)如上,如果當前未開啟MMU地址重映射,則PA的中斷向量也為上面所述。
2.第一次映射
LTORG
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
宏定義如下:
MACRO
$HandlerLabelHANDLER$HandleLabel;
$HandlerLabel
subsp,sp,#4;空出一個字
stmfdsp!,{r0};將R0入堆棧,此時的R0存在的數據是前一個模式所遺留的,必須加以保存
ldrr0,=$HandleLabel;RAM中的中斷向量表
ldrr0,[r0] ;取此中斷第一個字里面的內容
strr0,[sp,#4];先將SP指針加4個字節(jié),后把R0存入,不更新sp
ldmfdsp!,{r0,pc};進行跳轉
MEND
如果是IRQ中斷則進入下列子程序進行IRQ子中斷辨別
ldrr0,=HandleIRQ;判斷是哪個IRQ的子程序,建立IRQ中斷在內存指針的重映射
ldrr1,=IRQ_SEV
strr1,[r0]
IRQ_SEV;子中斷判斷并跳轉
subsp,sp,#4
stmfdsp!,{r8-r9}
ldrr9,=INTOFFSET
ldrr9,[r9]
ldrr8,=HandleEINT0
addr8,r8,r9,lsl #2
ldrr8,[r8]
strr8,[sp,#8]
ldmfdsp!,{r8-r9,pc}
內存中定義一個中斷地址表存放中斷服務程序的起始地址(在高級語言中指定)
ALIGN
AREARWDATA,DATA,READWRITE
MAP_ISR_STARTADDRESS
HandleReset# 4 ;#--Field:定義一個結構化內存表中的數據域,該域為4個字節(jié)(32bit)
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;以下是IRQ的子中斷
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7# 4
HandleEINT8_23# 4
HandleRSV6# 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT# 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD # 4
HandleDMA0# 4
HandleDMA1# 4
HandleDMA2# 4
HandleDMA3# 4
HandleMMC# 4
HandleSPI0# 4
HandleUART1# 4
HandleRSV24# 4
HandleUSBD# 4
HandleUSBH# 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
END
3.第二次映射(將中斷服務子程序地址放入內存中的中斷地址表)
#define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0))
#define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4))
#define pISR_SWI (*(unsigned *)(_ISR_STARTADDRESS+0x8))
#define pISR_PABORT (*(unsigned *)(_ISR_STARTADDRESS+0xc))
#define pISR_DABORT (*(unsigned *)(_ISR_STARTADDRESS+0x10))
#define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14))
#define pISR_IRQ (*(unsigned *)(_ISR_STARTADDRESS+0x18))
#define pISR_FIQ (*(unsigned *)(_ISR_STARTADDRESS+0x1c))
#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24))
#define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x28))
#define pISR_EINT3 (*(unsigned *)(_ISR_STARTADDRESS+0x2c))
#define pISR_EINT4_7 (*(unsigned *)(_ISR_STARTADDRESS+0x30))
#define pISR_EINT8_23 (*(unsigned *)(_ISR_STARTADDRESS+0x34))
#define pISR_NOTUSED6 (*(unsigned *)(_ISR_STARTADDRESS+0x38))
#define pISR_BAT_FLT (*(unsigned *)(_ISR_STARTADDRESS+0x3c))
#define pISR_TICK (*(unsigned *)(_ISR_STARTADDRESS+0x40))
#define pISR_WDT (*(unsigned *)(_ISR_STARTADDRESS+0x44))
#define pISR_TIMER0 (*(unsigned *)(_ISR_STARTADDRESS+0x48))
#define pISR_TIMER1 (*(unsigned *)(_ISR_STARTADDRESS+0x4c))
#define pISR_TIMER2 (*(unsigned *)(_ISR_STARTADDRESS+0x50))
#define pISR_TIMER3 (*(unsigned *)(_ISR_STARTADDRESS+0x54))
#define pISR_TIMER4 (*(unsigned *)(_ISR_STARTADDRESS+0x58))
#define pISR_UART2 (*(unsigned *)(_ISR_STARTADDRESS+0x5c))
#define pISR_LCD (*(unsigned *)(_ISR_STARTADDRESS+0x60))
#define pISR_DMA0 (*(unsigned *)(_ISR_STARTADDRESS+0x64))
#define pISR_DMA1 (*(unsigned *)(_ISR_STARTADDRESS+0x68))
#define pISR_DMA2 (*(unsigned *)(_ISR_STARTADDRESS+0x6c))
#define pISR_DMA3 (*(unsigned *)(_ISR_STARTADDRESS+0x70))
#define pISR_SDI (*(unsigned *)(_ISR_STARTADDRESS+0x74))
#define pISR_SPI0 (*(unsigned *)(_ISR_STARTADDRESS+0x78))
#define pISR_UART1 (*(unsigned *)(_ISR_STARTADDRESS+0x7c))
#define pISR_NOTUSED24 (*(unsigned *)(_ISR_STARTADDRESS+0x80))
#define pISR_USBD (*(unsigned *)(_ISR_STARTADDRESS+0x84))
#define pISR_USBH (*(unsigned *)(_ISR_STARTADDRESS+0x88))
#define pISR_IIC (*(unsigned *)(_ISR_STARTADDRESS+0x8c))
#define pISR_UART0 (*(unsigned *)(_ISR_STARTADDRESS+0x90))
#define pISR_SPI1 (*(unsigned *)(_ISR_STARTADDRESS+0x94))
#define pISR_RTC (*(unsigned *)(_ISR_STARTADDRESS+0x98))
#define pISR_ADC (*(unsigned *)(_ISR_STARTADDRESS+0x9c))
pISR_UNDEF = (unsigned)HaltUndef; //將中斷處理程序入口地址放入中斷變量地址所指向的內存空間
pISR_SWI = (unsigned)HaltSwi; //往中斷地址表中填入中斷服務子程序地址
pISR_PABORT = (unsigned)HaltPabort;
pISR_DABORT = (unsigned)HaltDabort;
pISR_EINT1 = (unsigned)Eint1Int;
評論