Skip to main content
Visitor II
May 3, 2020
Question

Linker script for ROM to RAM copying

  • May 3, 2020
  • 5 replies
  • 3330 views

I am writing a USB MSD bootloader for an STM32L4 processor with 2MB of Flash. The bootloader code will reside in Flash as will the application code. The application code will most likely be larger than 1MB so I’m thinking to have only a single bank. I will thus need to copy the pertinent routines that access Flash for erasing and programming from Flash to RAM. I can put all the pertinent routines into one file. I would like some help in writing the linker script so that I can specify that file separately for ROM to RAM copying. I’ve been looking at the linker script manual but I’m still unclear about the exact syntax. Any help would be greatly appreciated!

Thanks

    This topic has been closed for replies.

    5 replies

    Super User
    May 3, 2020

    In your function:

    __attribute__ ((section (".code_in_ram")))
    void function_to_overwrite_flash() {
     ...
    };

    In your linker script:

    /* Initialized data sections goes into RAM, load LMA copy after code */
     .data : 
     {
     . = ALIGN(4);
     _sdata = .; /* create a global symbol at data start */
     *(.data) /* .data sections */
     *(.data*) /* .data* sections */
     
     . = ALIGN(4);
     *(.code_in_ram)
     *(.code_in_ram*)
     
     . = ALIGN(4);
     _edata = .; /* define a global symbol at data end */
     } >RAM AT> FLASH

    And in your startup code:

    /* Copy the data segment initializers from flash to SRAM */ 
     movs r1, #0
     b LoopCopyDataInit
     
    CopyDataInit:
     ldr r3, =_sidata
     ldr r3, [r3, r1]
     str r3, [r0, r1]
     adds r1, r1, #4
     
    LoopCopyDataInit:
     ldr r0, =_sdata
     ldr r3, =_edata
     adds r2, r0, r1
     cmp r2, r3
     bcc CopyDataInit

    Note that you can use variables on the stack within that function, but any variables/constants stored in ROM will no longer be valid once you erase it.

    Visitor II
    May 3, 2020

    Calls to built-in functions would too cease to work.

    Visitor II
    May 3, 2020

    > I will thus need to copy the pertinent routines that access Flash for erasing and programming from Flash to RAM.

    No, you don't need to. Flash programming works fine from the same bank.

    > I can put all the pertinent routines into one file.

    They must be linked separately from the application. Put them into a separate project.

    Best practice is to locate the bootloader at the beginning of the flash. If a flag is set a certain way, and the reset source is software, then start the bootloader process, otherwise jump to the application. The application sets the flag and calls NVIC_SystemReset() to start the bootloader. When the bootloader finishes updating the flash, resets the flag and calls NVIC_SystemReset() to reset all peripherals before jumping to the application. The flag should be at a fixed memory location which is excluded in the linker scripts of both projects.

    erussellAuthor
    Visitor II
    May 3, 2020

    I am confused by your statement that you can program in the same bank where the code is running. I was interpreting section 3.3.8 of the reference manual to mean that you cannot either program or erase sectors (pages) from one bank while executing code from the same bank. And I would assume the same if there is only one bank. So you’re saying that I don’t need to have the routines that program or erase pages be put into RAM. That was true for the Kinetis processor I was using which had a separate Flash control module. I am planning to have the bootcode at the beginning of Flash which will jump to the application code unless it sees that a USB host has been connected. After the app file has been copied from the host and programmed into Flash, the bootcode will jump to the application.

    Visitor II
    May 3, 2020

    No, it's the other way round. You cannot execute code (or read data) from the same bank while a flash write or erase is in progress.

    Flash write or erase operations block reading from the same bank. The core will wait patiently for the operation to finish, and continue.

    Just keep in mind that erasing a flash sector can take a few seconds (listed somewhere in the datasheet), during that time everything is blocked.

    erussellAuthor
    Visitor II
    May 3, 2020

    Great! Thanks so much for the help!