真的是醉了,查來查去原來是NXP公司給的中斷服務函數框架的問題。
具體來說,我是參考了MCB2300的代碼,里面的中斷服務函數框架如下所示:
void Timer0Handler (void) __irq
{
T0IR = 1; /* clear interrupt flag */
IENABLE; /* handles nested interrupt */
timer0_counter++;
IDISABLE;
VICVectAddr = 0; /* Acknowledge Interrupt */
}
問題就是出在IENABLE和IDISABLE這兩個宏定義里,其在irq.h中的宏定義如下
static DWORD sysreg; /* used as LR register */
#define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode }
#define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg }
意思是對程序狀態寄存器CPSR和SPSR進行操作使其進入系統模式或IRQ模式,乍一看到沒什么問題,可是移植進工程里就出數據中止異常的問題。
下午測試的時候我把定時器中斷和串口中斷中的IENABLE和IDISABLE語句全部注釋掉再進行多次測試,都沒有什么問題。
從官方框架的注釋上來看這些宏定義是用于解決中斷嵌套的,也就是說像我這個工程中有兩個中斷必然會涉及到嵌套,不過遺憾的是ARM7貌似不太推薦中斷嵌套,周立功的《ARM嵌入式系統基礎教程》中也提到對于ARM7的中斷嵌套配置和操作較為復雜,不推薦使用。其次從代碼上來看,估計是每一次進入中斷都要對程序狀態寄存器進行操作,而頻繁的內核模式切換以及程序狀態寄存器的強制操作(因為一般這一類最底層的寄存器都是不對用戶開放的)導致了數據中止異常。
當然上述只是我的推測而已,不知道是否正確,還請大牛批評指正! |