SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Can I put interrupt vectors in RAM on Cortex M0 MCU after bootloader?
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

Can I put interrupt vectors in RAM on Cortex M0 MCU after bootloader?

Andrew Irwin
Last updated: October 5, 2023 9:58 am
Andrew Irwin 8 Min Read
Share
SHARE

The short answer is yes, it is possible to place interrupt vectors in RAM instead of flash memory on Cortex M0 microcontrollers after the bootloader has run. However, there are some important considerations to keep in mind when doing this.

Contents
Overview of Cortex M0 Interrupt HandlingCopying the Vector Table to RAMUpdating the VTORConsiderations When Relocating VectorsImplementing Vector Relocation After BootloaderExample CodeReferences

Overview of Cortex M0 Interrupt Handling

On Cortex M0 MCUs, the interrupt vector table is normally located at the beginning of flash memory, starting at address 0x00000000. This vector table contains the reset vector and up to 32 interrupt vector entries. Each entry consists of a 32-bit pointer to the associated interrupt handler function.

By default, the processor fetches these vector addresses from flash memory on startup and whenever an interrupt occurs. However, it is possible to relocate the vector table to RAM after bootup. This offers a few potential benefits:

  • Faster interrupt handling by reducing flash access latency
  • Ability to modify interrupt vectors at runtime
  • Freeing up flash memory by moving vectors to RAM

There are two main steps involved in moving the vectors to RAM:

  1. Copying the vector table from flash to RAM on startup
  2. Updating the Vector Table Offset Register (VTOR) to point to the new RAM-based table

Let’s look at these steps in more detail.

Copying the Vector Table to RAM

The first step is to copy the vector table from its default flash location to a RAM location. This would typically be done in the startup code, after the MCU comes out of reset but before jumping to the main application.

A simple way to do this is:

  1. Allocate a 32-byte aligned byte array in RAM to store the new vector table
  2. Copy the .vectors section from flash to this RAM array using memcpy() or a manual loop
  3. Update each vector’s address in RAM to point to the associated handler function

For example:

#define VECTORS_SIZE 0x100
static uint32_t ram_vectors[VECTORS_SIZE/sizeof(uint32_t)]; 

void copy_vectors(void) {

  // Copy vectors from flash to RAM
  memcpy(ram_vectors, (uint32_t*)0x00000000, VECTORS_SIZE);

  // Update vector addresses to point to handler functions
  ram_vectors[Reset_Handler] = (uint32_t)&ResetHandler;
  ram_vectors[NMI_Handler] = (uint32_t)&NMI_Handler;
  ...

}

This copies the first 256 bytes (0x100) from flash to the RAM array. It then updates each address to point to the correct interrupt handler function.

Updating the VTOR

After copying the vector table, the next step is to update the VTOR register to redirect the processor to the new RAM location on subsequent interrupts or reset.

The VTOR holds the start address of the vector table. This can be changed at runtime. To point to the new RAM-based vector table, write the start address of the ram_vectors array to VTOR:

// Set VTOR to new RAM location
SCB->VTOR = (uint32_t)ram_vectors; 

Now when interrupts occur, the processor will fetch the vector addresses from RAM instead of flash.

Considerations When Relocating Vectors

There are a few important considerations when relocating the vector table to RAM:

  • The new vector table must remain resident in RAM and not get overwritten.
  • Interrupt latency may increase slightly due to added RAM access time.
  • Make sure to update VTOR before enabling interrupts.
  • May need to handle interrupts differently during initial copy stage.
  • Relocation code must execute from flash, not RAM.
  • RAM usage increases by at least 256 bytes (for vector table).

Overall, putting vectors in RAM can improve interrupt response times, and free up flash memory for other uses. But care must be taken to do this properly without disrupting normal interrupt handling.

Implementing Vector Relocation After Bootloader

To implement vector relocation after a bootloader, the basic process would be:

  1. Bootloader runs initial system setup, copies itself to RAM, then jumps to the application entry point.
  2. Application startup code runs, which includes:
  • Copy vector table from flash to RAM
  • Update VTOR to point to new RAM table
  • Continue application initialization
  1. Application main loop runs, with interrupts now being handled via RAM-based vector table.

This allows the flexibility of having a bootloader initialize the system, while still allowing the application to customize the interrupt handling by moving vectors to RAM.

Some things to consider when implementing this:

  • The bootloader must copy itself to RAM before jumping to the application. Otherwise, the relocation code would improperly execute from flash rather than RAM.
  • The bootloader should not enable interrupts initially. The application should handle enabling interrupts after relocating the vectors.
  • Pass necessary information from bootloader to application (RAM table location, etc).
  • May need bootloader to handle any interrupts that occur in initial stages before relocation.
  • Ensure proper transition between bootloader and application entry points.

With careful coding, vector relocation can be cleanly integrated after a Cortex M0 bootloader. This takes advantage of both the initialization abilities of the bootloader, and the flexibility of RAM-based vectors for the application.

Example Code

Here is some example code showing a basic vector relocation implementation after a bootloader:

/* Bootloader */

void bootloader_start() {
  // Initial HW setup

  // Copy bootloader code to RAM

  // Jump to application entry point
  void (*application_entry)(void) = APPLICATION_ADDRESS;
  application_entry();
}

/* Application Code */

#define VECTORS_SIZE 0x100
static uint32_t ram_vectors[VECTORS_SIZE/sizeof(uint32_t)];

void application_entry() {

  // Copy vectors to RAM
  copy_vectors(); 

  // Set VTOR
  SCB->VTOR = (uint32_t)ram_vectors;

  // Continue application init
  init_application();

  // Start main loop
  while(1) {
    // Main loop  
  }
} 

void copy_vectors(void) {
  // Copy flash vectors to ram_vectors
  // Update vector addresses to handler functions
}

This demonstrates the basic flow of initializing the bootloader, transitioning to the application entry point, relocating the vectors, and then running the main application loop.

In conclusion, with careful programming it is certainly possible to relocate the interrupt vectors to RAM after bootup on a Cortex M0 microcontroller. This can provide performance and flexibility benefits for the application after initial bootloader initialization.

References

[1] Cortex-M0 Devices Generic User Guide (DUI0662A). ARM Ltd.

[2] AN258 Application Note. Moving Interrupt Vectors from Flash to RAM on ARM Cortex-M-Based MCUs. Silicon Labs.

[3] Application Note 192. Relocating the ARM Cortex M0 Vector Table. NXP.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article How to activate Eventrecorder together with RTX5 using Cortex-M0?
Next Article Is it possible to port the DesignStart Eval design to a different FPGA board?
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

Where is ARM microcontroller used?

ARM microcontrollers are used in a wide variety of electronic…

7 Min Read

Cortex M0: How to Make the Default crt0.o Startup for GCC

The Cortex-M0 is one of ARM's most basic and widespread…

8 Min Read

What is the reset sequence in ARM Cortex-M0?

The reset sequence in ARM Cortex-M0 microcontrollers involves several steps…

8 Min Read

Cortex-M0 Clock Speed

The Cortex-M0 is an ultra low power 32-bit ARM processor…

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

Sign in to your account