cancel
Showing results for 
Search instead for 
Did you mean: 

External Loader - stldr ERROR PARSING FAIL

JOHNROSE
Associate II

Hello,

I am attempting to make an external loader for a QuadSPI flash S25FL256SAGMFI000 using the STM32F769 and STM32CubeIDE.

I followed this tutorial: https://www.youtube.com/playlist?list=PLnMKNibPkDnHIrq5BICcFhLsmJFI_ytvE

I was able to run the code to the end of the while loop like described in the video and successfully wrote/read to memory at address 0x90000000.

I am able to generate an stldr file, but when I try to load it in the CubeProgrammer the file displays the error "ERROR PARSING FAIL". The programmer also does not display the right start address, the memory size, page size, or type, which leads me to believe there is a problem with the Dev_Inf.c file.

PARSING FAIL.jpg

Has anyone seen this error before and can steer me in the right direction of where to look to correct it? I have attached the Dev_Inf.c, Loader_Src.c, and quadspi.c files. Please let me know what other files I can attach for review.

 

Thank you!

12 REPLIES 12

Start with the .ELF / .STLDR, inspect with tools like OBJDUMP, FROMELF or OBJCOPY, try to understand how the form differs from those that load/work properly.

Make sure it's exporting the expected functions, and builds for RAM at 0x20000004

Check also the Linker Script, .LD

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

Hi Tesla - I'm a bit new to this and am not sure how to use the tools you mentioned to view the .elf, .stldr files. Are there some resources I could be looking at for these?

I am not able to attach the linker file, but here is the code:

/*
*****************************************************************************
**  File        : linker.ld
**
**                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
**
*****************************************************************************
*/

/* 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) + LENGTH(RAM);    /* 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 */

/* Specify the memory areas */
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000004, LENGTH = 8M
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  
  .isr_vector :
  {
  	. = . + 0x1FC;
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >RAM :Loader
  
  

  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >RAM
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >RAM :Loader

  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >RAM :Loader
  
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >RAM :Loader
  
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >RAM :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 */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM :Loader

  
  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _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 :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 :Loader
  
    .Dev_info :
  {
	KEEP(*Dev_Inf.o ( .rodata* ))
  } :SgInfo
  
  
  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >RAM :Loader
  
  
  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(4);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(4);
  } >RAM :Loader

  


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

 

JOHNROSE
Associate II

I did find this github for the exact quadspi I am using:

https://github.com/cturvey/stm32extldr/blob/main/h7_s25hl512/CLIVEONE-S25FL512S_STM32H7XX-PB2-PB6-PD11-PD12-PE2-PD13.stldr

Through this post on the ST forums:

https://community.st.com/t5/stm32cubeprogrammer-mcus/qspi-external-loader-for-stm32h750vbt6/td-p/145016

Is there a way I could modify this file to work with the F7?

The design of the cores and peripherals doesn't exactly make these things portable at a binary level. I'd have to back-port the SPANSION support into my build.

 

The .ELF object describes several sections that pull into memory, with symbols identifying the entry points, the data/size of StorageInfo typically driving the user interface in the External Loader menu, but it might be looking for Init, Write, SectorErase, etc.

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

Is there anything I can see in the .ELF that would indicate that it isn't loading the information from the Dev_Inf.c/h files?

Well dumping out the content of the data records describing StorageInfo should allow you to confirm the data in Dev_Inf.c is correctly reflected in the structure.

If you look at things that are working successfully, you can contrast that to the one that's not viable.

Is this really how you have the part wired? Is that viable? Have you programmed the part from application space?

PF10 CLK

PB10 NCS BK1

PF8 D0 BK1

PF9 D1 BK1

PC1 NCS BK2

PH2 D0 BK2

PH3 D1 BK2

fromelf.exe -csd CLIVEONE-W25Q64_STM32F4XX-PF10-PB6-PF8-PF9-PF7-PF6.stldr
========================================================================

