The interrupt vector table in ARM processors is located at the start of memory, beginning at address 0x00000000. This table contains the address of each exception and interrupt handling routine. When an exception or interrupt occurs, the processor jumps to the corresponding address in the vector table to run the appropriate handler.
Overview of Interrupts and Exceptions in ARM
Interrupts and exceptions are events that cause the processor to temporarily pause normal program execution and run a special routine called an interrupt handler or exception handler. These events can be generated internally by the processor or externally via peripherals. Examples include:
- Hardware interrupts from peripherals like timers, GPIO pins, uart serial ports, etc.
- Software interrupts invoked by the SVC instruction
- Exceptions such as undefined instructions, memory faults, divide by zero, etc.
The processor needs a way to quickly locate the correct handler based on the interrupt or exception cause. This is the purpose of the interrupt vector table.
Interrupt Vector Table Organization
The interrupt vector table contains one 4-byte entry for each possible interrupt or exception cause, totaling up to 256 entries. The 4-byte value is the memory address of the corresponding handler function.
For example, the first entry at offset 0x00 is for the reset handler, which runs on power-up. The second entry at offset 0x04 is for undefined instructions. And so on.
By default, the interrupt vector table starts at address 0x00000000. But this base address can be relocated by modifying the Vector Table Offset Register (VTOR).
Steps When an Interrupt Occurs
When an interrupt or exception event occurs, the processor handles it by:
- Saving the current program counter value to the link register (LR)
- Saving the current processor mode and status registers
- Entering the handler mode – IRQ mode for most interrupts, or Abort mode for data aborts
- Changing the program counter (PC) to the relevant vector table entry
This causes execution to jump to the handler function. The function can then service the interrupt and return.
Customizing the Interrupt Vector Table
The default exception handlers provided in the vector table perform minimal error handling before halting the system. For real applications, developers need to customize the table with application-specific handlers.
This is done by defining a new vector table array that contains the memory addresses of each custom handler function, and copying it to the start of memory. For example: .section .vectors vector_table: .word _estack /* end stack address */ .word reset_handler /* 1 Reset */ .word nmi_handler /* 2 NMI */ .word hard_fault_handler /* 3 Hard Fault */ … /* other handler addresses */
The linker script must be configured to place the vector table at the very start of flash or RAM by setting the ORIGIN address to 0x00000000.
At boot time, startup code needs to copy the vector table to address 0x00000000. This overrides the default minimal vector table implanted by the ARM compiler.
Relocating the Vector Table
In some cases, the interrupt vector table needs to be placed at a different memory location instead of the default 0x00000000 address. Reasons could include:
- Bootloader requirements to keep the first 4KB or 8KB of memory protected
- Memory map constraints in an RTOS or complex system
To relocate the vector table, the Vector Table Offset Register (VTOR) is used. This is a 32-bit register that holds the address of the vector table base. By writing a new value to VTOR, the processor will read the vector table from the updated address.
Relocation steps would be:
- Compile vector table to a new base address (e.g. 0x2000)
- Update VTOR with the new base address on startup
- Enable relocation by setting SCB_VTOR.TBLOFF bit
The processor will then use the new vector table location transparently when interrupts occur.
Interrupt Vector Table in Cortex-M Devices
The Cortex-M series of ARM processors are very common in microcontroller devices. Here are some key points about Cortex-M vector tables:
- By default located at 0x00000000 in flash memory
- First entry is the initial stack pointer value
- Second entry is the reset handler
- Total of up to 240 exception handlers
- Configurable through VTOR register
- Written in C or assembly, with reference to CMSIS headers
A sample Cortex-M vector table in C: uint32_t vectors[] __attribute__((section(“.vectors”))) = { /* Stack pointer */ (uint32_t)__stack_end__, /* Cortex-M handler */ (uint32_t)reset_handler, /* Other handlers… */ };
Benefits of the Vector Table Approach
The vector table structure provides an elegant and flexible way for ARM processors to handle asynchronous events like interrupts. Key benefits include:
- Allows dispatching to the right handler quickly via direct PC updating
- Simple tables allow for easy reconfiguration and customization
- Relocation through VTOR register helps with complex memory maps
- Maintains performance by keeping handler addresses in internal memory
- Standard structure usable across all ARM architectures
Summary
The key takeaways on ARM interrupt vector tables are:
- Located by default at base address 0x00000000
- Contains one entry per exception/interrupt with handler address
- Processor jumps to table entry to run handler on interrupt
- Can customize table with application handlers
- Relocatable via the VTOR register
- Simple and elegant dispatching for asynchronous events
The vector table is an essential part of ARM’s interrupt handling architecture. Proper configuration allows lower latency and quick execution of interrupt handlers in embedded systems.