Skip to main content
nikof
Associate II
July 6, 2022
Solved

External loader fails to download

  • July 6, 2022
  • 15 replies
  • 6267 views

Hi all,

I'm trying to put some TouchGFX data (images, text, ...) in an external flash (S25FL128L) on a custom board with STM32H7B0VB mcu. I'm using the octo-spi peripheral as quad-spi.

So, I followed the guide to make an external loader and I did it. It seems to work properly: if I load the .stdlr file in the STM32CubeProgrammer I can read, write, erase sector and mass erase the external flash.

Also, if I try to debug (STM32CubeIDE) a project using the loader without putting elements into external flash all works well and I can see all the memory locations.

The ploblem occur whe I try to put somenthing inside the external flash. I do that in the linker script with TouchGFX sections: IntFlashSection and TextFlashSection. See the script below:

/* Entry Point */
ENTRY(Reset_Handler)
 
/* Highest address of the user mode stack */
_estack = 0x20020000; /* 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
{
 FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
 AXI_SRAM (xrw) : ORIGIN = 0x24000000, LENGTH = 1024K
 AHB_SRAM (xrw) : ORIGIN = 0x30000000, LENGTH = 128K
 OCTOSPI (r)	 : ORIGIN = 0x90000000, LENGTH = 16M
}
 
/* Define output sections */
SECTIONS
{
 /* The startup code goes first into FLASH */
 .isr_vector :
 {
 . = ALIGN(4);
 KEEP(*(.isr_vector)) /* Startup code */
 . = ALIGN(4);
 } >FLASH
 
 /* 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 */
 } >FLASH
 
 /* Constant data goes into FLASH */
 .rodata :
 {
 . = ALIGN(4);
 *(.rodata) /* .rodata sections (constants, strings, etc.) */
 *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
 . = ALIGN(4);
 } >FLASH
 
 .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
 .ARM : {
 __exidx_start = .;
 *(.ARM.exidx*)
 __exidx_end = .;
 } >FLASH
 
 .preinit_array :
 {
 PROVIDE_HIDDEN (__preinit_array_start = .);
 KEEP (*(.preinit_array*))
 PROVIDE_HIDDEN (__preinit_array_end = .);
 } >FLASH
 .init_array :
 {
 PROVIDE_HIDDEN (__init_array_start = .);
 KEEP (*(SORT(.init_array.*)))
 KEEP (*(.init_array*))
 PROVIDE_HIDDEN (__init_array_end = .);
 } >FLASH
 .fini_array :
 {
 PROVIDE_HIDDEN (__fini_array_start = .);
 KEEP (*(SORT(.fini_array.*)))
 KEEP (*(.fini_array*))
 PROVIDE_HIDDEN (__fini_array_end = .);
 } >FLASH
 
 /* 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 AT> FLASH
 
 /* 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
 
 /* 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
 
 /* Remove information from the standard libraries */
 /DISCARD/ :
 {
 libc.a ( * )
 libm.a ( * )
 libgcc.a ( * )
 }
 
 .ARM.attributes 0 : { *(.ARM.attributes) }
 
 IntFlashSection :
 	{
 		*(IntFlashSection IntFlashSection.*)
 		*(.gnu.linkonce.r.*)
 		. = ALIGN(0x4);
 	} >OCTOSPI
 
 TextFlashSection :
 	{
 		*(TextFlashSection TextFlashSection.*)
 		*(.gnu.linkonce.r.*)
 		. = ALIGN(0x4);
 	} >OCTOSPI
 
}

The output of the console when I try to Debug or Run with this linker script is:

STMicroelectronics ST-LINK GDB server. Version 6.1.0
Copyright (c) 2022, STMicroelectronics. All rights reserved.
 
Starting server with the following options:
 Persistent Mode : Disabled
 Logging Level : 1
 Listen Port Number : 61234
 Status Refresh Delay : 15s
 Verbose Mode : Disabled
 SWD Debug : Enabled
 InitWhile : Enabled
 
Waiting for debugger connection...
Debugger connected
Waiting for debugger connection...
Debugger connected
Waiting for debugger connection...
 -------------------------------------------------------------------
 STM32CubeProgrammer v2.10.0 
 -------------------------------------------------------------------
 
 
 
