Problem adding section to linker script

Sysprogs forums Forums VisualGDB Problem adding section to linker script

Tagged: 

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #10224
    engicoder
    Participant

    I am trying to add a section to flash memory to store user settings that would be updated by using the FLASH erase/program functions. I copied the default flash linker script for the device I am using (STM32F030R8), modified it, and updated the project settings to use the modified script.

    Here is the modified section of the linker script:

    
    MEMORY
    {
        FLASH (RX)  : ORIGIN = 0x08000000, LENGTH = 64K - 1K
        SETTINGS(RWX) : ORIGIN = 0x0800FC00, LENGTH = 1K
        SRAM (RWX)  : ORIGIN = 0x20000000, LENGTH = 8K
    }
    
    _estack = 0x20002000;
    
    SECTIONS
    {
        .settings :
        {
            . = ALIGN(4);
            *(.settings)
            . = ALIGN(4);
        } > SETTINGS
    
    ...
    

    I added a variable to my code and used the __attribute__(__section__()) attribute to assign it to the new .settings section.

    
    __attribute__((__section__(".settings"))) const uint16_t settings[512];
    

    The code builds fine but when I try to program the device using GDB I get an error on the load indicating that the size of my new section does match the “loaded file”.

     
    load
    &"load\n"
    ~"Loading section .isr_vector, size 0xc0 lma 0x8000000\n"
    +download,{section=".isr_vector",section-size="192",total-size="23184"}
    +download,{section=".isr_vector",section-sent="192",section-size="192",total-sent="192",total-size="23184"}
    ~"Loading section .text, size 0x6d0 lma 0x80000c0\n"
    +download,{section=".text",section-size="1744",total-size="23184"}
    ~"Loading section .init_array, size 0x4 lma 0x8000790\n"
    +download,{section=".init_array",section-size="4",total-size="23184"}
    ~"Loading section .fini_array, size 0x4 lma 0x8000794\n"
    +download,{section=".fini_array",section-size="4",total-size="23184"}
    ~"Loading section .eeprom, size 0x80 lma 0x800fc00\n"
    +download,{section=".eeprom",section-size="128",total-size="23184"}
    &"Error finishing flash operation\n"
    ^error,msg="Error finishing flash operation"
    compare-sections
    &"compare-sections\n"
    ~"Section .eeprom, range 0x800fc00 -- 0x800fc80: MIS-MATCHED!\n"
    ~"Section .isr_vector, range 0x8000000 -- 0x80000c0: matched.\n"
    ~"Section .text, range 0x80000c0 -- 0x8000790: matched.\n"
    ~"Section .init_array, range 0x8000790 -- 0x8000794: matched.\n"
    ~"Section .fini_array, range 0x8000794 -- 0x8000798: matched.\n"
    &"warning: One or more sections of the target image does not match the loaded file\n"
    &"\n"
    ^done
    

    Am I missing something?

    • This topic was modified 7 years, 10 months ago by engicoder.
    • This topic was modified 7 years, 10 months ago by engicoder.
    • This topic was modified 7 years, 10 months ago by engicoder.
    • This topic was modified 7 years, 10 months ago by engicoder.
    #10232
    engicoder
    Participant

    Note: There is a mismatch in the info above. The array dimension is 512, but should be 64. The error dump is when the array length was 64, hence the section size of 128. I tried both array sizes.

    #10235
    support
    Keymaster

    Hi,

    Please check the contents of the OpenOCD window for more specific error messages. This should explain why FLASH programming fails.

    #10238
    engicoder
    Participant

    Where do I find the OpenOCD window? If you mean the test OpenOCD settings, the runs successfully. The errors I am seeing are coming from GDB after OpenOCD connects successfully.

    • This reply was modified 7 years, 10 months ago by engicoder.
    #10240
    support
    Keymaster

    Hi,

    The testing only checks the JTAG connectivity and does not try to load the FLASH. In order to see FLASH-related errors, please select Debug->Windows->GDBServer Console.

    #10246
    engicoder
    Participant

    I don’t see a GDBServer Console under Debug->Windows

    The problem I am seeing occur when I select Debug->Program and Start without Debugging

    First I see this popup:

    When I click on View GDB log I see this popup

    If I select the GDB Server log tab I see this:

     

    If I remove any references to the array declared

    __attribute__((__section__(".settings"))) const uint16_t settings[64];

    It programs without problem.

    • This reply was modified 7 years, 10 months ago by engicoder.
    #10248
    engicoder
    Participant

    I created a project using the Standard Peripheral template and replace LEDBlink.cpp with main.c

    Here is the source for main.c

    
    #include "stm32f0xx_flash.h"
    
    __attribute__((__section__(".settings"))) const uint16_t settings[64];
    
    int main()
    {
        uint16_t eep = settings[0];
    
        FLASH_Lock();
        FLASH_ErasePage((uint32_t)&settings[0]);
        FLASH_ProgramHalfWord((uint32_t)&settings[0], 0xDEAD);
        FLASH_ProgramHalfWord((uint32_t)&settings[1], 0xBEEF);
        FLASH_Unlock();
    
        eep = settings[0];
    
        for (;;)
        {}
    }
    
    #10249
    support
    Keymaster

    Hi,

    The “GDBServer Console” command will only be available during debugging, so you can view it after pressing F5.

    Based on the other details you provided, it looks like OpenOCD may have troubles programming sections that are not properly aligned. Please try modifying your linker script to place the new section inside the .text section:

    .text :
    {
    *(.text)
    ...
    . = <end of FLASH> - <expected size>;
    *(.eeprom)
    . = ALIGN(4);
    } > FLASH

     

    #10267
    engicoder
    Participant

    Thanks for the quick replies!
    I tried what you suggested. Flash is 64K so should extend to 0x08010000. Subtracting 1K gives us 0x0800C00 as the address for the .settings section.
    Using the following linker script:

     
        .text :
        {
            . = ALIGN(4);
            _stext = .;
    
            *(.text)
            *(.text*)
            *(.rodata)
            *(.rodata*)
            *(.glue_7)
            *(.glue_7t)
    
            . = 0x0800FC00;
            *(.settings)
    
            KEEP(*(.init))
            KEEP(*(.fini))
            . = ALIGN(4);
            _etext = .;
    
        } > FLASH
    

    I get a linker error:

    
        ld.exe: [...] section '.text' will not fit in region 'FLASH'
        ld.exe: region 'FLASH' overflowed by 134217952 bytes
    

    I got the same result if I try to create a separate section declaration as follows:

     
        .settings :
        {
            . = 0x0800FC00;
            *(.settings)
            . = ALIGN(4);
        } > FLASH
     
    
    • This reply was modified 7 years, 10 months ago by engicoder.
    #10269
    support
    Keymaster

    Hi,

    Please try using the section-relative address, i.e.

    . = 0x0000FC00;
    • This reply was modified 7 years, 10 months ago by support.
    • This reply was modified 7 years, 10 months ago by support.
    #10274
    engicoder
    Participant

    Thank you, that worked. I did have to compensate for the standard .isr_vector section that comes before text. In the default linker scrip there are also some sections that follow .text such as .ARM.extab, .init_array, .fini_array, etc. These seemed to be have sizes of zero, but I assume that is not always the case. Using your suggest as a hint, I was able to write a section definition that I placed after all other FLASH sections and calculate the current offset.

    
        _offset = .;
     
        .settings :
        {
            . = . + 0x0800FC00 - _offset;
            *(.settings)
        } > FLASH
    

    Oddly two other seemingly equivalent offset expressions generated a linker overflow error:
    . = 0x0800FC00;
    . = . + 0x0800FC00 - .;
    I assume this has to do with how the linker evaluates the expressions.

    For future readers, following is the FLASH section of the default linker script with the above addition.

    
    
    ENTRY(Reset_Handler)
    
    MEMORY
    {
        FLASH (RX)     : ORIGIN = 0x08000000, LENGTH = 64K
        SRAM (RWX)     : ORIGIN = 0x20000000, LENGTH = 8K
    }
    
    _estack = 0x20002000;
    
    SECTIONS
    {
        .isr_vector :
        {
            . = ALIGN(4);
            KEEP(*(.isr_vector))
            . = ALIGN(4);
        } > FLASH
    
        .text :
        {
            . = ALIGN(4);
            _stext = .;
    
            *(.text)
            *(.text*)
            *(.rodata)
            *(.rodata*)
            *(.glue_7)
            *(.glue_7t)
    
            KEEP(*(.init))
            KEEP(*(.fini))
            . = ALIGN(4);
            _etext = .;
    
        } > FLASH
    
        .ARM.extab :
        {
            . = ALIGN(4);
            *(.ARM.extab)
            *(.gnu.linkonce.armextab.*)
            . = ALIGN(4);
        } > FLASH
    
        .exidx :
        {
            . = ALIGN(4);
            PROVIDE(__exidx_start = .);
            *(.ARM.exidx*)
            . = ALIGN(4);
            PROVIDE(__exidx_end = .);
        } > FLASH
    
        .ARM.attributes :
        {
            *(.ARM.attributes)
        } > FLASH
    
        .preinit_array :
        {
            PROVIDE(__preinit_array_start = .);
            KEEP(*(.preinit_array*))
            PROVIDE(__preinit_array_end = .);
        } > FLASH
    
        .init_array :
        {
            PROVIDE(__init_array_start = .);
            KEEP(*(SORT(.init_array.*)))
            KEEP(*(.init_array*))
            PROVIDE(__init_array_end = .);
        } > FLASH
    
        .fini_array :
        {
            PROVIDE(__fini_array_start = .);
            KEEP(*(.fini_array*))
            KEEP(*(SORT(.fini_array.*)))
            PROVIDE(__fini_array_end = .);
        } > FLASH
    
        . = ALIGN(4);
        _sidata = .;
    
        _offset = .;
    
        .settings :
        {
            . = . + 0x0800FC00 - _offset;
            *(.settings)
        } > FLASH
    

    I would still like to understand why I could not create a separate MEMORY entry and associate a section with it.

    • This reply was modified 7 years, 10 months ago by engicoder.
    #10279
    support
    Keymaster

    Hi,

    Most likely something went wrong with the alignment and one of the sections ended up not being aligned properly. Running “arm-eabi-objdump -h <ELF file>” and checking the section addresses and sizes could explain what could be wrong.

    #10288
    engicoder
    Participant

    How do I generate an elf file with an MSBuild based project, like the ones created by the template?

    #10290
    engicoder
    Participant

    Ah, my mistake, it is generated, it just doesn’t have a .elf extension. The elf file has no extension.

    #10293
    support
    Keymaster

    No problem. Let us know if you need advice on interpreting the section offsets/sizes.

Viewing 15 posts - 1 through 15 (of 16 total)
  • You must be logged in to reply to this topic.