2025-04-09 8:39 AM
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
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!
Solved! Go to Solution.
2025-04-09 9:29 AM
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.
2025-04-09 9:29 AM
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.
2025-04-10 9:20 AM
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:
2025-04-10 7:04 PM - edited 2025-04-10 7:10 PM
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.