Log output file: c:\users\niko~1.fio\appdata\local\temp\stm32cubeprogrammer_a14888.log
ST-LINK SN : 34FF74065250343847111043
ST-LINK FW : V2J39S7
Board : --
Voltage : 3.23V
SWD freq : 4000 KHz
Connect mode: Under Reset
Reset mode : Hardware reset
Device ID : 0x480
Revision ID : Rev Z
Device name : STM32H7A/B
Flash size : 128 KBytes
Device type : MCU
Device CPU : Cortex-M7
BL Version : 0x90
 
 
 
Memory Programming ...
Opening and parsing file: st-link_gdb_server_a14888.srec
 File : st-link_gdb_server_a14888.srec
 Size : 694.94 KB 
 Address : 0x08000000 
 
 
Erasing memory corresponding to segment 0:
Erasing internal memory sectors [0 32]
Erasing memory corresponding to segment 1:
Erasing external memory sectors [0 108]
Download in Progress:
 
 
Error: failed to download Segment[0]
Error: failed to download the File
Shutting down...
Exit.

I dont't know how to solve this. Any ideas?

This topic has been closed for replies.
Best answer by Sara BEN HADJ YAHYA

Hello,

Please check N. SANTINI comment in this thread.

Sara.

15 replies

Tesla DeLorean
Guru
July 6, 2022

>>I don't know how to solve this. Any ideas?

Get more verbose logs, use the Command Line variant of STM32 Cube Programmer.

Make sure it's loading the right External Loader, and from the directory you expect.

You can instrument External Loaders to use any GPIO or UART available on the board to debug and understand what's happening internally.

CubeIDE + GDB Server, whole other levels of opportunity to fail there, but without knowing the loader is bullet-proof, and having a lot more diagnostic output, it's going to be a challenge to get a lot of support.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
July 6, 2022

@Osman SOYKURT​ similar to one of the other threads. Might help for the tools to become more verbose and detailed in the failure cases so technical support has something to work with. I might suggest adding detail of registers, or timeout expiration.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Osman SOYKURT
ST Technical Moderator
July 7, 2022

Hello Tesla DeLorean,

Thanks for this suggestion, I'll communicate this idea to my colleagues.

/Osman

ST Software Developer | TouchGFX
nikof
nikofAuthor
Associate II
July 7, 2022

Hi Tesla, thank you for your response.

I didnt't know that I can have a more detailed log on the STM32CubeProgrammer.

