在ARM程序的开发进程中,对中止的处理是很遍及的、也是恰当重要的。Realview MDK运用的RVCT编译器供给了__irq关键字,用此关键字润饰的函数被作为中止出来函数编译,即在编译的进程中,编译器会主动增加中止处理进程中现场维护和康复的代码,减小程序的开发难度,加速软件的开发进程。
在了解__irq关键字的效果之前,先看一下ARM核对反常的处理进程。当发生反常时, ARM核复制CPSR寄存器的内容SPSR_
? 从SWI和Undef反常回来时运用:
movs pc, LR;
? 从FIQ、IRQ和预取停止回来时运用:
SUBS PC, LR,#4;
? 从数据反常回来时运用:
SUBS PC, LR,#8
在运用上述指令反常回来时,假如LR之前被压栈的话运用LDM “∧”, 例如:
LDMFD SP!, {PC}∧
了解了ARM反常处理的进程今后,Realview MDK中__irq关键字的效果就简单了解了。下面的函数为一个中止处理函数,其前面加了__irq关键字。
__irq void pwm0_irq_handler(void)
{
//Deassert PWM0 interrupt signal
unsigned int i=AT91F_PWMC_GetInterruptStatus(AT91C_BASE_PWMC);
// Clear the LEDs. On the Board we must apply a “1” to turn off LEDs
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, led_mask[0]);
AT91F_PWMC_StopChannel(AT91C_BASE_PWMC,AT91C_PWMC_CHID1);
AT91F_AIC_ClearIt(AT91C_BASE_AIC,AT91C_ID_PWMC);
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}
当编译器器编译这个函数时,除了保存ATPCS规矩规则的寄存器以外,还保存了CPSR及PC的值。在函数的回来时,还主动增加了SUBS PC, LR, #4和从SPSR寄存器康复CPSR寄存器值的指令。用这种方法处理今后,中止处理函数能够和一般函数相同的运用。
留意:中止处理都是在ARM形式下进行的,当源程序欲编译成Thumb指令时,这时,用__irq关键字润饰的函数依然会被编译成ARM指令。假如源程序编译成在CORTEX M3上运转的指令时,关键字__irq对函数的编译没有任何影响,即编译器不会主动保存CPSR及PC的值,也不会增加SUBS PC, LR, #4和从SPSR寄存器康复CPSR寄存器值的指令,由于CORTEX M3处理器硬件会主动处理这些问题,无需软件开发人员关怀。