關於__irq使用,首先看ARM公司的說明:
ARM 編譯器 armcc 支持的函數關鍵字和運算符。
ARM 編譯器支持的關鍵字擴展表:
關鍵字
|
||
---|---|---|
__align
|
__int64
|
__svc
|
__ALIGNOF__
|
__INTADDR__
|
__svc_indirect
|
__asm
|
__irq
|
__svc_indirect_r7
|
__declspec
|
__packed
|
__value_in_regs
|
__forceinline
|
__pure
|
__weak
|
__global_reg
|
__softfp
|
__writeonly
|
__inline
|
__smc
|
|
通過使用 __irq 關鍵字,可以將 C 或 C++ 函數用作中斷例程。
__irq 是一個函數限定符。 它影響函數的類型。
限制:
armcc的編譯器的C對ANSI C的關鍵字做了些擴展。
比如__irq 是用來聲明IRQ和FIQ中斷處理函數用的,可以自動返回原來的現場。__asm用來嵌入彙編代碼等。
__irq爲一個標識,用來表示一個函數是否爲中斷函數。對於不同的編譯器,__irq在函數名中的位置不一樣,例如:
ADS編譯器中 : void __irq IRQ_Eint0(void);
Keil編譯器中 : void IRQ_Eint0(void) __irq;
但是其意義一樣,它所完成的任務是標識該函數爲中斷函數,在編譯器編譯是調用此函數時,先保護函數入口現場,然後執行中斷函數,函數執行完畢,恢復中斷現場,這整個過程不需要用戶重新編寫代碼來完成,由編譯器自動完成。因而這也給不具備中斷嵌套功能的ARM系統帶來了問題,若使用 __irq 時有中斷嵌套產生,這現場保護就會混亂。因此自己編寫中斷入口現場保護代碼,並不使用 __irq 標識符號,就是這個原因。
總結如下:
1、若不想自己編寫中斷入口現場保護代碼,而且使用中無中斷嵌套,在中斷函數中用 __irq 來標識我們的中斷函數,否則出錯;
2、若程序中要使用中斷嵌套,對於無中斷嵌套功能的ARM來說,一定要自己編寫中斷入口現場保護代碼,而且不能用 __irq 標識我們的中斷函數,否則出錯