Skip to main content
Associate
April 9, 2025
Solved

Can't flash ELF via UART bootloader, "write address was not acknowledged 0x20000060"

  • April 9, 2025
  • 2 replies
  • 849 views

Hello,

I can flash an HEX file via the CLI but not the ELF one.

More specifically, the flashing seems to succeed (if I reboot the board it works well), it's just at the end that an error message is displayed that I can't understand:

STM32_Programmer_CLI.exe -c port=COM4 br=115200 -d firmware.elf -g
[...]
File segment @0x20000064 is not 8-bytes aligned. It will be aligned to @0x20000060
[...]
Response received from device: NACK
Error: Write address not acknowledged: 0x20000060
Error: failed to download Sector[0]
Error: failed to download the File

aurelienlupin_0-1744212942290.png

Here's my linker script if it cal help to diagnose the issue (I have tried to remove the heap since we don't / must not use it) :

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Memories definition */
MEMORY
{
 CCMSRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 10K
 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
 FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
}

/* Sections */
SECTIONS
{
 /* The startup code into "FLASH" Rom type memory */
 .isr_vector :
 {
 . = ALIGN(4);
 KEEP(*(.isr_vector)) /* Startup code */
 . = ALIGN(4);
 } >FLASH

 /* The program code and other data into "FLASH" Rom type memory */
 .text :
 {
 . = ALIGN(4);
 *(.text) /* .text sections (code) */
 *(.text*) /* .text* sections (code) */
 *(.glue_7) /* glue arm to thumb code */
 *(.glue_7t) /* glue thumb to arm code */
 *(.eh_frame)

 KEEP (*(.init))
 KEEP (*(.fini))

 . = ALIGN(4);
 _etext = .; /* define a global symbols at end of code */
 } >FLASH

 /* Constant data into "FLASH" Rom type memory */
 .rodata :
 {
 . = ALIGN(4);
 *(.rodata) /* .rodata sections (constants, strings, etc.) */
 *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
 . = ALIGN(4);
 } >FLASH

 .ARM.extab (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
 {
 . = ALIGN(4);
 *(.ARM.extab* .gnu.linkonce.armextab.*)
 . = ALIGN(4);
 } >FLASH

 .ARM (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
 {
 . = ALIGN(4);
 __exidx_start = .;
 *(.ARM.exidx*)
 __exidx_end = .;
 . = ALIGN(4);
 } >FLASH

 .preinit_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__preinit_array_start = .);
 KEEP (*(.preinit_array*))
 PROVIDE_HIDDEN (__preinit_array_end = .);
 . = ALIGN(4);
 } >FLASH

 .init_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__init_array_start = .);
 KEEP (*(SORT(.init_array.*)))
 KEEP (*(.init_array*))
 PROVIDE_HIDDEN (__init_array_end = .);
 . = ALIGN(4);
 } >FLASH

 .fini_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__fini_array_start = .);
 KEEP (*(SORT(.fini_array.*)))
 KEEP (*(.fini_array*))
 PROVIDE_HIDDEN (__fini_array_end = .);
 . = ALIGN(4);
 } >FLASH

 /* Used by the startup to initialize data */
 _sidata = LOADADDR(.data);

 /* Initialized data sections into "RAM" Ram type memory */
 .data :
 {
 . = ALIGN(4);
 _sdata = .; /* create a global symbol at data start */
 *(.data) /* .data sections */
 *(.data*) /* .data* sections */
 *(.RamFunc) /* .RamFunc sections */
 *(.RamFunc*) /* .RamFunc* sections */

 . = ALIGN(4);
 _edata = .; /* define a global symbol at data end */

 } >RAM AT> FLASH

 _siccmsram = LOADADDR(.ccmsram);

 /* CCM-SRAM section
 *
 * IMPORTANT NOTE!
 * If initialized variables will be placed in this section,
 * the startup code needs to be modified to copy the init-values.
 */
 .ccmsram :
 {
 . = ALIGN(4);
 _sccmsram = .; /* create a global symbol at ccmsram start */
 *(.ccmsram)
 *(.ccmsram*)

 . = ALIGN(4);
 _eccmsram = .; /* create a global symbol at ccmsram end */
 } >CCMSRAM AT> FLASH

 /* Uninitialized data section into "RAM" Ram type memory */
 . = ALIGN(4);
 .bss :
 {
 /* This is used by the startup in order to initialize the .bss section */
 _sbss = .; /* define a global symbol at bss start */
 __bss_start__ = _sbss;
 *(.bss)
 *(.bss*)
 *(COMMON)

 . = ALIGN(4);
 _ebss = .; /* define a global symbol at bss end */
 __bss_end__ = _ebss;
 } >RAM

 /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
 ._user_heap_stack :
 {
 . = ALIGN(8);
 PROVIDE ( end = . );
 PROVIDE ( _end = . );
 . = . + _Min_Heap_Size;
 . = . + _Min_Stack_Size;
 . = ALIGN(8);
 } >RAM

 /* Create a section in order to identify the end of the main stack */
 ._user_main_stack_end :
 {
 . = ALIGN(8);
 } >RAM

 PROVIDE(_user_main_stack_end = .);

 /* Remove information from the compiler libraries */
 /DISCARD/ :
 {
 libc.a ( * )
 libm.a ( * )
 libgcc.a ( * )
 }

 .ARM.attributes 0 : { *(.ARM.attributes) }
}

 Any idea what's wrong?

