SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Handling Resets and Exceptions During Cortex-M3 Boot Code Execution
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm Cortex M3

Handling Resets and Exceptions During Cortex-M3 Boot Code Execution

Elijah Erickson
Last updated: October 5, 2023 10:08 am
Elijah Erickson 7 Min Read
Share
SHARE

When a Cortex-M3 microcontroller first powers on or resets, it will begin executing boot code located in internal flash or external memory. This boot code is responsible for configuring the system and preparing it for application code execution. However, resets and exceptions may occur during the boot process which must be handled properly to ensure reliable system start up. This article provides guidance on handling resets and exceptions during Cortex-M3 boot code execution.

Contents
Cortex-M3 Reset TypesReset Handler CodeConfigurable Reset BehaviorHandling Exceptions During BootDebugging Boot CodeValidating Boot CodeBoot Optimization TechniquesBoot Security ConsiderationsConclusion

Cortex-M3 Reset Types

There are several types of resets that can occur on a Cortex-M3:

  • Power-on reset – Occurs when power is first applied to the microcontroller
  • External reset – Triggered by an external reset signal
  • Software reset – Triggered by software writing to the AIRCR register
  • Watchdog reset – Triggered by the watchdog timer expiring

Upon any reset event, the Cortex-M3 will start executing code from the reset vector located at address 0x00000000. This reset handler code should perform basic system initialization like copying data sections to RAM, before jumping to more comprehensive boot code.

Reset Handler Code

Here is example reset handler code in C: void Reset_Handler(void) { // Copy .data section from flash to RAM uint32_t size = (uint32_t)&_edata – (uint32_t)&_sdata; uint8_t *pDst = &_sdata; uint8_t *pSrc = &_etext; while(size–) { *pDst++ = *pSrc++; } // Clear BSS section __asm(” ldr r0, =_sbss\n” ” ldr r1, =_ebss\n” ” mov r2, #0\n” ” .thumb_func\n” “zero_loop:\n” ” cmp r0, r1\n” ” it lt\n” ” strlt r2, [r0], #4\n” ” blt zero_loop”); // Call system initialization SystemInit(); // Jump to main __asm(” ldr r0,=_start\n” ” bx r0″); }

This performs essential startup tasks like zeroing RAM, copying initialized data to RAM, and calling SystemInit() before jumping to the main application entry point _start().

Configurable Reset Behavior

The Cortex-M3 reset behavior is configurable via the AIRCR and DEMCR registers:

  • AIRCR controls reset type and reset vector
  • DEMCR controls debug event behavior

For example, to enable a core reset and use the default reset vector: // Enable core reset AIRCR = AIRCR_VECTKEY | AIRCR_SYSRESETREQ; // Use default reset vector AIRCR = AIRCR & ~AIRCR_VECTRESET;

Handling Exceptions During Boot

Exceptions like hard faults, bus faults, and usage faults may occur during the boot process before the Cortex-M3 fault handlers are configured. To handle these cleanly:

  • Implement a default fault handler that at least blinks an error LED
  • Configure SVC_Handler and PendSV_Handler to an infinite loop
  • Configure configurable fault handlers to point to the default handler

Example default fault handler code: void Fault_Handler(void) { // Blink error LED while(1) { Error_LED_Toggle(); } }

And example handler configuration: SVC_Handler = Fault_Handler; PendSV_Handler = Fault_Handler; MemManage_Handler = Fault_Handler; BusFault_Handler = Fault_Handler; UsageFault_Handler = Fault_Handler;

This helps prevent the boot code from crashing catastrophically before the proper application fault handlers are configured.

Debugging Boot Code

Debugging boot code brings unique challenges since the Cortex-M3 debug mechanisms may not yet be enabled. Possible debugging techniques include:

  • Step through boot code with a JTAG/SWD debugger
  • Use an ITM SWO trace to observe boot execution
  • Integrate a UART driver early and print debug messages
  • Toggle GPIO pins at key points to observe with a logic analyzer

Printing debug messages via UART is often the simplest and most informative technique. For example: void boot_message(char *msg) { UART_Init(); // Initialize UART peripheral UART_WriteString(msg); } void Reset_Handler() { boot_message(“Reset occurred”); // Reset handling code boot_message(“Done reset handling”); }

Validating Boot Code

Thoroughly test and validate boot code by injecting faults and exceptions. For example:

  • Trigger reset during different application states
  • Corrupt stack pointer to trigger stack faults
  • Enable MemManage, BusFault, and UsageFault
  • Trigger a hard fault exception
  • Force boot code execution from flash rather than RAM

Validate that in each case, the system reliably recovers and indicates the error. This build confidence in the boot code’s fault handling mechanisms.

Boot Optimization Techniques

Certain optimization techniques can help optimize boot time and performance:

  • Place boot code in ITCM RAM for single cycle access
  • Initialize hardware in a sequential order
  • Configure PLLs/clocks to minimum settings first
  • Only enable necessary peripherals/interrupts
  • Use DMA if possible for memory transfers
  • Keep boot code compact by calling initialized C functions

Faster boot times increase responsiveness and reduce power consumption during start up. Boot time can be measured with oscilloscope on GPIO pins toggling at entry/exit of boot.

Boot Security Considerations

Keep these security considerations in mind for Cortex-M3 boot code:

  • Prevent access to boot code regions via MPU or memory protections
  • Do not include any debug functionality or backdoors
  • Clear registers and memory regions containing sensitive data
  • Use checksums to validate boot code integrity
  • Encrypt boot code region for anti-tampering

Securing the boot code protects the system during its most vulnerable phase and forms a root of trust for chain of trust security architectures.

Conclusion

Robustly handling resets and exceptions during Cortex-M3 boot code is critical for reliable system start up. Use fault handlers, debug methods, and testing techniques to build confidence in the boot code. Apply optimizations and security principles to further enhance the boot process. With careful design and implementation, Cortex-M3 boot code can provide a solid foundation for the application and overall system operation.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Relocating the Vector Table in Cortex-M3 Boot Code
Next Article Reset Sequence in Cortex-M3 Microcontrollers
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

Reset Sequence in Cortex-M3 Microcontrollers

Cortex-M3 microcontrollers feature a flexible reset sequence that allows system…

13 Min Read

Low Power Modes in the Cortex-M3 Architecture (Explained)

The Cortex-M3 processor offers various low power modes to reduce…

8 Min Read

Using Processor-Only vs. Full Reset in Cortex-M3 Debugging

When debugging Cortex-M3 processors, developers have the option of using…

11 Min Read

Debugging Capabilities of the Cortex-M3 (Explained)

The Cortex-M3 processor from ARM offers a comprehensive set of…

12 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account