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
Actually, this is even more interesting: gcc.gnu.org/.../show_bug.cgi