cancel
Showing results for 
Search instead for 
Did you mean: 

How to make update binary that does not write in some parts of the flash?

RMoli.3
Associate III

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. 

  • full_program.elf file: used in production
  • update.elf: used in to update

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:

RMoli3_0-1687446118427.png

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? 

1 ACCEPTED SOLUTION

Accepted Solutions
RMoli.3
Associate III

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 

View solution in original post

7 REPLIES 7
Pavel A.
Evangelist III

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?

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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.  

Pavel A.
Evangelist III

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.

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.

Pavel A.
Evangelist III

OK, understood. So maybe this is a CubeProgrammer bug.

RMoli.3
Associate III

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