In this lesson, you will learn how to shift the location of your interrupt vector table so that your application can manage its own hardware interrupts independently of the bootloader.
Why Relocate the Vector Table?
In many embedded systems, the processor expects the vector table (the jump table for ISRs) to reside at a fixed address, typically at the very beginning of Flash memory (address 0x00000000). When a bootloader occupies this space, it handles the initial interrupts. However, once the bootloader jumps to your main application, you need the processor to look at a new vector table—one defined within your application's own memory space—to handle its specific peripheral interrupts.
The Mechanism
Most modern microcontrollers (like those based on the ARM Cortex-M architecture) provide a dedicated register specifically for this purpose, often called the Vector Table Offset Register (VTOR).
By default, this register points to the hardware reset vector. To relocate the table, your application's startup code must calculate the base address of the new vector table and write that address into the VTOR. The processor will then use this new offset to calculate the memory address of every interrupt handler triggered thereafter.
Implementation Example
If your application is linked to start at address 0x08004000 rather than the base of the Flash, you must update the VTOR early in your main() or system initialization routine:
// Define the base address where the application's vector table resides
#define APPLICATION_VECTOR_TABLE_ADDRESS 0x08004000
void relocate_vector_table(void) {
// Access the VTOR register (address defined by the architecture)
volatile uint32_t *vtor = (uint32_t *)0xE000ED08;
// Point the processor to the new table
*vtor = APPLICATION_VECTOR_TABLE_ADDRESS;
}
By executing this shift during the earliest stage of your application entry, you ensure that any interrupt firing after the bootloader hands off control is routed correctly to the handlers defined within your application binary. Without this step, the processor would continue to look at the bootloader's memory space, likely resulting in a hard fault or unexpected system behavior when your application tries to trigger interrupts.
Key Takeaway: Relocating the vector table via the VTOR register allows an application to "own" its interrupt handlers by overriding the default system-wide vector table pointer.