Yesterday I've opened a thread about a system crash after the execution of an IRQ routine. After many tests I've isolated the problem and symplified the context in which it happens.
Now the problem I see is the following.
I've only an IRQ routine linked to CPU timer 0. It should be invoked every 1 ms. However after the first call the CPU switches to DATA ABORT mode.
I configure LPC2378 (rev. B) with 72 MHz clock and MAM fully enabled (the problem is present olaso with MAM partially enabled). The source code is the following
/************************************************* ** INITIALISING FUNCTION **************************************************/ void ini_base_timer(void){ PCONP |= (1 << 1); /* power up timer 0 */ T0TCR = 0; /* disable timer 0 */ PCLKSEL0 |= 0x00000004; /* timer 0 clock = PCLOCK */ T0IR = 0x11; /* reset irq flag */ T0CTCR = 0; T0PR = 8; /* prescaler */ T0MR0 = 7999; /* match register 0 */ /* configuration vectored interrupt */ VICIntEnClr |= (1 << 4); /* irq disabling */ VICIntSelect &= ~(1 << 4);/* IRQ interrupt */ VICVectPriority4 = 8; /* priority */ VICVectAddr4 = (UINT32)&irq_base_timer; /* ISR */ VICIntEnable |= (1 << 4);/* irq enabling*/ T0MCR |= 0x03; /* irq enabling and TC reset on match register 0 value */ T0TCR = 0x01; /* start timer */ } /* end ini_base_timer */ /************************************************* ** IRQ FUNCTION (ISR) ** global variables: ** long sd[32]; // global array ** unsigned char buffer_rx_fw[512]; // global array **************************************************/ void __IRQ__ irq_base_timer(void){ UINT32 cont; FIO4SET = 0x01; /* set GPOUTPUT 4.0 */ T0IR = 1; /* irq flag reset */ for(cont = 0; cont < 2; cont++){ if(sd[31] == cont){ sd[30]++; if(sd[30] == buffer_rx_fw[cont]) sd[28]++; } /* end if */ } /* end for */ FIO4CLR = 0x01; /* clear GPOUTPUT 4.0 */ VICVectAddr = 0; /* dummy write */ } /* end irq_base_timer */
In this condition the problem is deterministic in the sense that every time after the first execution of irq function, CPU switches to DATA ABORT mode (the system crashes!). If I execute code step-by-step in assembly mode I see that when micro exits from irq function the LR register contains the address of an instruction that causes DATA ABORT exception. I don't know how a simple IRQ routine can generate such terrible problem!
I'm using GCC compiler (ver. 4.0.3) with optimization level 1. If I put optimization level to 0 (zero) the system doesn't crash, however the assembly code produced is so redundant to degradate system performance too much!
Have you any suggestions?
Thank you,
Demis