The Cortex-M0 and Cortex-M3 are two popular ARM processor cores used in many embedded and IoT applications. Both support vector table remapping, which allows flexibility in locating the exception/interrupt vector table. However, there are some key differences between the Cortex-M0 and Cortex-M3 implementations of vector table remapping that developers need to be aware of.
Overview of Vector Table Remapping
In Cortex-M processors, the vector table is a key data structure that defines the start addresses of exception and interrupt handlers. By default, this vector table is located at the start of code memory (address 0x00000000). However, both Cortex-M0 and M3 provide a vector table offset register (VTOR) that allows you to remap the location of the vector table to a different region of code memory.
This vector table relocation is useful for several reasons:
- It allows you to locate the vector table in RAM rather than flash memory for faster exception handling.
- It enables better usage of flash memory when you have multiple application images.
- It helps avoid conflicts when linking code from multiple libraries.
However, despite this common capability, the Cortex-M0 and M3 differ in how they implement vector table relocation.
Cortex-M0 Vector Table Remapping
The Cortex-M0 implementation of vector table remapping is relatively simple. The VTOR register is 32 bits wide and specifies a byte address for the start of the vector table. This allows the vector table to be positioned anywhere within the 4GB address space of the processor.
When vector table relocation is enabled, the Cortex-M0 will fetch the address of each exception handler from the VTOR-specified location. For example, if you program VTOR to 0x200000, the processor will look at address 0x200000 for the initial stack pointer value and address 0x200004 for the reset handler address, etc.
One key thing to note with Cortex-M0 is that the vector table addresses are absolute addresses. So if you set VTOR to 0x200000, the handler addresses will be absolute addresses like 0x5000, 0x6000, etc. This allows flexibility but means you need to generate the vector table accordingly.
Cortex-M3 Vector Table Remapping
The Cortex-M3 implementation of vector table relocation is a bit more sophisticated than the Cortex-M0 approach. The key differences are:
- The M3 VTOR register is only 24 bits wide, so it specifies an offset from address 0x00000000 rather than an absolute address.
- The vector table entries stored at the VTOR location specify offsets rather than absolute addresses.
What this means in practice is that with the Cortex-M3, you specify a VTOR offset in units of 4KB blocks. For example, setting VTOR to 0x20 means the vector table will be located at address 0x00008000.
Then, the vector table entries at this new location specify offsets from address 0x00000000 rather than absolute addresses. For instance, if the first vector table entry is 0x40, it means the reset handler is located at address 0x00000040 rather than being the absolute address 0x00000040.
This approach has a couple implications:
- Vector table relocation is limited to the lower 256MB address range rather than the full 4GB range.
- It provides an efficient way to use a single set of vector table offsets even when remapping the table to different locations.
Key Differences Summary
In summary, the key differences between Cortex-M0 and Cortex-M3 vector table remapping are:
|VTOR register size
|Offset from 0x00000000
|Offset from 0x00000000
These differences mean that Cortex-M0 offers more flexibility in terms of the vector table placement, while Cortex-M3 provides some extra convenience in using position-independent vector table offsets.
Configuring Vector Table Remapping
The process of setting up vector table remapping is mostly straightforward on both Cortex-M0 and M3 processors. The key steps are:
- Define a vector table region in code memory for the relocated table.
- Populate the region with exception handlers defined at appropriate absolute or offset addresses.
- Write the VTOR register value to point to the start of the vector table region before you enable exceptions.
- Clean and invalidate instruction and data caches if enabled.
This can all be done in C/C++ code, but is often handled by the linker script and startup code provided by your IDE or software framework. Consult your specific development tool documentation for details on the exact remapping configuration process.
Here are some examples of why and how you might use vector table remapping with Cortex-M0/M3 microcontrollers:
A bootloader is a small program that loads your main application code. By remapping the vector table to point to bootloader exception handlers initially, it can run first to boot your application from external flash or another interface.
Over-the-air (OTA) firmware updates require robust fail-safe mechanisms. Remapping the vector table to point to a safe set of handlers in readonly memory ensures exceptions are properly handled if an update fails or interrupts normal operation.
You may have multiple application images in internal flash that you switch between. Remapping the vector table makes it easy to have separate vector tables for each image while minimizing wasted flash space.
If integrating code from multiple third-party libraries that define ISRs, vector table relocation can resolve conflicts by allowing each set of ISRs to reside at different addresses.
In closing, Cortex-M0 and Cortex-M3 both enable flexible vector table placement via the VTOR register. The main differences are that Cortex-M0 supports full 4GB address relocation with absolute vector addresses, while Cortex-M3 uses an offset scheme within a 256MB range. With an understanding of these implementations, developers can take full advantage of vector table remapping to optimize exception handling, bootloaders, OTAs, flash usage, and library compatibility.
For additional details on how to configure and take advantage of vector table remapping, check the application notes and reference manuals for your specific Cortex-M0 or Cortex-M3 microcontroller.