新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > ARM(920T)异常和中断映射过程

ARM(920T)异常和中断映射过程

作者:时间:2016-11-20来源:网络收藏
ARM(920T)有四种异常(复位、未定义指令、预取指、数据中止)和三个中断(软件中断、IRQ中断、FIQ中断)

因此有七个向量,向量表如下:

本文引用地址:http://www.eepw.com.cn/article/201611/319024.htm


1.跳转

Reset
bHandlerReset ;处理器默认运行模式是 中断向量0x00000000

bHandlerUndef 中断向量为0x00000004
bHandlerSWI中断向量为0x00000008
bHandlerPabort中断向量为0x0000000c
bHandlerDabort中断向量为0x00000010
b. ;.表示当前地址,表示当前地址死循环 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个字节,后把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个字节(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;



评论


技术专区

关闭