Search code examples
armembeddedstm32resetbootloader

Where to find the intended boot sequence of an MCU


I have worked with STM, NXP and Atmel MCUs, but all the time during board bring up, we use the vendor provided startup script to bring up the hardware. I know we do that because we do not want to be rewriting the linker script and startup sequence from scratch, which is hardly productive. But from a learner's perspective if given an MCU how do we know in which sequence it needs to be booted? I was thinking maybe there should be some place where the sequence is documented but we rarely look at it.

Is there some place the vendor will document the startup sequence (steps to execute in ResetHandler() function) for a specific chip or a family of chips? I tried looking at the programmer's model in Cortex-M4 and ARMv7 technical reference manuals. But I was not able to find it. The chip I am currently using to learn in STM32G431RBT6


Solution

  • Chip vendors don't typically dictate such things; it is application specific - i.e. up to you how you use the chip. Often it is "documented" by example/reference code rather then explicitly described.

    That said there are some general principles:

    There will be hardware initialisation which will be part specific, and for that the MCU reference manual and/or data sheet would be your source. For example for your STM32 the PLL will normally be configured if you want to run the MCU at more than the default internal RC oscillator's 16MHz, and before that you would typically need to configure memory timing and wait-states. If you are using external memory, you might also configure the bus and memory controller at that point - necessary if the external memory is in the link map so that code and data may be located there by your toolchain's linker.

    Following hardware initialisation, the software run-time environment must be established. A C runtime will typically establish a stack, initialise static data, and initialise the library (for heap etc.). A C++ run-time will additionally call constructors for objects in global scope. Often this will be compiler/toolchain supplied code that is invoked before main() - for example you will typically see start-up code calling perhaps __main (ARMCC) or _start (GCC) - neither are a direct call to main() but rather the C/C++ runtime initialisation (which ultimately calls main() where you might do more application specific initialisation and/or start an RTOS kernel for example.

    For ARM Cortex-M for which there is a framework called CMSIS, the hardware initialisation is placed in a user supplied function SystemInit(). If you have a vendor supplied SystemInit() you are expected there to modify it to suit your application. Or you can implement your own from scratch. SystemInit() will be invoked from Reset_Handler (usually implemented as assembler) which is the reset vector handler.

    See for example: https://developer.arm.com/documentation/ka001193 which describes the typical start-up of a Cortex-M7 device following CMSIS conventions.