When developing embedded systems using the ARM Cortex-M0 processor and a bootloader, you may encounter issues with incorrect vector tables causing the system to crash or behave erratically on startup. The root cause is often a mismatch between the vector table defined in the bootloader code and the application code. This article provides a guide on identifying and fixing incorrect vector tables to resolve these boot-up issues.
The Role of the Vector Table
The vector table defines the initial stack pointer value and the location of exception and interrupt handlers. It provides the linkage between hardware exceptions/interrupts and the software routines that handle them. The processor fetches the address of the initial stack pointer and the various exception handlers from the vector table located at the start of the memory on startup. The bootloader and application firmware must use the same vector table definition for proper execution flow.
Typical Symptoms of Incorrect Vector Table
When the vector table configured in the bootloader does not match the application’s vector table, you may see the following symptoms on system startup:
- Crashes or hangs immediately on boot-up
- Random crashes or freezes during runtime
- Certain peripherals not working correctly
- Interrupt service routines not triggered properly
These issues arise because the processor fetches incorrect handler addresses or stack pointer values from a misconfigured vector table at startup. This results in erratic execution flow and crashes.
Checking the Bootloader and Application Vector Tables
To identify vector table mismatches, you need to cross-verify the vector table structures defined in the bootloader code against the application firmware. The key areas to check are:
- Startup handler address – This is the reset handler executed on boot-up.
- Stack pointer initialization value – Sets up the initial stack for the processor.
- Exception handler addresses – Handlers for errors like hard fault, NMI, SVC, etc.
- Peripheral interrupt handler addresses – Handlers for interrupts from on-chip peripherals.
Compare the addresses or handler names defined for these entries in the bootloader vector table structure against the application firmware’s vector table. Look for any mismatches in the addresses or name of the handlers populated in the table structures.
Fixing Mismatch Between Bootloader and Application Vector Tables
If you identify a mismatch between the vector tables, the fix involves making the bootloader and application vector tables consistent. Here are some ways to achieve this:
- Reuse same vector table definition: Have the application firmware use the same vector table structure defined in the bootloader codebase.
- Weak symbol bindings: Use weak symbol bindings in the application code to fallback to bootloader handler definitions.
- Runtime remapping: Dynamically remap the vector table to the application definition after bootup.
- Linker script tweaks: Use linker scripts to ensure same addresses for common handler symbols.
- Bootloader configuration: Some bootloaders allow configuring the vector table separately.
The best option depends on the specific bootloader you are using and complexity of the handler definitions in the application code. Using the same vector table or remapping at runtime helps avoid mismatches.
Key Points to Keep in Mind
Here are some key points to keep in mind when working with vector tables in Cortex-M0 systems using a bootloader:
- The bootloader and application must use the same vector table definition for expected execution flow.
- Check vector tables early in case of boot-up crashes or abnormal behavior.
- Match the startup handler, stack pointer, exception handlers and interrupt handlers between bootloader and application.
- Use reuse, remapping, linking or configuration options to make vector tables consistent.
- Test boot-up thoroughly after making any vector table changes.
Example Scenario
Let’s look at an example scenario to understand how this issue can manifest:
- Using Cortex-M0 processor and a USB bootloader that defines a custom vector table.
- Application firmware uses the standard CMSIS vector table definition.
- Startup handler address and stack pointer definition mismatch between the two vector tables.
- Result: On boot-up, incorrect startup handler executed leading to crash.
Fix:
- Identified mismatch in startup handler address by inspecting bootloader and application vector tables.
- Modified the application to reuse the same vector table defined in the bootloader codebase.
- Rebuilt application and bootloader code.
- Boot-up now works correctly with matching vector tables.
This example demonstrates how vector table mismatches can lead to boot-up crashes and how to identify and resolve such issues.
Summary
Vector table issues are a common root cause of failures when using Cortex-M0 processors with a bootloader. Tracing and comparing the vector tables configured in the bootloader and application firmware can help uncover mismatches leading to incorrect execution flow. Addressing these by making the vector table definitions consistent between the bootloader and application ensures proper boot-up and runtime behavior.