SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Relocate the Vector Table in Cortex-M0
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

Relocate the Vector Table in Cortex-M0

Neil Salmon
Last updated: September 16, 2023 2:50 pm
Neil Salmon 9 Min Read
Share
SHARE

The vector table is a key component in Cortex-M0 microcontrollers that contains the reset and exception vectors needed for the system to operate. By default, the vector table resides at the start of flash memory in these controllers. However, you may want to relocate it for several reasons – to place other code at the start of flash, to place it in RAM for faster exception handling, or to allow booting from an external memory device. Relocating the vector table requires configuring the Vector Table Offset Register (VTOR) and updating linker scatter files. This guide will walk through the steps needed to successfully relocate the vector table in Cortex-M0 based microcontrollers.

Contents
Introduction to the Vector TableReasons to Relocate the Vector TableRelocating the Vector Table1. Select a New Vector Table Location2. Configure the VTOR Register3. Update the Linker Scatter File4. Rebuild Code with New Settings5. Redirect Interrupts If NeededConclusion

Introduction to the Vector Table

The vector table contains the initial stack pointer value and reset vector used on power up or reset. It also contains exception vector entries for handling events like interrupts, faults, and traps. For Cortex-M0, the vector table resides at address 0x00000000 in flash memory after reset. Each vector is 4 bytes long, so the full vector table occupies the first 256 bytes of flash.

Here is the default layout of the Cortex-M0 vector table:

  • 0x00: Initial stack pointer value
  • 0x04: Reset vector – points to reset handler code
  • 0x08: NMI vector – points to NMI handler code
  • 0x0C: HardFault vector – points to HardFault handler code
  • 0x10: Reserved vector
  • 0x14: Reserved vector
  • 0x18: Reserved vector
  • 0x1C: Reserved vector
  • 0x20: SVCall vector – points to SVCall handler code
  • 0x24: Reserved vector
  • …

The vector table is a key part of exception handling in Cortex-M0. When an exception occurs like an interrupt or fault, the processor will jump to the corresponding vector entry to run the associated handler code. So relocating the vector table requires retaining this table structure and updating the code locations.

Reasons to Relocate the Vector Table

There are several common reasons you may want to relocate the vector table in Cortex-M0:

  • Place other code at the start of flash – The vector table occupies the first 256 bytes of flash memory by default. You may want to place other code like main() at address 0x00000000 instead.
  • Locate it in RAM for faster exception handling – Storing the vector table in RAM can allow faster jumps to exception handlers since flash has longer access times.
  • Boot from external memory – Relocating the vector table is required if you want to boot from an external memory device.
  • Security reasons – Spreading out code over memory can make some vulnerabilities harder to exploit.

The steps needed to actually relocate the vector table are covered next.

Relocating the Vector Table

Here are the key steps required to relocate the vector table in Cortex-M0 based microcontrollers:

  1. Select a new location – First decide on the new address for the vector table, either in flash or RAM. Ensure no other code uses that space.
  2. Set the VTOR register – The Vector Table Offset Register (VTOR) holds the vector table base address. Update this register with the new vector table address.
  3. Update linker scatter file – The linker file defines where code and data sections get placed in memory. Update it to place the vector table section at the new address.
  4. Rebuild code with new vector table location – Compile your code so the new vector table address gets used on reset and exceptions.
  5. Redirect interrupts if required – If relocating the vector table to RAM, update interrupt vector locations to point to code still in flash.

Detailed explanations for each step are provided in the following sections.

1. Select a New Vector Table Location

First, choose an available address for the new vector table location. Some options:

  • Start of RAM (e.g. 0x20000000)
  • End of flash memory
  • External RAM or flash chip address space

Ensure no existing code uses the new vector table address range. The vector table requires 256 contiguous bytes. Also align the address on a 256 byte boundary for best performance.

2. Configure the VTOR Register

The VTOR register specifies the vector table base address. To relocate the vector table, this register must be updated to point to the new location.

In Cortex-M0, the VTOR register is a 32-bit register located at address 0xE000ED08. Write the new vector table address to this register before any exceptions occur. This is often done early in the reset handler code.

For example, to set the VTOR to 0x20000000 for a vector table located at the start of RAM: /* Reset handler */ void Reset_Handler() { // Update VTOR with new vector table address SCB->VTOR = 0x20000000; // Rest of reset handler code }

After this, exceptions will use the vector table at the new RAM address.

3. Update the Linker Scatter File

The linker scatter file defines the memory map – where code and data sections get placed. To move the vector table, the scatter file must be updated.

For example, a default scatter file may define the vector table section .vectors like this: LR_IROM1 0x00000000 0x00000400 { ; load region size_region ER_IROM1 0x00000000 0x00000400 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } .vectors 0x00000000 0x000001000 { ; vector table placed at start of IRAM } …

To move it, change the .vectors address. For example: LR_IROM1 0x00000000 0x00000400 { ER_IROM1 0x00000000 0x00000400 { *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } … .vectors 0x20000000 0x00000100 { ; vector table placed at start of RAM }

Ensure the new address has at least 256 bytes allocated. Rebuild the code with the updated scatter file to place the vector table correctly.

4. Rebuild Code with New Settings

Next, rebuild your Cortex-M0 project with the new VTOR and scatter file settings. The generated code will now use the relocated vector table. Make sure to set the VTOR register early in your startup code before exceptions are handled.

Test that the reset and exception handlers are called correctly after relocating the vector table.

5. Redirect Interrupts If Needed

One special case is relocating the vector table to RAM. Since RAM is erased on reset, interrupt vectors can’t point directly to handler code in RAM. Instead, they need to point back to code in flash memory.

For ARMv6-M (Cortex-M0), this can be done using a special Interrupt Vector Table Offset Register (VTOR). This register adds an offset to all exception vector fetches, allowing them to indirectly reference code in flash.

So if you move the vector table itself to 0x20000000 in RAM, set the IVT offset to 0xFFFF0000 using: SCB->VTOR = 0x20000000; // Relocated vector table in RAM SCB->IVT_OFS = 0xFFFF0000; // Interrupt vectors point to flash

With this offset, an interrupt vector containing 0x00001234 would point to 0xFFFF1234 in flash when fetched by the processor.

Conclusion

Relocating the vector table in Cortex-M0 microcontrollers provides flexibility in the memory layout. It requires configuring the VTOR register, updating scatter files, and potentially redirecting interrupts. With these steps completed, you can take advantage of a custom vector table location.

Understanding the vector table and relocation process enables creating more advanced embedded firmware. The techniques covered in this guide apply across the entire Cortex-M family, with slight differences in register names and features. Refer to the reference manual for your specific Cortex-M MCU for complete details when relocating the vector table.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Cortex M0 Based MCU DAC Error
Next Article Cortex M0 toggle pins not responding
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

Using NVIC_SystemReset() to Trigger Soft Reset in Cortex-M0

The NVIC_SystemReset() function can be used to trigger a soft…

8 Min Read

Arm vs x86: A Detailed Comparison

Arm and x86 are the two most common CPU architectures…

7 Min Read

gcc-arm cross compiler

A cross compiler is a compiler capable of creating executable…

7 Min Read

Does a microcontroller need a bootloader?

A microcontroller is a small, low-cost computer chip that is…

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

Sign in to your account