Lately, I’ve been cleaning up some some C code that runs on an ARM7 controller. In some situations (upgrade, fatal error, etc…) the program will perform a reset. Presently it just jumps to 0 and assumes that the start-up code will reinitialize everything correctly. It got me to thinking about what would be the best procedure a la “Leave No Trace” for an ARM reset. Here is my first crack at it:
void Reset(void)
{
/* Disable interrupts */
__disable_interrupts();
/* Reset peripherals, externals and processor */
AT91C_BASE_RSTC->RSTC_RCR = AT91C_RSTC_KEY | AT91C_RSTC_PERRST | AT91C_RSTC_EXTRST| AT91C_RSTC_PROCRST;
while(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_SRCMP);
/* Jump to the reset vector */
(*(void(*)())0)();
}
This code assumes the IAR ARM compiler and the At91Lib. Anything I haven’t considered?
That should do the trick. I use a similar function with an Atmel SAM3U. I never bothered to poll the status register, but that’s a good idea and I’m going to go add that right now!
However, you should never get to the reset vector line since the processor will have already reset. IAR has an
__noreturnattribute for use in these cases to allow further compiler optimization. I also load my reset function into ram (see__ramfunc) since I use at the end of firmware updates where the microcontroller can’t run from flash.Also, you shouldn’t need AT91C_RSTC_EXTRST flag unless you are controlling the reset of external devices with that line.