However, this is the complete output. I cut the first part (connection, read hex, etc.) because the post was too long.

 08:32:12:530 : Memory Programming ...
 08:32:12:530 : Opening and parsing file: striker_ui_ext_flash.hex
 08:32:12:544 : File : striker_ui_ext_flash.hex
 08:32:12:545 : Size : 695.50 KB 
 08:32:12:545 : Address : 0x08000000 
 08:32:12:545 : Erasing Segment <0> Address <0x08000000> Size <257796>Bytes
 08:32:12:545 : Erasing memory corresponding to segment 0:
 08:32:12:545 : Memory erase...
 08:32:12:549 : halt ap 0 
 08:32:12:549 : w ap 0 reg 15 PC (0x24000000) 
 08:32:12:549 : w ap 0 reg 17 MSP (0x24000500) 
 08:32:12:550 : w ap 0 reg 16 xPSR (0x01000000) 
 08:32:12:553 : w ap 0 @0x24001140 0x00000200 bytes Data 0x00000000
 08:32:12:553 : w ap 0 @0x24000000 0x00000004 bytes Data 0x0000BE00
 08:32:12:574 : w ap 0 @0x24000004 0x00000D10 bytes Data 0x8F4FF3BF
 08:32:12:574 : Erasing internal memory sectors [0 31]
 08:32:12:574 : Init flashloader...
 08:32:12:574 : halt ap 0 
 08:32:12:575 : w ap 0 reg 0 R0 0x00000001
 08:32:12:578 : w ap 0 reg 1 R1 0x00000000
 08:32:12:580 : w ap 0 reg 2 R2 0x00000000
 08:32:12:580 : w ap 0 reg 3 R3 0x00000000
 08:32:12:581 : w ap 0 reg 4 R4 0x00000000
 08:32:12:581 : w ap 0 reg 5 R5 0x00000000
 08:32:12:581 : w ap 0 reg 6 R6 0x00000000
 08:32:12:581 : w ap 0 reg 7 R7 0x00000000
 08:32:12:581 : w ap 0 reg 8 R8 0x00000000
 08:32:12:582 : w ap 0 reg 9 R9 0x00000000
 08:32:12:582 : w ap 0 reg 10 R10 0x00000000
 08:32:12:582 : w ap 0 reg 11 R11 0x00000000
 08:32:12:583 : w ap 0 reg 12 R12 0x00000000
 08:32:12:583 : w ap 0 reg 13 SP 0x00000000
 08:32:12:584 : w ap 0 reg 14 LR 0x24000001
 08:32:12:584 : w ap 0 reg 15 PC 0x2400000B
 08:32:12:585 : w ap 0 reg 16 xPSR 0x01000000
 08:32:12:586 : w ap 0 reg 17 MSP 0x24001110
 08:32:12:586 : w ap 0 reg 18 PSP 0x00000000
 08:32:12:586 : run ap 0 
 08:32:12:587 : halt ap 0 
 08:32:12:588 : r ap 0 reg 0 R0 0x00000001
 08:32:12:589 : Loader sector erase...
 08:32:12:590 : w ap 0 reg 0 R0 0x08000000
 08:32:12:590 : w ap 0 reg 1 R1 0x0803E000
 08:32:12:592 : w ap 0 reg 2 R2 0x00000002
 08:32:12:592 : w ap 0 reg 3 R3 0x00000000
 08:32:12:593 : w ap 0 reg 4 R4 0x00000000
 08:32:12:594 : w ap 0 reg 5 R5 0x00000000
 08:32:12:594 : w ap 0 reg 6 R6 0x00000000
 08:32:12:594 : w ap 0 reg 7 R7 0x00000000
 08:32:12:600 : w ap 0 reg 8 R8 0x00000000
 08:32:12:600 : w ap 0 reg 9 R9 0x00000000
 08:32:12:601 : w ap 0 reg 10 R10 0x00000000
 08:32:12:602 : w ap 0 reg 11 R11 0x00000000
 08:32:12:602 : w ap 0 reg 12 R12 0x00000000
 08:32:12:602 : w ap 0 reg 13 SP 0x00000000
 08:32:12:603 : w ap 0 reg 14 LR 0x24000001
 08:32:12:603 : w ap 0 reg 15 PC 0x2400086B
 08:32:12:603 : w ap 0 reg 16 xPSR 0x01000000
 08:32:12:604 : w ap 0 reg 17 MSP 0x24001110
 08:32:12:605 : w ap 0 reg 18 PSP 0x00000000
 08:32:12:605 : run ap 0 
 08:32:12:666 : halt ap 0 
 08:32:12:674 : r ap 0 reg 0 R0 0x00000001
 08:32:12:675 : erase: 0124ms
 08:32:12:675 : Erasing Segment <1> Address <0x90000000> Size <454396>Bytes
 08:32:12:675 : Erasing memory corresponding to segment 1:
 08:32:12:675 : Memory erase...
 08:32:12:675 : halt ap 0 
 08:32:12:675 : w ap 0 reg 15 PC (0x24000000) 
 08:32:12:676 : w ap 0 reg 17 MSP (0x24000500) 
 08:32:12:676 : w ap 0 reg 16 xPSR (0x01000000) 
 08:32:12:678 : w ap 0 @0x240184A0 0x00000200 bytes Data 0x00000000
 08:32:12:681 : w ap 0 @0x24000000 0x00000004 bytes Data 0x0000BE00
 08:32:13:336 : w ap 0 @0x24000004 0x00018064 bytes Data 0x00000000
 08:32:13:337 : Erasing external memory sectors [0 110]
 08:32:13:337 : Init flashloader...
 08:32:13:337 : halt ap 0 
 08:32:13:337 : w ap 0 reg 0 R0 0x00000001
 08:32:13:339 : w ap 0 reg 1 R1 0x00000000
 08:32:13:340 : w ap 0 reg 2 R2 0x00000000
 08:32:13:340 : w ap 0 reg 3 R3 0x00000000
 08:32:13:340 : w ap 0 reg 4 R4 0x00000000
 08:32:13:340 : w ap 0 reg 5 R5 0x00000000
 08:32:13:341 : w ap 0 reg 6 R6 0x00000000
 08:32:13:349 : w ap 0 reg 7 R7 0x00000000
 08:32:13:351 : w ap 0 reg 8 R8 0x00000000
 08:32:13:351 : w ap 0 reg 9 R9 0x00000000
 08:32:13:352 : w ap 0 reg 10 R10 0x00000000
 08:32:13:353 : w ap 0 reg 11 R11 0x00000000
 08:32:13:353 : w ap 0 reg 12 R12 0x00000000
 08:32:13:353 : w ap 0 reg 13 SP 0x00000000
 08:32:13:353 : w ap 0 reg 14 LR 0x24000001
 08:32:13:353 : w ap 0 reg 15 PC 0x240006B1
 08:32:13:353 : w ap 0 reg 16 xPSR 0x01000000
 08:32:13:353 : w ap 0 reg 17 MSP 0x24018464
 08:32:13:353 : w ap 0 reg 18 PSP 0x00000000
 08:32:13:353 : run ap 0 
 08:32:13:575 : halt ap 0 
 08:32:13:575 : r ap 0 reg 0 R0 0x00000001
 08:32:13:575 : Loader sector erase...
 08:32:13:576 : w ap 0 reg 0 R0 0x90000000
 08:32:13:576 : w ap 0 reg 1 R1 0x9006E000
 08:32:13:576 : w ap 0 reg 2 R2 0x00000002
 08:32:13:576 : w ap 0 reg 3 R3 0x00000000
 08:32:13:576 : w ap 0 reg 4 R4 0x00000000
 08:32:13:576 : w ap 0 reg 5 R5 0x00000000
 08:32:13:576 : w ap 0 reg 6 R6 0x00000000
 08:32:13:576 : w ap 0 reg 7 R7 0x00000000
 08:32:13:576 : w ap 0 reg 8 R8 0x00000000
 08:32:13:576 : w ap 0 reg 9 R9 0x00000000
 08:32:13:576 : w ap 0 reg 10 R10 0x00000000
 08:32:13:576 : w ap 0 reg 11 R11 0x00000000
 08:32:13:576 : w ap 0 reg 12 R12 0x00000000
 08:32:13:577 : w ap 0 reg 13 SP 0x00000000
 08:32:13:577 : w ap 0 reg 14 LR 0x24000001
 08:32:13:577 : w ap 0 reg 15 PC 0x240007D3
 08:32:13:579 : w ap 0 reg 16 xPSR 0x01000000
 08:32:13:580 : w ap 0 reg 17 MSP 0x24018464
 08:32:13:582 : w ap 0 reg 18 PSP 0x00000000
 08:32:13:582 : run ap 0 
 08:32:17:745 : halt ap 0 
 08:32:17:745 : r ap 0 reg 0 R0 0x00000001
 08:32:17:746 : erase: 5077ms
 08:32:17:746 : Download in Progress:
 08:32:17:746 : Size : 257824 Bytes
 08:32:17:746 : Address : 0x08000000 
 08:32:17:746 : Buffer program...
 08:32:17:750 : halt ap 0 
 08:32:17:750 : w ap 0 reg 15 PC (0x24000000) 
 08:32:17:750 : w ap 0 reg 17 MSP (0x24000500) 
 08:32:17:750 : w ap 0 reg 16 xPSR (0x01000000) 
 08:32:17:753 : w ap 0 @0x24001140 0x00000200 bytes Data 0x00000000
 08:32:17:753 : w ap 0 @0x24000000 0x00000004 bytes Data 0x0000BE00
 08:32:17:779 : w ap 0 @0x24000004 0x00000D10 bytes Data 0x8F4FF3BF
 08:32:17:779 : Loader write range...
 08:32:18:689 : w ap 0 @0x24001140 0x0001F7A0 bytes Data 0x20020000
 08:32:18:689 : W B1 in RAM @0x24001140 size 0x0001F7A0 : 0915ms
 08:32:18:690 : Init flashloader...
 08:32:18:692 : halt ap 0 
 08:32:18:693 : w ap 0 reg 0 R0 0x00000001
 08:32:18:693 : w ap 0 reg 1 R1 0x00000000
 08:32:18:693 : w ap 0 reg 2 R2 0x00000000
 08:32:18:693 : w ap 0 reg 3 R3 0x00000000
 08:32:18:693 : w ap 0 reg 4 R4 0x00000000
 08:32:18:694 : w ap 0 reg 5 R5 0x00000000
 08:32:18:694 : w ap 0 reg 6 R6 0x00000000
 08:32:18:695 : w ap 0 reg 7 R7 0x00000000
 08:32:18:696 : w ap 0 reg 8 R8 0x00000000
 08:32:18:696 : w ap 0 reg 9 R9 0x00000000
 08:32:18:697 : w ap 0 reg 10 R10 0x00000000
 08:32:18:697 : w ap 0 reg 11 R11 0x00000000
 08:32:18:698 : w ap 0 reg 12 R12 0x00000000
 08:32:18:698 : w ap 0 reg 13 SP 0x00000000
 08:32:18:699 : w ap 0 reg 14 LR 0x24000001
 08:32:18:699 : w ap 0 reg 15 PC 0x2400000B
 08:32:18:699 : w ap 0 reg 16 xPSR 0x01000000
 08:32:18:700 : w ap 0 reg 17 MSP 0x24001110
 08:32:18:700 : w ap 0 reg 18 PSP 0x00000000
 08:32:18:701 : run ap 0 
 08:32:18:701 : halt ap 0 
 08:32:18:707 : r ap 0 reg 0 R0 0x00000001
 08:32:18:709 : w ap 0 reg 0 R0 0x08000000
 08:32:18:710 : w ap 0 reg 1 R1 0x0001F7A0
 08:32:18:711 : w ap 0 reg 2 R2 0x24001140
 08:32:18:713 : w ap 0 reg 3 R3 0x00000002
 08:32:18:713 : w ap 0 reg 4 R4 0x00000000
 08:32:18:714 : w ap 0 reg 5 R5 0x00000000
 08:32:18:714 : w ap 0 reg 6 R6 0x00000000
 08:32:18:714 : w ap 0 reg 7 R7 0x00000000
 08:32:18:714 : w ap 0 reg 8 R8 0x00000000
 08:32:18:714 : w ap 0 reg 9 R9 0x00000000
 08:32:18:715 : w ap 0 reg 10 R10 0x00000000
 08:32:18:715 : w ap 0 reg 11 R11 0x00000000
 08:32:18:715 : w ap 0 reg 12 R12 0x00000000
 08:32:18:715 : w ap 0 reg 13 SP 0x00000000
 08:32:18:715 : w ap 0 reg 14 LR 0x24000001
 08:32:18:715 : w ap 0 reg 15 PC 0x24000079
 08:32:18:715 : w ap 0 reg 16 xPSR 0x01000000
 08:32:18:715 : w ap 0 reg 17 MSP 0x24001110
 08:32:18:715 : w ap 0 reg 18 PSP 0x00000000
 08:32:18:715 : run ap 0 
 08:32:19:650 : w ap 0 @0x240208E0 0x0001F780 bytes Data 0xB2093004
 08:32:19:651 : W B2 in RAM @0x24080740 size 0x0001F780: 0961ms
 08:32:19:654 : r ap 0 reg 0 R0 0x00000001
 08:32:19:654 : Wait W B1 in Flash @0x08000000 size 0x0001F7A0: 0001ms
 08:32:19:654 : r ap 0 reg 0 R0 0x00000001
 08:32:19:654 : Write elapsed time: 1879ms
 08:32:19:656 : halt ap 0 
 08:32:19:656 : w ap 0 reg 15 PC (0x24000000) 
 08:32:19:656 : w ap 0 reg 17 MSP (0x24000500) 
 08:32:19:656 : w ap 0 reg 16 xPSR (0x01000000) 
 08:32:19:657 : Loader write range...
 08:32:20:581 : w ap 0 @0x24001140 0x0001F7A0 bytes Data 0x20020000
 08:32:20:581 : W B1 in RAM @0x24001140 size 0x0001F7A0 : 0925ms
 08:32:20:583 : halt ap 0 
 08:32:20:584 : r ap 0 reg 0 R0 0x5200200C
 08:32:20:584 : Error: failed to download Segment[0]
 08:32:20:584 : Error: failed to download the File

