Friday, December 19, 2008

Anatomy of STR912 boot sequence in EWARM

Power-on: waits til voltages rise above Low-Voltage Detect, then sets PC to 0x00000000

First instruction jumps to Reset Handler. The jump is usually a LD PC,[PC+xxx] command that loads the PC from a table just past the end of the vector handlers.

Reset Handler is always written in ASM because it needs to do things that are unsafe in C, like initializing flash memory interfaces, RAM interfaces and needs access to the CPSR register, which you don't have from C. This usually sets the flash memory interface, sets up stack space for each of the system modes, then jumps to ?main. In EWARM, the Reset Handler is installed at 0x180, and is given the symbol __iar_program_start. If you do not write your own, EWARM will pick one for you.

?main - This does basically 3 things:
  1. Call __low_level_init(). You can write this in C, as long as you are careful not to use global variables. This is useful for setting the clock speed and other things that don't need to be done in ASM. EWARM has a default dummy __low_level_init().
  2. Call __iar_init_memory. Not something the user should deal with. This is where the C global variables are initialized, and global C++ objects are constructed.
  3. Call main. This is the traditional C entry point.
main - Your plain old C function where the real fun begins.

I've seen several examples (the code from ST) that does the low level init in main() and not earlier. This is not a big deal, but it means that the clock will be running much slower on power-up, so if you are doing a lot of C++ initialization, it will boot slower (perhaps 4x slower if you are using a 25 MHz crystal and can run the PLL at 96 MHz).

No comments: