Skip to main content
Visitor II
December 18, 2024
Question

External Loader - stldr ERROR PARSING FAIL

  • December 18, 2024
  • 4 replies
  • 3341 views

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!

    This topic has been closed for replies.

    4 replies

    Graduate II
    December 18, 2024

    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

    JOHNROSEAuthor
    Visitor II
    December 19, 2024

    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) }
    }
    
    

     

    JOHNROSEAuthor
    Visitor II
    December 19, 2024

    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?

    Graduate II
    December 19, 2024

    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.

    JOHNROSEAuthor
    Visitor II
    December 19, 2024

    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?

    Graduate II
    December 19, 2024

    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
    ...

     

    JOHNROSEAuthor
    Visitor II
    December 20, 2024

    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?