** ELF Header Information

    File Name: CLIVEONE-W25Q64_STM32F4XX-PF10-PB6-PF8-PF9-PF7-PF6.stldr

    Machine class: ELFCLASS32 (32-bit)
    Data encoding: ELFDATA2LSB (Little endian)
    Header version: EV_CURRENT (Current version)
    Operating System ABI: none
    ABI Version: 0
    File Type: ET_EXEC (Executable) (2)
    Machine: EM_ARM (ARM)

    Image Entry point: 0x20000895
    Flags: EF_ARM_HASENTRY + EF_ARM_ABI_FLOAT_SOFT (0x05000202)

    ARM ELF revision: 5 (ABI version 2)

    Conforms to Soft float procedure-call standard

    Header size: 52 bytes (0x34)
    Program header entry size: 32 bytes (0x20)
    Section header entry size: 40 bytes (0x28)

    Program header entries: 2
    Section header entries: 10

    Program header offset: 6252 (0x0000186c)
    Section header offset: 6316 (0x000018ac)

    Section header string table index: 7
========================================================================
** Program header #0 (PT_LOAD) [PF_R]
    Size : 200 bytes
    Virtual address: 0x00000000 (Alignment 32768)
====================================
** Program header #1 (PT_LOAD) [PF_X + PF_W + PF_R]
    Size : 5800 bytes (5708 bytes in file)
    Virtual address: 0x20000004 (Alignment 32768)
========================================================================

** Section #1 '.info' (SHT_PROGBITS) [SHF_ALLOC]
    Size   : 200 bytes (alignment 4)
    Address: 0x00000000

    0x000000:   43 4c 49 56 45 4f 4e 45 2d 57 32 35 51 36 34 5f    CLIVEONE-W25Q64_
    0x000010:   53 54 4d 33 32 46 34 58 58 2d 50 46 31 30 2d 50    STM32F4XX-PF10-P
    0x000020:   42 36 2d 50 46 38 2d 50 46 39 2d 50 46 37 2d 50    B6-PF8-PF9-PF7-P
    0x000030:   46 36 00 73 6f 75 72 63 65 72 33 32 40 67 6d 61    F6.sourcer32@gma
    0x000040:   69 6c 2e 63 6f 6d 00 00 00 00 00 00 00 00 00 00    il.com..........
    0x000050:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0x000060:   00 00 00 00 07 00 00 00 00 00 00 90 00 00 80 00    ................
    0x000070:   00 01 00 00 ff 00 00 00 80 00 00 00 00 00 01 00    ................
    0x000080:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0x000090:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0x0000a0:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0x0000b0:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    0x0000c0:   00 00 00 00 00 00 00 00                            ........

** Section #2 '.prog' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    Size   : 5680 bytes (alignment 4)
    Address: 0x20000004
...
** Section #8 '.symtab' (SHT_SYMTAB)
    Size   : 128 bytes (alignment 4)
    String table #9 '.strtab'
    Last local symbol no. 0

    Symbol table .symtab (7 symbols, 0 local)

      #  Symbol Name                Value      Bind  Sec  Type  Vis  Size
    ========================================================================

      1  StorageInfo                0x00000000   Gb    1  Data  De   0xc8
      2  Init                       0x20000895   Gb    2  Code  De   0x1d0
      3  DeInit                     0x20000a65   Gb    2  Code  De   0x4
      4  Write                      0x20000b69   Gb    2  Code  De   0xa4
      5  Read                       0x20000af5   Gb    2  Code  De   0x74
      6  MassErase                  0x20000ae5   Gb    2  Code  De   0xe
      7  SectorErase                0x20000a69   Gb    2  Code  De   0x7c
...

 

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

The pinout does work, I am using the STM32F769IIT6. I am able to execute example code in the debug mode to erase, write and read contents or the flash successfully. I will have to look at the .elf file. I need to download KEIL MDK to get the fromelf.exe program.

 

Just an observation; the contents for the Dev_Inf .cyclo and .su files in the release folder are empty. Looking at other files, this doesn't seem normal. Could that be part of the problem?

In GNU objdump/objcopy should have some similar functionality, as I recall.

You could perhaps attach the offending .STLDR, probably need to be in a .7z or something.

I could use the memory in 1 or 2-bit modes, seems an odd configuration across two banks TBH

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

Attached .stldr for review. We are using 1 bit mode for now for testing - do you think that creates a problem?