SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Bootloader causing incorrect vector table and issues with PendSV
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

Bootloader causing incorrect vector table and issues with PendSV

Andrew Irwin
Last updated: September 17, 2023 2:27 am
Andrew Irwin 7 Min Read
Share
SHARE

When developing embedded systems using ARM Cortex-M processors, a common issue that can occur is the bootloader causing an incorrect vector table and problems with the PendSV interrupt. This can lead to hard-to-diagnose faults and system crashes. In this article, we’ll examine the root causes of this issue and provide solutions to resolve it.

Contents
The Role of the BootloaderHow the Bootloader Can Cause IssuesVector Table Located IncorrectlyInvalid Interrupt Handler AddressesFailing to Initialize the Stack PointerForgetting to Forward InterruptsSolutionsInitialize the Vector Table CorrectlyCarefully Set Handler AddressesSet Up the Main StackForward Interrupts to ApplicationsValidate Bootloader OperationInitialize RAM CorrectlyExample Bug AnalysisThe IssueRoot CauseThe FixAdvanced TechniquesError Checking and ValidationFault HandlersVersioning and PatchingIsolation and ContainmentCode Reviews and Static AnalysisComponent TestingConclusion

The Role of the Bootloader

The bootloader is a small program that runs when the microcontroller first powers up. Its main responsibilities are:

  • Set up the initial stack pointer and processor mode
  • Initialize RAM
  • Copy the application program from flash to RAM
  • Jump to the application code start address

To accomplish these tasks, the bootloader needs to configure the vector table, which holds the addresses of key interrupt service routines. This includes exceptions like hard faults and the PendSV interrupt. The vector table is normally located at the start of flash or RAM.

How the Bootloader Can Cause Issues

There are a few ways that bugs in the bootloader code can lead to an incorrect vector table and issues with PendSV:

Vector Table Located Incorrectly

The processor always expects the vector table to be at a predefined address, usually 0x00000000. If the bootloader configures the vector table at the wrong location, the processor will read invalid data when exceptions occur.

Invalid Interrupt Handler Addresses

Even if the vector table is located properly, invalid handler addresses can still be programmed. For example, setting the PendSV address to 0x00000000 will cause a fault when PendSV activates.

Failing to Initialize the Stack Pointer

The stack pointer provides critical storage for context information when handling interrupts. If the bootloader does not set up the main stack pointer correctly, exceptions will fail in unpredictable ways.

Forgetting to Forward Interrupts

When jumping to the application, the bootloader should enable interrupts and provide code to forward unhandled interrupts to the application vector table. If this is missing, interrupts go unserviced.

Solutions

While bootloader bugs can be tricky, there are steps developers can take to avoid these issues:

Initialize the Vector Table Correctly

Use the NVIC_SetVectorTable() function to correctly point the vector table to the intended memory location. This ensures exceptions go to the right place.

Carefully Set Handler Addresses

When populating the vector table entries, verify that each address points to a valid handler function. Pay special attention to critical interrupts like PendSV and SysTick.

Set Up the Main Stack

Early in startup, initialize the Main Stack Pointer register with the address of a valid RAM area for the stack. Aim for at least a few KB of stack space.

Forward Interrupts to Applications

Before jumping to the application, use NVIC_EnableIRQ() to enable interrupts globally. Also provide default handler code that forwards unserviced interrupts to the application vector table.

Validate Bootloader Operation

Thoroughly test the bootloader and confirm that exceptions are handled gracefully. Insert faults using a debugger or write test code to trigger interrupts.

Initialize RAM Correctly

Make sure any RAM usage is safely initialized to avoid errant code execution. The best practice is to zero out all RAM areas on startup.

Example Bug Analysis

To make troubleshooting bootloader vector table issues more concrete, consider this example:

The Issue

A Cortex-M4 system using a custom bootloader is experiencing crashes soon after the application starts. Analysis shows that the crashes coincide with PendSV interrupts, indicating a fault during handling.

Root Cause

By stepping through the bootloader code, the culprit is found. The PendSV interrupt is accidentally being forwarded to the bootloader’s interrupt table instead of the application table after startup. This results in a crash when the invalid interrupt handler address is executed.

The Fix

To resolve the issue, the bootloader code is updated to point PendSV to the application’s interrupt table instead of the bootloader table after startup. This ensures that PendSV is properly handled by the application for correct operation.

Advanced Techniques

For complex bootloaders and applications, additional techniques can help avoid subtle vector table defects:

Error Checking and Validation

Include sanity checks like stack overflow detection and watchdog timers to identify faults quickly and halt the system before corruption spreads.

Fault Handlers

Provide fault handlers that can catch common exceptions, print debug data, and place the system into a safe state when anomalies occur.

Versioning and Patching

Support bootloader versioning and live patching to enable bug fixes to be deployed without full firmware updates.

Isolation and Containment

Use memory protection units to limit access and prevent corruption from spreading across partition boundaries.

Code Reviews and Static Analysis

Conduct rigorous code reviews and static analysis of bootloader source code to identify defects before release.

Component Testing

Test the bootloader thoroughly as an independent component before integration to uncover issues early.

Conclusion

Bootloader bugs that lead to incorrect vector tables and PendSV handling issues can certainly cause major problems in Cortex-M systems. However, through careful initialization, validation, and testing, developers can avoid these frustrating defects. Following best practices for bootloader implementation, along with fault detection and mitigation techniques, leads to robust embedded systems.

With an understanding of the causes, solutions, and preventative measures, developers can confidently build Cortex-M applications on a dependable software foundation.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Context switches with Cortex-M0 is wrong what to do
Next Article Optimize Context Switching Performance on Cortex-M0
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

ARM Cortex-M4 Instruction Set

The ARM Cortex-M4 is a 32-bit RISC processor core designed…

5 Min Read

What is ARM Assembly Language?

ARM assembly language is a low-level programming language used to…

9 Min Read

ARM Cortex-M4 Interrupt Handling

The ARM Cortex-M4 processor has a flexible and configurable interrupt…

7 Min Read

What is ARM cross-compiler?

An ARM cross-compiler is a compiler that runs on one…

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

Sign in to your account