Search code examples
clinkerembeddedstm32

How to add padding to a [sub]section in linker script to fill a specific size


I have a stm32f4 mcu with 512 KB of flash memeory. The flash memory is divided in different sections as below:

Flash memory of stm32f4 mcu

I've dedicated the first 16KB section to bootloader. The bootloader executable is compiled separately and I insert padding bytes to it via objcopy:

COMMAND ${CMAKE_OBJCOPY} -O binary --pad-to 0x08004000 --gap-fill 0xff $<TARGET_FILE:${BOOTLOADER}> ${BOOTLOADER}.bin)

and load it before main application using the linker script.

I want to keep some tuning parameters in the second section so they would not change after a hard-reset.

Problem is I don't know how to padd the parameter section to fit exactly in 16KBs so when re-writing the values from application or bootloader (flash sections should be wiped before writing), other sections of the code do not get corrupted.

This is the linker script's text section:

SECTIONS
{
    .text : {
        KEEP(*(.bootloader_section)) /* 16 KB */
        KEEP(*(.parameters_section)) /* 16 KB HOW??? */ 
        
        /* Main application: should start from 0x8008000 = 32KB offset from flash base */
        *(.vectors) /* Vector table */
        KEEP(*(.firmware_info))
        *(.text*)   /* Program code */
        . = ALIGN(4);
        *(.rodata*) /* Read-only data */
        . = ALIGN(4);
    } >rom

And also there is a parameters.c file in the project which contains parameter values:

__attribute__((section(".parameters_section"))) Parameters_t param = {
    .tuning.value1 = 0x4,
    .tuning.value2 = 0x3,
    .tuning.value3 = 0x2,
    .tuning.value4 = 0x3,
    .reserved4 = 0xaaaaaaaa,
    .reserved5 = 0xaaaaaaaa,
    .reserved6 = 0xaaaaaaaa,
    .reserved7 = 0xaaaaaaaa,
    .reserved8 = 0xaaaaaaaa,
    .reserved9 = 0xaaaaaaaa,
    .reserved10 = 0xaaaaaaab,
    .reserved11 = 0xaa0aaaaa,
    .reserved12 = 0xaaaaaaaa,
    .reserved13 = 0xaaaaaaaa,
    .reserved14 = 0xaaaaaaaa,
    .reserved15 = 0xaaaaaaaa,
    .reserved16 = 0xaaaaaaaa,
    .reserved17 = 0xaaaaaaaa,
    .reserved18 = 0xaaaaaaaa,
    .reserved19 = 0xaaaaaaaa,
};

Should I also compile the parameters.c separate from other source files and pad it using objcopy? or is there other ways to do this?


Solution

  • Why not just define memory sections for the various things you want, and make sure the relevant things go in each?

    This is completely untested, but hopefully shows the intent.

    MEMORY
    {
      RAM         (xrw) : ORIGIN = 0x20000000,  LENGTH = 36K
      BOOTFLASH   (rx)  : ORIGIN = 0x8000000,   LENGTH = 16K
      PARAMETERS  (r)   : ORIGIN = 0x8004000,   LENGTH = 16K
      APPFLASH    (rx)  : ORIGIN = 0x8008000,   LENGTH = 128K
    }
    
    SECTIONS
    {
        .boottext : {
            KEEP(*(.bootloader_section)) /* 16 KB */
        } > BOOTFLASH
    
        .parameters : {
            KEEP(*(.parameters_section)) /* 16 KB */
        } > PARAMETERS
    
        .text : {
            *(.vectors) /* Vector table */
            KEEP(*(.firmware_info))
            *(.text*)   /* Program code */
            . = ALIGN(4);
            *(.rodata*) /* Read-only data */
            . = ALIGN(4);
        } > APPFLASH
    ...
    }
    

    You'd need to correct the size of the RAM and the APPFLASH, I just used random numbers there, since I don't know about how much RAM you have, and couldn't be bothered calculating the remaining flash size.