Hi guys,
Does the M0 always default to 0x0 when an interrupt triggers? I understand VTOR is not available in M0 for relocation of the tables.
Can I copy the application vector table just the vector table to beginning of SRAM and remap the SRAM to 0x0 so that during interrupts it will always go to the SRAM to fetch the vectors? Is that the right way to relocate the vector?
If I understand it correctly the REMAP is mainly used for
1. Power up fetch of first MSP and Reset Vector
2. After powerup --- allows interrupt vectors (assume M0 always goes to 0x0 to fetch vectors) to be fetched from the REMAPed addresses.
3. It masks out accesses to the actual memory located on physical 0x0 on the bus.
It is not really useful for actual application program because the PC can be explicitly controlled with branching/jump instructions.
Hypothetically, if I do not place any memory blocks on 0x0 and then use REMAP to switch some other blocks at say 0x1 or 0x2 into 0x0 as needed, would this be a good way to switch the location of the vector table?
For example
SRAM at 0x1
FLASH at 0x2 ((Bootloader (at beginning)+ application Prog))
At power up Remap FLASH to 0x0 -- Run bootloader Vectortable + code; copy AppProgram Vector table to SRAM.
REMAP SRAM to 0x0 (application vector table active), jump to Application at FLASH (now mapped to 0x2)
and so on.
It would seem possible to run the MCU and use the REMAP in this way, but would appreciate any feedback from more experienced designers.
Initial thoughts were obtained from this thread regarding relocating vector tables
https://community.arm.com/developer/ip-products/processors/f/cortex-m-forum/13533/relocating-the-vector-table-in-cortex---m0/36527#36527
Yes, the M0 always default fetch to vector table at address 0x0 when an interrupt triggers. No, VTOR is not available in M0 for relocation of the tables.
And your example makes sense to me.
I think the key point is that the bus-matrix does some remap, not mask.
Thanks for the reply Haiyan.
Just to elaborate a little bit on the address remap and masking (term which I use here). Copying a short snippet of code from cmsdk_mcu_addr_decode.v taken from the example Cortex-M0 CMSDK system
// AHB address decode // 0x00000000 - 0x0000FFFF : 64K flash / boot firmware // 0x01000000 - 0x0100FFFF : boot firmware : only 4k is used // 0x20000000 - 0x2000FFFF : SRAM // 0x40000000 - 0x4000FFFF : APB subsystem // 0x40010000 - 0x4001FFFF : AHB peripherals (GPIOs) // 0xF0000000 - 0xF0000FFF : System ROM Table // ---------------------------------------------------------- // Memory decode logic // ---------------------------------------------------------- // If Boot loader is not present (BOOT_LOADER_PRESENT==0), // boot_hsel always 0. // Otherwise select if address = 0x0100xxxx or when remap_ctrl // is 1, and address = 0x0000xxxx assign boot_hsel = (BOOT_LOADER_PRESENT==0) ? 1'b0 : ((haddr[31:16]==16'h0000) & (remap_ctrl==1'b1)) | (haddr[31:16]==16'h0100); assign flash_hsel = (BOOT_LOADER_PRESENT==0) ? // 0x00000000 // Boot loader not present. Select if first 64KB is selected (haddr[31:16]==16'h0000) : // Boot loader present. If boot loader is selected then flash is // not selected (haddr[31:16]==16'h0000) & (boot_hsel==1'b0);
Assuming the BOOT_LOADER_PRESENT = 1 and remap_Ctrl = 1 boot_hsel will be asserted when either 0x0000 or 0x0100 appears on HADDR. Note that natively boot_hsel is mapped to 0x0100 when remap_ctrl = 0.
Conversely flash_hsel (supposedly the Program Flash) which is mapped to 0x0000 will be 'masked' out (in my own terms) when remap_Ctrl = 1 because all accesses to 0x0000 on HADDR will be received by boot_hsel instead of flash_hsel.
In any case I will have to try out my example with actual C-code to prove the concept.
Going off topic here but along the lines of bootloading, is there a good reference material on understanding the ARM/GCC toolchain linker scripts and syntax, section files and the startup.s files? I might start another thread on this.