infineon4engineers Facebook

infineon@google+ Google+

infineon@linkedin linkedin

infineon4engi@twitter twitter

infineon@youtube youtube

+ Reply to Thread
Results 1 to 2 of 2

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

  1. #1
    Beginner Beginner ErnieT is on a distinguished road
    Join Date
    Feb 2018
    Location
    Germany
    Posts
    10
    Points
    150

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

    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

  2. #2
    Beginner Beginner ErnieT is on a distinguished road
    Join Date
    Feb 2018
    Location
    Germany
    Posts
    10
    Points
    150
    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?).

    Code:
    <snip>
    
      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 = .;
    
    <snip>
    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.

    Code:
    <snip>
    __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__:
    <snip>
    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:
    Code:
    <snip>
    /* relocate vectors to RAM */
        ldr  r0, =SYSTEM_relocateVectorsToRam
        blx  r0
    
        ldr  r0, =main
        blx  r0
    <snip>
    In system_XMC4800.c:
    Code:
    <snip>
    __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();
    }
    <snip>
    Improvements are welcome, like not hard-coding the size of SYSTEM_ramVectors[].
    Last edited by ErnieT; Nov 8th, 2018 at 11:28 PM. Reason: further info on PPB->VTOR

+ Reply to Thread

Tags for this Thread

Disclaimer

All content and materials on this site are provided “as is“. Infineon makes no warranties or representations with regard to this content and these materials of any kind, whether express or implied, including without limitation, warranties or representations of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, whether express or implied, is granted by Infineon. Use of the information on this site may require a license from a third party, or a license from Infineon.


Infineon accepts no liability for the content and materials on this site being accurate, complete or up- to-date or for the contents of external links. Infineon distances itself expressly from the contents of the linked pages, over the structure of which Infineon has no control.


Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Usage Terms of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Usage Terms of this site. Infineon reserves the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.