XMC4800: Vector table remap/relocation from flash to RAM (bootloader)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User14604
Level 4
Level 4
First solution authored
Hello,

working on a small bootloader project which parses an incoming .HEX file on UART and puts it to flash.

The incoming data is received by UART RX interrupt (USIC0_0_IRQHandler), which itself is put to RAM. The vector table is still located in flash, which will probably prevent any ISR call while erasing/writing flash. Or isn't this necessary at all?

1. The vector offset register (VTOR) is present as PPB->VTOR and SCB->VTOR. Which one I am supposed to use?
2. I know that the vector table must be placed in flash after start-up, because the reset handler cannot be run when placed in RAM. So I basically need to put the vector table in beginning of flash as well as RAM. How do I tell the linker script to do so?

Best regards,
Ernie
0 Likes
1 Reply
User14604
Level 4
Level 4
First solution authored
To answer my own question ...
1. SCB->VTOR needs to be updated. See SystemCoreSetup(). PPB->VTOR will be updated automatically.
2. Created a linker segment, which is placed between stack and .ram_code. The segment must be aligned to 1024 byte in RAM, otherwise relocation will fail (probably?).




Stack (NOLOAD) :
{
__stack_start = .;
. = . + stack_size;
__stack_end = .;
__initial_sp = .;
} > SRAM_combined

/* vector table in RAM (aligned to 1024 byte) */
.ram_vectors (NOLOAD) : {
. = ALIGN(1024);
__ram_vectors_start = .;
* (.ram_vectors);
. = ALIGN(4); /* section size must be multiply of 4 */
__ram_vectors_end = .;
} > SRAM_combined
__ram_vectors_size = __ram_vectors_end - __ram_vectors_start;

/* functions with __attribute__((section(".ram_code"))) */
.ram_code :
{
. = ALIGN(4); /* section size must be multiply of 4 */
__ram_code_start = .;




In startup assembler file (reset handler), an entry has been added to the copy table to make the start-up script copy vector table from flash to new location in RAM.



__copy_table_start__:
.long __data_load, __data_start, __data_size
.long __ram_code_load, __ram_code_start, __ram_code_size
.long __Vectors, __ram_vectors_start, __ram_vectors_size
__copy_table_end__:



In same file the relocate-to-RAM method is called just before main() is called. The relocation could possible be performed in SystemCoreSetup(), but this method is called right at the beginning of the reset handler, where the RAM content has not been loaded and therefore the new RAM vector table is not populated. So I decided to add the new method SYSTEM_relocateVectorsToRam().

In startup_XMC4800.s:


/* relocate vectors to RAM */
ldr r0, =SYSTEM_relocateVectorsToRam
blx r0

ldr r0, =main
blx r0



In system_XMC4800.c:


__attribute__((section(".ram_vectors")))
uint8_t SYSTEM_ramVectors[512]; /** Place holder for vector table in RAM. Will be placed in correct segment by linker,
filled by reset vector and activated by SYSTEM_relocateVectorsToRam() */

/**
* Relocate vectors to RAM.
*
* Must be called after assembler start-up script performed the copy operation from flash.
*/
void
SYSTEM_relocateVectorsToRam(void) {

/* relocate vector table to RAM */
__disable_irq();
SCB->VTOR = (uint32_t) &SYSTEM_ramVectors;
__DSB();
__enable_irq();
}



Improvements are welcome, like not hard-coding the size of SYSTEM_ramVectors[].
0 Likes