Sysprogs forums › Forums › VisualGDB › Problem adding section to linker script
Tagged: Linker
- This topic has 15 replies, 2 voices, and was last updated 7 years, 10 months ago by engicoder.
-
AuthorPosts
-
January 31, 2017 at 17:09 #10224engicoderParticipant
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?
January 31, 2017 at 18:19 #10232engicoderParticipantNote: 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 #10235supportKeymasterHi,
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 #10238engicoderParticipantWhere 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.
January 31, 2017 at 19:53 #10240supportKeymasterHi,
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 #10246engicoderParticipantI 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.
January 31, 2017 at 21:45 #10248engicoderParticipantI 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 #10249supportKeymasterHi,
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 #10267engicoderParticipantThanks 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.
February 1, 2017 at 21:12 #10269supportKeymasterFebruary 1, 2017 at 22:17 #10274engicoderParticipantThank 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.
February 2, 2017 at 06:14 #10279supportKeymasterHi,
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 #10288engicoderParticipantHow do I generate an elf file with an MSBuild based project, like the ones created by the template?
February 2, 2017 at 20:25 #10290engicoderParticipantAh, 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 #10293supportKeymasterNo problem. Let us know if you need advice on interpreting the section offsets/sizes.
-
AuthorPosts
- You must be logged in to reply to this topic.