The first instruction executed by an ARM Cortex-M0 processor after reset is located at address 0x00000000. This initial instruction is responsible for setting up the stack pointer and branching to the reset handler code provided by the user application.
ARM Cortex-M0 Reset Behavior
When an ARM Cortex-M0 chip initially powers on or resets, it will begin executing instructions starting from address 0x00000000 in code memory. The processor resets with the following state:
- The program counter (PC) is set to 0x00000000
- The link register (LR) is undefined
- The processor mode is Thread mode
- The stack pointer (SP) is undefined
- All general purpose registers R0-R12 are undefined
- The priority mask register is set to 0xFF
- All interrupts are disabled
Since the stack pointer is undefined, the very first thing the processor must do is initialize it so operations like pushing and popping can work properly. The code located at address 0x00000000 is responsible for setting up the initial stack pointer.
Initial Stack Pointer Setup
Here is the typical assembly code found at address 0x00000000 for Cortex-M0: stacktop: .word 0x20001000 .word reset_handler .word loop
This does two main things:
- Sets up the stack pointer to point to a defined location in RAM (stacktop)
- Branches to the user reset handler code (reset_handler)
Specifically, the first instruction loads the stack pointer (SP) with the value 0x20001000. This points SP to a location in RAM for use as the stack space. The value 0x20001000 is just an example – the actual stack location is application specific.
The second instruction is a branch to the reset handler code. The processor executes these two instructions sequentially before passing control to the user application at the reset_handler label.
Application Reset Handler
The application reset handler code will be located at the reset_handler label specified in the second instruction. This code is responsible for any chip initialization or setup required by the application. Typical tasks done in the reset handler include:
- Copy initialized data from flash to RAM
- Initialize chip peripherals
- Set up the system tick for timekeeping
- Initialize operating system components
- Enable interrupts
- Branch to main application code
Here is an example reset handler: reset_handler: // Copy data from flash to RAM // Initialize chip peripherals // Set up systick timer // Initialize operating system // Enable interrupts // Call system initialization function // Branch to main program loop: b loop // infinite loop
After reset handler initialization is complete, it will branch to the main application code. An infinite loop is placed at the end as a trap if main ever returns.
C Code Initialization
For C programs, the reset handler is typically implemented in assembly and provided as part of the chip’s startup code. It will perform the basic stack pointer initialization shown earlier. The user can then provide a C function named main() that will be called after the low-level reset initialization is complete.
Here is an example startup sequence in C: // Assembly startup code .stacktop: .word 0x20001000 .word reset_handler .word loop … reset_handler: // Set up stack pointer // Branch to SystemInit() loop: b loop // C initialization code void SystemInit() { // Chip initialization // Initialize OS components } int main() { // Application code }
With this structure, all C programs need to provide is the main() function containing application specific initialization and control flow. The low-level details are hidden away in the assembly startup code.
Summary
To summarize:
- The first instruction executed on Cortex-M0 reset is located at address 0x00000000
- This code sets up the stack pointer and branches to a reset handler
- The reset handler performs chip and OS initialization tasks
- After initialization, control is passed to the main application
- In C programs, the assembly startup handles reset and calls main()
So in all cases, the very first instruction executed simply loads the stack pointer. Understanding the processor reset sequence and initial stack pointer setup is key to embedded software development on ARM Cortex-M0.
Cortex-M0 Stack Usage
The stack pointer initialized by the first instruction on reset is used throughout normal program operation for function calls and interrupt handling. Here are some examples of Cortex-M0 stack usage:
Function Calls
When a function is called, the return address is pushed onto the stack. Any function parameters or local variables are also stored on the stack. On return, the stack frame is popped off and execution continues at the return address.
Exception Handling
If an exception occurs like an interrupt or fault, the stack is used to save context like the program counter and processor flags. The stack allows the handler to safely execute without corrupting the state of the interrupted code.
Context Switching
In an RTOS, a context switch between threads will utilize the stack to store one thread’s context before restoring another’s. This allows multiple threads to share one CPU.
In all these cases the stack is essential for passng data and storing temporary information. That’s why properly initializing the stack pointer is the most important job of the very first Cortex-M0 instruction.
First Instruction Details
Here are some key details on the instruction to initialize the Cortex-M0 stack pointer on reset:
- Located at address 0x00000000 in code memory
- Loads stack pointer (SP) with high memory address for descending stack
- Executed only once on reset
- Typically loads SP from value defined in startup code
- Second instruction branches to reset handler
- Implemented in assembly, transparent to C programmers
- Provided by chip vendor as part of standard startup code
This simple yet essential instruction kicks off the boot process and enables further system initialization. Without properly configuring SP, any use of the stack would lead to a hard fault exception.
Changing the First Instruction
The first instruction is baked into the system startup code and not typically modified. However, if complete low level control is needed the default implementation can be replaced. For example:
- Point SP at a different memory region for stack
- Initialize multiple stacks for exception handling
- Enable the MPU before branching to reset handler
- Clear or initialize any .bss variables
- Configure interrupts prior to reset handler
To make these types of customizations, the assembly startup code linked into the application would need to be edited. This gives low level control but does require in depth knowledge of the processor architecture and reset process.
First Instruction Summary
In summary, the very first instruction executed by an ARM Cortex-M0 on reset loads the stack pointer to initialize it before any other operation:
- Occurs at fixed address 0x00000000
- Implemented in assembly in chip startup code
- Loads stack pointer (SP) with high memory address
- Only executed once on reset
- Enables use of stack by application
- Second instruction branches to reset handler
- Starts the Cortex-M0 boot process
Understanding this critical first step in the reset sequence provides insight into the processor behavior. While this instruction is handled automatically, developers working with the bare metal system core still benefit from knowing what happens in the very first cycle after reset.