In this short video, let's understand the booting sequence of ARM Cortex-M processors.
A system reset sets all registers to their reset values, except for the reset flags in
the clock controller register (CSR) and the registers in the backup domain.
A system reset can be generated by hardware or software.
For example, if the NRST pin is pulled low, a system reset takes place.
NRST pin is pulled up internally within the processor chip.
If the reset button is pressed down, NRST pin is pulled low.
When the reset button is released, the NRST pin becomes high again.
A pull-down capacitor is added in parallel with the reset button.
This bypass capacitor is to improve the level of electromagnetic susceptibility (EMS).
Electromagnetic susceptibility of a device is defined as the ability to operate without
fault under electrical disturbances and noise.
In other words, EMS is the level of tolerance to various forms of electromagnetic radiation.
The bypass capacitor can remove high-frequency voltage signal from NRST pin, and thus reduce
the transient circuit demand on the power supply unit.
Let's quickly review the interrupt vector table.
The first word in the memory contains the value to initialize the Main Stack Pointer
(MSP).
The second word in the memory is a pointer to the function reset handler, which is the
starting memory address, or called entry point, of the function reset handler.
Here is the booting process.
When the processor boots, it first reads two pins, including pin boot 0 and pin boot 1.
The processor determines the boot mode based on these two pins.
In the second step, the processor copies the value stored at the memory address 0 to the
main stack pointer (MSP).
Basically, the main stack pointer (MSP) is initialized in this step.
In the third step, the processor copies the value stored at the memory address 4 to the
program counter (PC).
Note that the program counter always holds the memory address of the next instruction
to be executed by the processor.
Therefore, immediately after the processor boots, the processor will start to execute
the function reset handler.
Typically, the reset handler performs some hardware initialization first, such as initialization
of data segment and BSS segment.
Then, the reset handler calls the main() function and transfers the control to the main() function.
Here is a specific example.
Suppose the word stored at the memory address 0 is 20001BB0 in hex, and the word stored
at the memory address 4 is 08000269 in hex.
The second word holds the memory address of the function reset handler.
The memory address of the reset handler function in fact is 08000268 in hex, which is different
from the second word stored in the memory.
The least significant bit of the memory address of the reset handler function is 0. However,
the least significant bit of the second word in the memory is 1.
This is because ARM uses the least significant bit of the program counter to indicate whether
the processor run in the Thumb mode or the ARM mode.
Because ARM Cortex-M processors only support the Thumb mode, the least significant bit
of the program counter should always be 1.
After the processor determines the boot mode by reading pin boot 0 and pin boot 1, the
processor copies the first word to the stack pointer register (SP).
Then, the processor copies the second word to the program counter register (PC).
Most Cortex-M processors support at least three different boot modes.
The processor can boot from the in-chip flash memory, the system memory, or the in-chip
SRAM.
The code stored in the system memory is called bootloader.
The bootloader is usually provided by chip manufacturers.
A bootloader can upgrade the firmware inside the internal flash memory.
All STM32 microprocessors come with a pre-programmed bootloader in a ready-only memory region (ROM).
This ROM region is called system memory.
However, sometimes you want to develop a custom bootloader.
For example, you may want to encrypt the firmware and put it on the internet so that customers
can upgrade the firmware.
In this case, you have to write a custom bootloader to decode the encrypted firmware.
Here is the memory map of ARM Cortex-M processors.
The address range of each memory region is fixed.
Let's take a look at the code region.
The code region ranges from 0 to 1FFFFFFF in hex.
The top area is the ROM region reserved to store bootloaders.
The middle area is the in-chip flash memory.
The bottom area is an area that can be physically mapped to the internal flash, system memory,
and internal SRAM.
The starting address of internal flash memory, the system memory, and internal SRAM is also
fixed.
Specifically, the starting address of internal flash is 08000000 in hex, and the address
of the system memory starts at 1FFF0000 in hex.
Now, let's look at the boot mode.
The boot modes are determined by the voltage applied to pin boot 1 and pin boot 0.
If pin boot 0 is connected to the ground, the processor will boot from the internal
flash memory.
If pin boot 0 is grounded, the processor will physically map the internal flash memory to
the button area.
For example, the memory address 8000000 is physically mapped to the memory address 0.
In other words, the Flash memory contents can be accessed starting from address 0 or
8000000.
As discussed previously, when the processor boots, it always fetches the value of the
stack pointer and program counter from the memory address 0 and 4, respectively.
Because the internal flash memory is physically remapped to the starting address 0, the flash
memory is in fact the boot memory.
When pin boot 1 is low, and pin boot 0 is high, the system memory is physically mapped
to the bottom area.
When the processor fetches the value of the program counter from memory address 4, the
processor in fact fetches the value from the system memory.
As result, the system memory is chosen as the boot memory.
In this boot mode, processor can reprogram the flash memory or perform the device firmware
upgrade.
When both pin boot 1 and pin boot 0 are high, the internal SRAM is physically mapped to
the bottom area.
The memory address 20000000 is physically mapped to the memory address 0.
Therefore, the processor boots from SRAM.
Here, we answer three frequently asked questions.
First, how to set up the boot mode?
The boot mode is determined by the PCB design, not by the processor.
For the STM32L4 discovery kit, the default boot memory is the internal flash because
pin boot 0 is connected to the ground.
Second, how to place code to the boot memory?
When the linker combines object and library files into a single executable, a linker script
provides the linker two critical types of instructions regarding, how data and code
sections are merged, and where each section should be placed in the memory.
Programmers can modify the linker script to place the code in the target boot memory.
Third, how to set values stored at memory address 0 and 4?
The short answer is the startup code.
The startup code, such as the startup assembly file, sets these values.
For example, the STM32 startup assembly file defines the stack size, the stack pointer's
initial value, and the program counter's initial value.
Please visit the book website for more examples and tutorials.
Thank you for watching.
See you in the next video.