Thanks for your help!

Best answer by Tesla DeLorean

RAM is not FLASH

You should double check what's getting into RAM. Review .ELF with objdump or fromelf type dumping tools.

Might be that STM32 Cube Programmer is ignoring NOLOAD / NOBITS type flagging on the sections being exported.

If it's a bug you could report that, or in the mean time you could interstage through a .HEX if that's working

You could use ALIGN(8) if that's what its complaining about, I don't think RAM cares, but the FLASH lines internally might.

2 replies

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
April 9, 2025

RAM is not FLASH

You should double check what's getting into RAM. Review .ELF with objdump or fromelf type dumping tools.

Might be that STM32 Cube Programmer is ignoring NOLOAD / NOBITS type flagging on the sections being exported.

If it's a bug you could report that, or in the mean time you could interstage through a .HEX if that's working

You could use ALIGN(8) if that's what its complaining about, I don't think RAM cares, but the FLASH lines internally might.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Associate
April 10, 2025

Hello,

Thanks for your help. I have managed to fix the issue by indeed adjusting the alignment of the .data section size.

I changed the latest ALIGN to 8 in this section:

 .data :
 {
 . = ALIGN(4);
 _sdata = .; /* create a global symbol at data start */
 *(.data) /* .data sections */
 *(.data*) /* .data* sections */
 *(.RamFunc) /* .RamFunc sections */
 *(.RamFunc*) /* .RamFunc* sections */

 . = ALIGN(8);
 _edata = .; /* define a global symbol at data end */
 } >RAM AT> FLASH

BEFORE the fix:

Sections:
Idx Name Size VMA LMA File off Algn
 0 .isr_vector 000001d8 08000000 08000000 00001000 2**0
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 1 .text 00009cd4 08000200 08000200 00001200 2**6
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 2 .rodata 00000294 08009ed4 08009ed4 0000aed4 2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 3 .ARM.extab 00000000 0800a168 0800a168 0000c064 2**0
 CONTENTS, READONLY
 4 .ARM 00000008 0800a168 0800a168 0000b168 2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 5 .preinit_array 00000000 0800a170 0800a170 0000c064 2**0
 CONTENTS, ALLOC, LOAD, DATA
 6 .init_array 00000004 0800a170 0800a170 0000b170 2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 7 .fini_array 00000004 0800a174 0800a174 0000b174 2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 8 .data 00000064 20000000 0800a178 0000c000 2**2
 CONTENTS, ALLOC, LOAD, DATA
 9 .ccmsram 00000000 10000000 10000000 0000c064 2**0
 CONTENTS
 10 .bss 00000c60 20000064 20000064 0000c064 2**2
 ALLOC

AFTER the fix:

Sections:
Idx Name Size VMA LMA File off Algn
 0 .isr_vector 000001d8 08000000 08000000 00001000 2**0
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 1 .text 00009cd4 08000200 08000200 00001200 2**6
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 2 .rodata 00000294 08009ed4 08009ed4 0000aed4 2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 3 .ARM.extab 00000000 0800a168 0800a168 0000c068 2**0
 CONTENTS, READONLY
 4 .ARM 00000008 0800a168 0800a168 0000b168 2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 5 .preinit_array 00000000 0800a170 0800a170 0000c068 2**0
 CONTENTS, ALLOC, LOAD, DATA
 6 .init_array 00000004 0800a170 0800a170 0000b170 2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 7 .fini_array 00000004 0800a174 0800a174 0000b174 2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 8 .data 00000068 20000000 0800a178 0000c000 2**2
 CONTENTS, ALLOC, LOAD, DATA
 9 .ccmsram 00000000 10000000 10000000 0000c068 2**0
 CONTENTS
 10 .bss 00000c60 20000068 20000068 0000c068 2**2
 ALLOC

And now it works well :smiling_face_with_smiling_eyes:

Pavel A.
Super User
April 11, 2025

The offending address was 20000064 and in "working" variant changed to something aligned on 8. From your section listings, it is something located between .data and .bss (which has not changed their addresses). But the listings do not show anything between .data and .bss.  So it looks to me like a bug in CubeProgrammer, it passes to the target weird bits of the ELF that should be discarded.