打印

ColdFire与ARM处理器中断响应分析

[复制链接]
3085|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
阿南|  楼主 | 2007-10-22 20:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
**标题:
ColdFire与ARM处理器中断响应分析

**简介:
对于任何一种处理器,中断都是非常重要的,它的响应速度,直接关系着程序的性能。另外用户程序出现跑飞形象,也大多都是由中断引起,在中断的处理过程当中执行非法指针操作引起。因此分析、熟悉处理器的中断响应执行过程,无论对其性能的了解,还是解决由中断引起的程序跑飞的调试,都是必须的。

正文:
一.    ARM处理器中断分析(以S3C2410的IRQ及timer0中断为例)
1.    中断初始化过程
1> 中断向量表起始地址定义
C文件中的宏定义:
#define _ISR_STARTADDRESS       0x33ffff00
汇编文件中的定义:
    _ISR_STARTADDRESS    EQU 0x33ffff00
2> IRQ中断及具体外设中断源地址定义
C文件中的宏定义:
    。。。。。。
#define pISR_IRQ       (*(unsigned *)(_ISR_STARTADDRESS+0x18))
。。。。。。
#define pISR_TIMER0   (*(unsigned *)(_ISR_STARTADDRESS+0x48))
。。。。。。。
汇编文件中的定义:
    。。。。。。
pISR_IRQ       EQU  (_ISR_STARTADDRESS+0x18)
。。。。。。
pISR_TIMER0   EQU  (_ISR_STARTADDRESS+0x48)
。。。。。。
        AREA RamData, DATA, READWRITE

        ^   _ISR_STARTADDRESS
。。。。。。
HandleIRQ       #   4               //注:位于_ISR_STARTADDRESS+0x18处
。。。。。。
HandleTIMER0     #   4
。。。。。。
        END
3> 相关的子程序段
内核中断都要用到的宏定义:
        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't 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)
    MEND

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}
4> 系统启动时的初始化过程
ResetHandler
    //系统复位后,从这开始执行
    。。。。。。
    ldr    r0,=HandleIRQ       
    ldr    r1,=IsrIRQ //将IRQ中断处理程序IsrIRQ入口地址保存在向量表HandleIRQ位置
    str    r1,[r0]
    。。。。。。
pISR_TIMER0 = (int)Timer0Done;//该语句为C语言,在应用程序中初始化
//将定时器0的中断处理程序地址保存在向量表该中断源位置
2.    中断响应过程
当产生timer0中断请求时,PC指向IRQ中断入口(地址:0x00000018)处,执行跳转指令(b    HandlerIRQ)到宏定义(HandlerIRQ      HANDLER HandleIRQ)处,即相当于如下程序:
HandlerLabel
    sub        sp,sp,#4       
    stmfd    sp!,{r0}       
    ldr        r0,=HandleIRQ
    ldr        r0,[r0]         
    str        r0,[sp,#4]      
    ldmfd    sp!,{r0,pc}
执行这段程序后,PC将指向存放在中断向量表HandleIRQ处的IsrIRQ程序,如下:
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} 
上述的INTOFFSET为中断偏移寄存器,该值保存了请求挂起的中断源的偏移值(每个中断源都对应一个唯一值,参考S3C2410 datasheet的P14-16页表格,如timer0的偏移值为10),指示是哪个中断源产生请求处理,例如timer0产生中断请求,则该值就为10。由于EINT0的偏移值为0,而中断向量表是根据偏移值排列的,故上述的程序将向量表的HandlerEINT0再加上INTOFFSET值,查表得到pISR_TIMER0位置处的timer0中断处理程序Timer0Done的地址,所以执行这段程序后PC指向了Timer0Done,也就是用户最终的中断处理程序。
二.    ColdFire中断分析(以MCF52235的EPORT0的IRQ4为例)
1.    中断向量表初始化
1>    中断函数定义
__interrupt__ void
irq4_handler(void)
{
。。。。。。
}
2>    向量表定义
/*
 * Exception Vector Table
 */
VECTOR_TABLE:
_VECTOR_TABLE:
INITSP:        .long    ___SP_INIT                /* Initial SP            */
INITPC:        .long    0x00000400                /* Initial PC            */
vector02:    .long    _asm_exception_handler    /* Access Error            */
。。。。。。
vector44:    .long    _irq4_handler       //64+4(IRQ4的中断源号)=0x44
。。。。。。
vectorFF:    .long    _irq_handler
3>    系统启动时的对中断向量表的初始化
    /* Copy the vector table to RAM */
    if (__VECTOR_RAM != VECTOR_TABLE)
    {
        for (n = 0; n < 256; n++)
            __VECTOR_RAM[n] = VECTOR_TABLE[n];
    }
    mcf5xxx_wr_vbr((uint32)__VECTOR_RAM);//将向量表地址写入内核向量寄存器

2.    中断响应过程
当IRQ4中断源产生中断时,PC将直接指向中断向量表的IRQ4处的服务程序地址:irq_handler。注:由于接触ColdFire也不是很久,所以不一定正确,还请熟悉ColdFire的朋友指证。不过我在单步仿真的情况下,触发IRQ4时,观察PC值确时是如此的。
三.    总结
由上述分析,ColdFire处理器很像8位单片机(如:51系列等)那样,一个中断源占用一个中断入口,只是该中断入口是跟随内核的VBR值的不同,而可以不同。当产生某个中断源请求时,PC直接指向该中断源的处理程序。相比之下,ARM的中断响应处理要复杂些,无论是哪个中断源请求,都必须先进入IRQ(假设中断源被设成IRQ模式)的中断入口,再根据具体中断源的偏移寄存器INTOFFSET值,找到最终中断源的处理程序。

相关帖子

沙发
阿南|  楼主 | 2007-10-22 20:36 | 只看该作者

有没有兄弟要一起学MOTO单片机的?

欢迎访问:

使用特权

评论回复
板凳
LPcfANS| | 2007-10-24 10:55 | 只看该作者

明年开始....

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5786

主题

10221

帖子

463

粉丝