2023-06-22 08:10 AM
I have a project in which I have a specific flash section dedicated to device calibrations (.factory_variables). This allows me to to create a full_program.elf file and an update.elf file with different linkers.
Having to maintain two linkers is not efficient (compile time, binary management ,etc). I am trying to do a single compilation and then use arm-none-eabi-objcopy.exe to remove the calibration section. However when trying to update with the update.elf and stm32cubeprogrammer the following error appears:
The reason for this error is that stm32cubeprogrammer incorrectly detects the .elf headers with size = 0.
I am currently creating the update with the following command:
cp full_program.elf update.elf
arm-none-eabi-objcopy.exe --remove-section .factory_variables .\update.elf
Using readelf tool I can see that update.elf is correctly created. Section 3 is "emptied" and leaved with 0 space
ORIGINAL FILE:
readelf --segments .\2023-05-30-1.0.1-FULL.elf
Elf file type is EXEC (Executable file)
Entry point 0x8022d75
There are 10 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x08000000 0x08000000 0x001f8 0x001f8 R 0x10000
LOAD 0x018000 0x08008000 0x08008000 0x02d0d 0x02d0d RW 0x10000
LOAD 0x020000 0x08010000 0x08010000 0x02d0c 0x02d0c RW 0x10000
LOAD 0x032000 0x20072000 0x08018000 0x00060 0x00060 RW 0x10000
LOAD 0x040000 0x08020000 0x08020000 0x175420 0x175420 RWE 0x10000
LOAD 0x1c0000 0x20000000 0x08195420 0x004c8 0x2db48 RW 0x10000
LOAD 0x00db48 0x2002db48 0x081958e8 0x00000 0x00600 RW 0x10000
LOAD 0x1ce000 0x2007e000 0x081958e8 0x00390 0x00390 RW 0x10000
LOAD 0x1d4000 0x20074000 0x20074000 0x02d0c 0x02d0c RW 0x10000
LOAD 0x000000 0xc0000000 0xc0000000 0x00000 0x177000 RW 0x10000
Section to Segment mapping:
Segment Sections...
00 .isr_vector
01 .data_calibration
02 .data_calibration_copy
03 .factory_variables
04 .text .rodata FontFlashSection FontSearchFlashSection ExtFlashSection TextFlashSection .ARM .init_array .fini_array
05 .data .bss
06 ._user_heap_stack
07 .rte_variables
08 .config_ram
09 TouchGFX_Framebuffer
UPDATE.ELF
readelf --segments .\a.elf
Elf file type is EXEC (Executable file)
Entry point 0x8022d75
There are 10 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x08000000 0x08000000 0x001f8 0x001f8 R 0x10000
LOAD 0x018000 0x08008000 0x08008000 0x02d0d 0x02d0d RW 0x10000
LOAD 0x020000 0x08010000 0x08010000 0x02d0c 0x02d0c RW 0x10000
LOAD 0x000174 0x20072000 0x00000000 0x00000 0x00000 RW 0x10000
LOAD 0x030000 0x08020000 0x08020000 0x175420 0x175420 RWE 0x10000
LOAD 0x1b0000 0x20000000 0x08195420 0x2e4d8 0x2e4d8 RW 0x10000
LOAD 0x1edb48 0x2002db48 0x081958e8 0x2e010 0x2e010 RW 0x10000
LOAD 0x24e000 0x2007e000 0x081958e8 0x2e010 0x2e010 RW 0x10000
LOAD 0x284000 0x20074000 0x20074000 0x02d0c 0x02d0c RW 0x10000
LOAD 0x000000 0xc0000000 0xc0000000 0x00000 0x177000 RW 0x10000
Section to Segment mapping:
Segment Sections...
00 .isr_vector
01 .data_calibration
02 .data_calibration_copy
03
04 .text .rodata FontFlashSection FontSearchFlashSection ExtFlashSection TextFlashSection .ARM .preinit_array .init_array .fini_array
05 .data .bss ._user_heap_stack
06 ._user_heap_stack
07 .rte_variables
08 .config_ram
09 TouchGFX_Framebuffer
How can I remove this 0 size segment or remove the .factory_variables from the ELF file to allow updating without overwritting the configuration?
Solved! Go to Solution.
2023-07-21 05:11 AM
Just to sumarize my solution in case other people find in a similar situation. I added the .srec file as the output of the compilation process. I then made a small script (in my case in python) that parses the addresses of the .srec file and removes the desired adress range. This allows simple integration into a CI/CD
2023-06-22 10:41 AM - edited 2023-06-22 10:42 AM
Note that your section .data_calibration_copy is located in SRAM at 0x20072000 - but is stored in flash at 0x08018000. So I guess it is defined like the "initialized RAM" section (.data).
If so, it's not clear what you're trying to do by removing the section. The initialization code still will copy something from the flash to RAM, but it will be random junk?
2023-06-22 01:56 PM
Or use structure pointers and don't have it in the object / binary file at all? And outside the scope of the space described to the linker, or in a NOLOAD / NOINIT type section.
Have the main line code look and check the integrity of the data in the calibration section, and either write or use defaults. Be able to write the calibration data as a function of the primary application if it needs changing, or test station programming.
2023-06-23 05:35 AM - edited 2023-06-23 05:38 AM
I know the names are misleading but I am removing the section .factory_variables no the .data_calibration_copy.
Regarding
@Pavel A. wrote:Note that your section .data_calibration_copy is located in SRAM at 0x20072000 - but is stored in flash at 0x08018000. So I guess it is defined like the "initialized RAM" section (.data).
If so, it's not clear what you're trying to do by removing the section. The initialization code still will copy something from the flash to RAM, but it will be random junk?
If a device has never been flashed it will NOT work as it will copy random junk. However, if a device was already configured it will copy the values that were already present.
What I am trying to achieve is to have a simple way to obtain a binary-B from a binary-A that allows me to update all the the flash in the device with the exception of a defined range of flash.
2023-06-23 09:05 AM - edited 2023-06-23 09:09 AM
Which stm32? What is the size of flash sector? CubeProgrammer does not know how to update partial sectors without erasing the whole sector first. Especially in the middle of the image.
Maybe you have found a bug in either tool (objcopy or Cube Programmer), then try to convert the elf to hex, with complete removal of the offending address range.
2023-06-26 03:22 AM
I am not trying to partially erase a sector. I am trying to partially erase and update the flash memory of the STM32F7. Each section in my linker is assigned to N flash sectors. Thus when erasing a section from the binary it is only affecting specific flash sectors which are controlled.
2023-06-26 06:35 AM - edited 2023-06-26 06:36 AM
OK, understood. So maybe this is a CubeProgrammer bug.
2023-07-21 05:11 AM
Just to sumarize my solution in case other people find in a similar situation. I added the .srec file as the output of the compilation process. I then made a small script (in my case in python) that parses the addresses of the .srec file and removes the desired adress range. This allows simple integration into a CI/CD