cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeProgrammer v2.21 breaks External Loader

JFisher-Legato
Associate II

Hello,

Our project is based on the STM32WBA65MI, and we have an external flash chip on the board that we use STM32CubeProgrammer w/a custom external loader to program. This worked well with STM32CubeProgrammer v2.20, but when I updated to STM32CubeProgrammer v2.21, suddenly I was unable to connect to the board using the external loader.

This happens as soon as I select the external loader and

JFisherLegato_0-1764769774872.png

If I select verbosity level 3, this is what I see:

08:50:10:520 : Selected loader: C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin/ExternalLoader/MX25R6435_STM32WBA65-LEGATO.stldr
08:50:10:520 : Error: Flash loader C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin/ExternalLoader/MX25R6435_STM32WBA65-LEGATO.stldr cannot be loaded.

Here's the StorageInfo:

struct StorageInfo __attribute__((section(".Dev_Info"))) const StorageInfo  = {
        "MX25R6435F_Legato",       // Device Name + version number
        SPI_FLASH,                 // Device Type
        0x00000000,                // Device Start Address
        0x800000,                  // Device Size in Bytes
        0x1000,                    // Programming Page Size
        0xFF,                      // Initial Content of Erased Memory

        // Specify Size and Address of Sectors (view example below)
        {
                { 0x800,    // Sector Numbers,
                  0x1000 }, // Sector Size

                { 0x00000000, 0x00000000 }
        }
};

I'm running Windows 11 Pro 25H2 if that makes a difference. The flash part we're writing to is the MX25R6435F.

My linker script is as follows:

/* Entry Point */
ENTRY(Init)

/* Generate 2 segment for Loader code and device info */
PHDRS {Loader PT_LOAD ; SgInfo PT_LOAD ; }

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* 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
{
  RAM_D1    (xrw)    : ORIGIN = 0x20000004,   LENGTH = 512K-4
}

/* Sections */
SECTIONS
{

  .isr_vector :
  {
  	. = . + 0x1FC; /* ISR vector offset */
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >RAM_D1 :Loader

  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*)  } >RAM_D1

  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >RAM_D1 :Loader

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }  >RAM_D1 :Loader

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  }  >RAM_D1 :Loader

  .fini_array :
  {
    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 into "RAM" Ram type memory */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* 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
  
  /* The program code and other data into RAM 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))
	KEEP (*Loader_Src.o ( .text* ))
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >RAM_D1 : Loader
  
  .Dev_Info :
  {
  	__Dev_Info_START = .;
  	*(.Dev_Info*)
  	KEEP(*(.Dev_Info))
  	__Dev_Info_END = .;
  } >RAM_D1 :SgInfo
  
  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >RAM_D1 :Loader
  
  /* 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_D1 :Loader

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

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

For what it's worth, I also set up the Init() function to simply return 0, but CubeProgrammer still threw the same error.

Thank you,

Jonathan

0 REPLIES 0