2025-02-28 7:10 AM
I created an external flash STLDR file for my board, with STM32H750VB chip and W25Q64 QSPI FLASH. After copying the STLDR file to the cubeprographer directory, it can perform normal external flash read/write and sector erase functions. However, when selecting full chip erase, the cubeprographer prompts me "please select external loader before performing external full chip erase". But I am sure that my code contains the correct int MassErase (void) function, and I used the readelf command in Ubuntu environment to read the STLDR file I created, which also includes the MassErase function. But it seems that this function cannot be correctly detected by the cubeprographer. How can I locate the cause and solve this problem?
Wishing you peace
Solved! Go to Solution.
2025-03-05 5:58 PM
The .STLDR you attached looks reasonable enough
Not sure the linker script is entirely correct. It describes the FLASH at 0x08000000 and the StorageInfo structure is placed there.
2025-02-28 10:11 AM
>>How can I locate the cause and solve this problem?
Hard to know with the detail presented, you look to be looking in the right places.
Perhaps attach the .ELF / .STLDR, or a structure dump via OBJDUMP, OBJCOPY, or whatever.
Perhaps the address or attributes of the function? The case?
Perhaps compare the structure of how your's dumps vis-a-v all the other examples in the ExternalLoader subdirectory.
Screen shots of error, showing loader that's loaded, the Log at Verbosity Level 3..
2025-03-01 6:46 AM - edited 2025-03-01 7:03 AM
thank you for your replay!
this is my Screen shots and error message
This stldr file can help me perform external flash read, write, and fast erase functions, but full chip erase cannot be used.
I saved the output of objdump and readelf commands in CMDobjdump.txt and CMDreadlef.txt files. It can be found that the masserase function exists in both files. However, when executing external full chip erase, the error shown in the figure above is always prompted. I put part of these two files here for easy display, as well as my cubeide project. By the way, the cubeide I use is the Linux version, and the development environment is ubuntu22.04.5LTS.
This problem has bothered me for a week
Thank you again for your reply
this is source code screen shots
about of the cubeprogrammer
about of the cubeide
2025-03-01 7:59 AM
I'll take a look. Make sure the most current version of your loader is in the STM32 Cube Programmer External Loader directory
This is the one I built as a constrast
2025-03-02 4:14 AM - edited 2025-03-02 4:37 AM
I have used the stldr file you provided, It can perform left and right external flash operations normally in ubuntu environment without any errors, and I sent an email to ask if I could donate to get the source code, remember?^_^
Last night, I used the stldr file I made to do some other tests and found some new problems. The same stldr file can be used in cubeprogrammer under windows environment, all functions are normal, but in ubuntu, cubeprogrammer only reports an error for full external flash erase. However, in ubuntu command line, using the command "STM32_Programmer_CLI -c port=SWD freq=4000 -el /home/user/keanlee/stm32/hope/hope_h750_w25q64jv_stldr/hope_h750_w25q64jv_stldr/Debug/hope_h750_w25q64jv_stldr.stldr -e all", the mass erase function can be executed normally to complete the full chip erase. I don't know why this happens. I hope to get some supplements and solutions in this regard. Thank you again for your reply, which is very important to me.
In the Ubuntu CubeIDE environment, I set up the CubeIDE project as follows:
Is it possible that these settings may cause errors?
2025-03-05 4:47 PM
It has been a few days since we last discussed this issue. May I ask if there are any results yet?
Best wishes
2025-03-05 5:58 PM
The .STLDR you attached looks reasonable enough
Not sure the linker script is entirely correct. It describes the FLASH at 0x08000000 and the StorageInfo structure is placed there.
2025-03-05 6:42 PM
Thank you very much for your reply. I have modified the linker script and removed the 0x08000000 flash address. After recompiling, everything is working properly. I am really excited and thank you again for your help Because I have never used buymeacoffee before, I am researching how to use it. Please enjoy your coffee later, that is my agreement! Best wishes!
2025-03-05 7:08 PM
Oh my god, I made a *** mistake in the test just now. I erased the on-chip flash memory instead of the external flash memory, and the full chip erase of the external flash memory still reported an error: Please select external loader before performing external full chip erase, I made the following modifications in the linker script, but it still doesn't work. Do you have any suggestions? I'm laughing at my own foolishness!
/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : STM32CubeIDE
**
** Abstract : Linker script for STM32H7 series
** 128Kbytes FLASH and 1056Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** Copyright (c) 2024 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Generate 2 segment for loader code and device info */
PHDRS {Loader PT_LOAD; SgInfo PT_LOAD ; }
/* Specify the memory areas */
MEMORY
{
RAM_D1 (xrw) : ORIGIN = 0x24000004, LENGTH = 512K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >RAM_D1 :Loader
/* The program code and other data goes into FLASH */
.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 */
} >RAM_D1 :Loader
.Dev_info :
{
KEEP(*Dev_Inf.o ( .rodata ))
} >RAM_D1 :SgInfo
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >RAM_D1 :Loader
.ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >RAM_D1 :Loader
.ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >RAM_D1 :Loader
.preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >RAM_D1 :Loader
.init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >RAM_D1 :Loader
.fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >RAM_D1 :Loader
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.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_D1 :Loader
/* Uninitialized data section */
. = 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_D1 :Loader
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM_D1 :Loader
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
2025-06-27 11:09 AM
Win11 laptop, Micron MT25QL01GBBB on NUCLEO-U5A5ZJ-Q board.
STM32CubeProgrammer v2.18.0.
Loads program (into internal flash) and GUI (TouchGFX) assets into the external flash. Can "Erase selected sectors" but displays "Please select external loader before performing external full chip erase". Using v1.16.0 of STM32CubeIDE. Tried:
"int __attribute__((used)) MassErase(void)"
... no joy.
The MassErase present in the ELF, the name is present in the .symtab with proper address (I guess that's how STM32CubeProgrammer finds the entry addresses).
IMHO the message really means that STM32CubeProgrammer cannot find the address, see the traces below, it really does not attempt to do anything:
Successful sector erase:
13:22:47:081 : r ap 0 @0x0BF99EFE 0x00000001 bytes Data 0xFFFFFF92
13:22:47:084 : Flash sector erase ...
13:22:47:085 : r ap 0 @0x40022040 0x00000004 bytes Data 0x1FEFF8AA
13:22:47:085 : Swap Bank enabled: sector indexes swapped
13:22:47:090 : r ap 0 @0x40022040 0x00000004 bytes Data 0x1FEFF8AA
13:22:47:090 : Flash erase...
13:22:47:093 : halt ap 0
13:22:47:093 : w ap 0 reg 15 PC (0x20000000)
13:22:47:093 : w ap 0 reg 17 MSP (0x20000500)
13:22:47:093 : w ap 0 reg 16 xPSR (0x01000000)
13:22:47:096 : w ap 0 @0x2001C720 : 0x00000200 bytes, Data 0x00000000...
13:22:47:097 : w ap 0 @0x20000000 : 0x00000004 bytes, Data 0x0000BE00...
13:22:47:465 : w ap 0 @0x20000004 : 0x0001C2F8 bytes, Data 0x000082B4...
13:22:47:465 : Init flashloader...
13:22:47:465 : halt ap 0
13:22:47:465 : w ap 0 reg 0 R0 0x00000001
13:22:47:465 : w ap 0 reg 1 R1 0x00000000
13:22:47:465 : w ap 0 reg 2 R2 0x00000000
13:22:47:465 : w ap 0 reg 3 R3 0x00000000
13:22:47:465 : w ap 0 reg 4 R4 0x00000000
13:22:47:465 : w ap 0 reg 5 R5 0x00000000
13:22:47:466 : w ap 0 reg 6 R6 0x00000000
13:22:47:466 : w ap 0 reg 7 R7 0x00000000
13:22:47:466 : w ap 0 reg 8 R8 0x00000000
13:22:47:466 : w ap 0 reg 9 R9 0x00000000
13:22:47:466 : w ap 0 reg 10 R10 0x00000000
13:22:47:466 : w ap 0 reg 11 R11 0x00000000
13:22:47:466 : w ap 0 reg 12 R12 0x00000000
13:22:47:466 : w ap 0 reg 13 SP 0x00000000
13:22:47:466 : w ap 0 reg 14 LR 0x20000001
13:22:47:466 : w ap 0 reg 15 PC 0x20008349
13:22:47:466 : w ap 0 reg 16 xPSR 0x01000000
13:22:47:466 : w ap 0 reg 17 MSP 0x2001C6F8
13:22:47:466 : w ap 0 reg 18 PSP 0x00000000
13:22:47:466 : run ap 0
13:22:47:798 : halt ap 0
13:22:47:798 : r ap 0 reg 0 R0 0x00000001
13:22:47:798 : Loader sector erase...
13:22:47:799 : w ap 0 reg 0 R0 0x77CF0000
13:22:47:800 : w ap 0 reg 1 R1 0x77CF0000
13:22:47:800 : w ap 0 reg 2 R2 0x00000002
13:22:47:801 : w ap 0 reg 3 R3 0x00000000
13:22:47:801 : w ap 0 reg 4 R4 0x00000000
13:22:47:801 : w ap 0 reg 5 R5 0x00000000
13:22:47:801 : w ap 0 reg 6 R6 0x00000000
13:22:47:801 : w ap 0 reg 7 R7 0x00000000
13:22:47:801 : w ap 0 reg 8 R8 0x00000000
13:22:47:801 : w ap 0 reg 9 R9 0x00000000
13:22:47:802 : w ap 0 reg 10 R10 0x00000000
13:22:47:802 : w ap 0 reg 11 R11 0x00000000
13:22:47:802 : w ap 0 reg 12 R12 0x00000000
13:22:47:804 : w ap 0 reg 13 SP 0x00000000
13:22:47:804 : w ap 0 reg 14 LR 0x20000001
13:22:47:805 : w ap 0 reg 15 PC 0x2000847D
13:22:47:805 : w ap 0 reg 16 xPSR 0x01000000
13:22:47:806 : w ap 0 reg 17 MSP 0x2001C6F8
13:22:47:807 : w ap 0 reg 18 PSP 0x00000000
13:22:47:807 : run ap 0
13:22:47:821 : halt ap 0
13:22:47:821 : r ap 0 reg 0 R0 0x00000001
13:22:47:821 : Existing specified sectors are erased successfully Protected sectors are not erased
Unsuccessful Mass Erase:
14:05:29:441 : UPLOADING ...
14:05:29:441 : Size : 1024 Bytes
14:05:29:441 : Address : 0x8000000
14:05:29:441 : Read progress:
14:05:29:442 : Reading data...
14:05:29:444 : r ap 0 @0x40022040 0x00000004 bytes Data 0x1FEFF8AA
14:05:29:444 : r ap 0 @0x40022050 0x00000004 bytes Data 0x00000000
14:05:29:444 : r ap 0 @0x40022040 0x00000004 bytes Data 0x1FEFF8AA
14:05:29:445 : r ap 0 @0x08000000 0x00000400 bytes Data 0x20270000
14:05:29:445 : Data read successfully
14:05:29:445 : Time elapsed during the read operation is: 00:00:00.004