微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 2440中断解析

2440中断解析

时间:11-21 来源:互联网 点击:
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)

MEN

将sp减少一个字节,使其在堆栈高端留出存储返回地址,因为pc在寄存器组 中的位置大于r0,出栈时装入的是栈的高端的内容

保存r0

装载中断处理函数的指针

装载中断处理函数的地址

将中断处理函数的地址存入刚才预留的位置,r0的上面

出栈后,pc指向的既是中断处理函数的地址

以上是个宏,用于把中断服务程序的首地址装载到pc中,我称它为“加载程序”。

本初始化程序定义了一个数据区(在文件最后),34个字空间,存放相应中断服务程序的首地址。每个字空间都有一个标号,以Handle***命名。

在向量中断模式下使用“加载程序”来执行中断服务程序。

sub sp,sp,#4 是把SP的地址减4字节,而这个地方需要存放跳转地址也就是第5行的HandleSWI指向的内容(ISR),将此内容写入pc,实现跳转

接下来是压栈所需要的寄存器r0,因为接下来需要使用r0所以先压栈r0,这也是为什么刚刚先把SP加四字节的原因,第6句话就是跳转到刚刚第5句所压栈的地址处,也就是HandleSWI指向的内容(ISR)处

下面是每个中断源的“加载程序”

HandlerFIQ HANDLER HandleFIQ

HandlerIRQ HANDLER HandleIRQ

HandlerUndef HANDLER HandleUndef

HandlerSWI HANDLER HandleSWI

HandlerDabort HANDLER HandleDabort

HandlerPabort HANDLER HandlePabort

下面这段程序的首地址将要被放到HandleIRQ中,在非向量中断模式下发生IRQ中断时,执行此程序来判断中断源以执行相应的中断服务程序。

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}

下面就是把IsrIRQ的首地址装载到HandleIRQ的代码

; 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]

ALIGN

AREA RamData, DATA, READWRITE

异常向量表

^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00

HandleReset # 4

HandleUndef # 4

HandleSWI # 4

HandlePabort # 4

HandleDabort # 4

HandleReserved # 4

HandleIRQ # 4

HandleFIQ # 4

中断向量表

;Do not use the label IntVectorTable,

;The value of IntVectorTable is different with the address you think it may be.

;IntVectorTable

;@0x33FF_FF20

HandleEINT0 # 4

HandleEINT1 # 4

HandleEINT2 # 4

HandleEINT3 # 4

HandleEINT4_7 # 4

HandleEINT8_23 # 4

HandleCAM # 4 ; Added for 2440.

HandleBATFLT # 4

HandleTICK # 4

HandleWDT # 4

HandleTIMER0 # 4

HandleTIMER1 # 4

HandleTIMER2 # 4

HandleTIMER3 # 4

HandleTIMER4 # 4

HandleUART2 # 4

;@0x33FF_FF60

HandleLCD # 4

HandleDMA0 # 4

HandleDMA1 # 4

HandleDMA2 # 4

HandleDMA3 # 4

HandleMMC # 4

HandleSPI0 # 4

HandleUART1 # 4

HandleNFCON # 4 ; Added for 2440.

HandleUSBD # 4

HandleUSBH # 4

HandleIIC # 4

HandleUART0 # 4

HandleSPI1 # 4

HandleRTC # 4

HandleADC # 4

;@0x33FF_FFA0

END

本程序的初始化中断部分实现的很巧妙,基于34个字单元将向量中断和非向量中断的实现结合在一起。

向量中断直接使用“加载程序”,把相应的中断服务程序首地址(存放于Handle***)加载到PC。

非向量中断通过执行IsrIRQ判断中断源,并同时计算出相应Handle***的地址,再将此地址的内容加载到PC。

我有两个问题:

问题一,非向量中断有个缺点,它始终从优先级最低的中断源开始识别,且是通过过分析I_ISPR寄存器的每一位来识别,但是尽管有多个中断同时发生,I_ISPR只有一位置1。如此一来,频繁发生低优先级中断是否会屏蔽其他中断?

我有过一次试验,设置两个中断INT_TICK和INT_TIMER5,两个中断服务程序都使用串口打印一串字符。当TIMER5以频率为1KHz(每毫秒一次)中断时,TICK中断服务程序毫无反应。

问题二,本代码

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top