Realview MDK中編譯器對中斷處理的過程詳解
在理解__irq關(guān)鍵字的作用之前,先看一下ARM核對異常的處理過程。當(dāng)產(chǎn)生異常時, ARM核拷貝CPSR寄存器的內(nèi)容SPSR_
? 從SWI和Undef異常返回時使用:
movs pc, LR;
? 從FIQ、IRQ和預(yù)取終止返回時使用:
SUBS PC, LR,#4;
? 從數(shù)據(jù)異常返回時使用:
SUBS PC, LR,#8
在使用上述指令異常返回時,如果LR之前被壓棧的話使用LDM “∧”, 例如:
LDMFD SP!, {PC}∧
理解了ARM異常處理的過程以后,Realview MDK中__irq關(guān)鍵字的作用就容易理解了。下面的函數(shù)為一個中斷處理函數(shù),其前面加了__irq關(guān)鍵字。
__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);
}
當(dāng)編譯器器編譯這個函數(shù)時,除了保存ATPCS規(guī)則規(guī)定的寄存器以外,還保存了CPSR及PC的值。在函數(shù)的返回時,還自動添加了SUBS PC, LR, #4和從SPSR寄存器恢復(fù)CPSR寄存器值的指令。用這種方式處理以后,中斷處理函數(shù)可以和普通函數(shù)一樣的使用。
注意:中斷處理都是在ARM模式下進(jìn)行的,當(dāng)源程序欲編譯成Thumb指令時,這時,用__irq關(guān)鍵字修飾的函數(shù)仍然會被編譯成ARM指令。如果源程序編譯成在CORTEX M3上運(yùn)行的指令時,關(guān)鍵字__irq對函數(shù)的編譯沒有任何影響,即編譯器不會自動保存CPSR及PC的值,也不會添加SUBS PC, LR, #4和從SPSR寄存器恢復(fù)CPSR寄存器值的指令,因為CORTEX M3處理器硬件會自動處理這些問題,無需軟件開發(fā)人員關(guān)心。
評論