Overview
All current Cortex-M processors get out of reset as follows:
- the initial stack pointer value is at address 0 of the vector table;
- the initial program counter value is at address 4 of the vector table. The processor hardware will initialise the stack pointer register and the program counter register using those values.
Astrobe puts the two values at the beginning of the binary file. However, the MCU does not use these values for the stack pointer and the program counter right after reset – it first executes code in the boot rom.
Stepping over the initial steps after reset, the boot rom code will eventually execute our program code uploaded as UF2 file, as created from Astrobe’s .bin
file, and use the aforementioned initial values. This is done differently on the RP2040 and the RP2350.
RP2040
On the RP2040, the boot code loads the first 256 bytes in flash memory from address 010000000H
into SRAM.1 This code’s responsibility is to configure and enable Execute In Place (XIP). It must be prepended to Astrobe program code.2
This prepended code also must, as its last instructions, load the initial stack pointer value and program counter value into their respective registers. The easiest way is to load the program code in Astrobe’s .bin
file at flash address 010000100H
, so that address 010000100H
contains the initial stack pointer value, and address 010000104H
the initial program counter value.
From there on, the initialisation sequence of the Oberon program starts to execute.
RP2350
On the RP2350, the boot code takes care of configuring and enabling Execute In Place (XIP), no need to prepend any initialisation code. However, the RP2350 has a plethora of different possible modes and memory layouts to load and execute code, including code signing and address translation. Therefore, the boot code needs to get the corresponding configuration data, which is provided via meta data blocks in the UF2 file, which must be added to Astrobe’s program code.3
These meta data blocks can be prepended or inserted in different ways. An easy way is to prepend the necessary meta data in the first 256 bytes at 010000000H
, and load the program code in Astrobe’s .bin
file at flash address 010000100H
. Hence, the meta data block in the first 256 bytes must direct the boot code to the same addresses as with the RP2040 for the initial stack pointer value and program counter value at 010000100H
and 010000104H
, respectively.
The boot rom code will load these two values into their respective registers, and from there on, the initialisation sequence of the Oberon program starts to execute.
Business as Usual: Module Initialisations and Program Start
Consequently, the initialisation of your program modules are done, as per Astrobe’s linker, and last but not least your main program module gets control when its body is executed as last step of the initialisation sequence.
The program runs in Secure, privileged thread mode.
If you have the Professional Edition of the Astrobe tools, you can disassemble the program. The value at line 2 gives you the address of the first instruction of your program executed (subtract 1 for bit 0 set for Thumb code). Search for the four least significant hex digits in the listing, and you’ll arrive at bl.w LinkOptions..init
near the end, which is always the first instruction.