Sysprogs forums › Forums › VisualGDB › Problem adding section to linker script
Tagged: Linker
- This topic has 15 replies, 2 voices, and was last updated 8 years ago by
engicoder.
-
AuthorPosts
-
January 31, 2017 at 17:09 #10224
engicoder
ParticipantI 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?
January 31, 2017 at 18:19 #10232engicoder
ParticipantNote: 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.
January 31, 2017 at 18:49 #10235support
KeymasterHi,
Please check the contents of the OpenOCD window for more specific error messages. This should explain why FLASH programming fails.
January 31, 2017 at 19:40 #10238engicoder
ParticipantWhere 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 8 years ago by
engicoder.
January 31, 2017 at 19:53 #10240support
KeymasterHi,
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.
January 31, 2017 at 21:29 #10246engicoder
ParticipantI 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 8 years ago by
engicoder.
January 31, 2017 at 21:45 #10248engicoder
ParticipantI 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 (;;) {} }
February 1, 2017 at 03:33 #10249support
KeymasterHi,
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
February 1, 2017 at 21:02 #10267engicoder
ParticipantThanks 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 8 years ago by
engicoder.
February 1, 2017 at 21:12 #10269support
KeymasterFebruary 1, 2017 at 22:17 #10274engicoder
ParticipantThank 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 8 years ago by
engicoder.
February 2, 2017 at 06:14 #10279support
KeymasterHi,
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.
February 2, 2017 at 15:47 #10288engicoder
ParticipantHow do I generate an elf file with an MSBuild based project, like the ones created by the template?
February 2, 2017 at 20:25 #10290engicoder
ParticipantAh, my mistake, it is generated, it just doesn’t have a .elf extension. The elf file has no extension.
February 3, 2017 at 05:14 #10293support
KeymasterNo problem. Let us know if you need advice on interpreting the section offsets/sizes.
-
This reply was modified 8 years ago by
-
AuthorPosts
- You must be logged in to reply to this topic.