Osman SOYKURT
ST Technical Moderator
July 7, 2022

Hello nikof,

Don't know if this helps but can you try with

OCTOSPI (xrw)	 : ORIGIN = 0x90000000, LENGTH = 16M

Also, is your flash memory correctly configured ? You can follow this guide to set it up.

/Osman

ST Software Developer | TouchGFX
nikof
nikofAuthor
Associate II
July 7, 2022

Hello Osman,

I tried your advice but nothing changed.

Also, I think the flash memory is correctly configured. I can read, write and erase just sendig the appropriate commands. Also I can do all these things in the STM32CubeProgrammer.

The problem occur when I try to run my TouchGFX project putting something in the external flash. In the linker script:

TextFlashSection :
{
 *(TextFlashSection TextFlashSection.*)
 *(.gnu.linkonce.r.*)
 . = ALIGN(0x4);
} >OCTOSPI

Osman SOYKURT
ST Technical Moderator
July 7, 2022

You're in memory mapped mode right ?

Have you check in your application in TouchGFX Designer if you have this checkbox checked ?

0693W00000QKdltQAD.png 

/Osman

ST Software Developer | TouchGFX
nikof
nikofAuthor
Associate II
July 7, 2022

Yes, I'm in memory mapped mode.

Yes, it is checked.

Tesla DeLorean
Guru
July 7, 2022

Looks to be failing when it switched back to the internal loader, so might suggest that the external one is making a mess of the MCU, perhaps having it running interrupts, or using RAM (0x24000000) for a different and incompatible purpose.

The loaders shouldn't need to be using interrupts. There are other ways to mark off time for timeouts and delays.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
nikof
nikofAuthor
Associate II
July 8, 2022

I made the loader following this guide:

https://www.youtube.com/watch?v=XqCq0xtQmbI&t=505s

The source code of this is available in this repo:

https://github.com/STMicroelectronics/stm32-external-loader/tree/contrib

These are my functions defined in Loader_Src.c file:

int
Init(void) {
 
 *(uint32_t*)0xE000EDF0 = 0xA05F0000; //enable interrupts in debug
 
 
 SystemInit();
	//__disable_irq();
 
 /* ADAPTATION TO THE DEVICE
 *
 * change VTOR setting for H7 device
 * SCB->VTOR = 0x24000000 | 0x200;
 *
 * change VTOR setting for other devices
 * SCB->VTOR = 0x20000000 | 0x200;
 *
 * */
 
 SCB->VTOR = 0x24000000 | 0x200;
 
 //__set_PRIMASK(0); //enable interrupts
 
 HAL_Init();
 
 SystemClock_Config();
 
 MX_GPIO_Init();
 
 __HAL_RCC_OSPI1_FORCE_RESET();		//completely reset peripheral
 __HAL_RCC_OSPI1_RELEASE_RESET();
 
 if (LDR_QUADSPI_Init() != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 
 if (CSP_QSPI_EnableMemoryMappedMode() != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 /*Trigger read access before HAL_QSPI_Abort() otherwise abort functionality gets stuck*/
 uint32_t a = *(uint32_t*) 0x90000000;
 a++;
 
 __set_PRIMASK(1); //disable interrupts
 return LOADER_OK;
}
 
/**
 * @brief Program memory.
 * @param Address: page address
 * @param Size : size of data
 * @param buffer : pointer to data buffer
 * @retval LOADER_OK = 1 : Operation succeeded
 * @retval LOADER_FAIL = 0 : Operation failed
 */
int
Write(uint32_t Address, uint32_t Size, uint8_t* buffer) {
 
 //__set_PRIMASK(0); //enable interrupts
 
 if (HAL_OSPI_Abort(&hospi1) != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 if (CSP_QSPI_Write((uint8_t*) buffer, (Address & (0x0fffffff)), Size) != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 __set_PRIMASK(1); //disable interrupts
 return LOADER_OK;
}
 
/**
 * @brief Read memory. (not mandatory)
 * @param Address: page address
 * @param Size : size of data
 * @param buffer : pointer to data buffer
 * @retval LOADER_OK = 1 : Operation succeeded
 * @retval LOADER_FAIL = 0 : Operation failed
 */
int
Read(uint32_t Address, uint32_t Size, uint8_t* buffer) {
 
	int i = 0;
 
 //__set_PRIMASK(0); //enable interrupts
 
 if (HAL_OSPI_Abort(&hospi1) != HAL_OK) {
		__set_PRIMASK(1); //disable interrupts
		return LOADER_FAIL;
	}
 
 if (CSP_QSPI_EnableMemoryMappedMode() != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 for (i=0; i < Size;i++)
	{
		*(uint8_t*)buffer++ = *(uint8_t*)Address;
		Address ++;
	}
 
 __set_PRIMASK(1); //disable interrupts
 return LOADER_OK;
}
 
/**
 * @brief Sector erase.
 * @param EraseStartAddress : erase start address
 * @param EraseEndAddress : erase end address
 * @retval LOADER_OK = 1 : Operation succeeded
 * @retval LOADER_FAIL = 0 : Operation failed
 */
int
SectorErase(uint32_t EraseStartAddress, uint32_t EraseEndAddress) {
 
 //__set_PRIMASK(0); //enable interrupts
 
 if (HAL_OSPI_Abort(&hospi1) != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 if (CSP_QSPI_EraseSector(EraseStartAddress, EraseEndAddress) != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 __set_PRIMASK(1); //disable interrupts
 return LOADER_OK;
}
 
/**
 * Description :
 * Mass erase of external flash area
 * Optional command - delete in case usage of mass erase is not planed
 * Inputs :
 * none
 * outputs :
 * none
 * Note: Optional for all types of device
 */
int
MassErase(void) {
 
 //__set_PRIMASK(0); //enable interrupts
 
 if (HAL_OSPI_Abort(&hospi1) != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 if (CSP_QSPI_Erase_Chip() != HAL_OK) {
 __set_PRIMASK(1); //disable interrupts
 return LOADER_FAIL;
 }
 
 __set_PRIMASK(1); //disable interrupts
 return LOADER_OK;
}

I tried to disable interrupts but nothing changed.

Also, in the guide there is a testing file for external flash. Downloading this file into ext flash (starting from 0x90000000) works well. Like you said I think the problem occurs when I need to switch between internal and external loader.

So, following your suggestion it seems to be a problem of RAM.

Xzhiy.1
Associate II
July 11, 2022

Following words may be wrong? IntFlashSection is apparently not SPI memory, just a hint.

  1. IntFlashSection :
  2. {
  3. *(IntFlashSection IntFlashSection.*)
  4. *(.gnu.linkonce.r.*)
  5. . = ALIGN(0x4);
  6. } >OCTOSPI

nikof
nikofAuthor
Associate II
July 11, 2022

It seems not a problem. I tried to remove the IntFlashSection from the OCTOSPI but doesn't work.

Markus GIRDLAND
ST Employee
July 11, 2022

This could be because you need to initialize the external loader in your debug configuration inside STM32CubeIDE.

Do you know if this checkbox is checked?

0693W00000QKqWcQAL.png

nikof
nikofAuthor
Associate II
July 11, 2022

It was unchecked, but checking it doesn't resolve the problem.

Sara BEN HADJ YAHYA
ST Technical Moderator
July 12, 2022

Hello,

Please check N. SANTINI comment in this thread.

Sara.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question.