cancel
Showing results for 
Search instead for 
Did you mean: 

Custom External Loader fails: Error: failed to download Segment[0]

Marcus1
Associate II

Hi

I am trying to get a custom external loader working on a STM32L562VET with a MT25QL128ABA attached over QuadSPI. I have followed this tutorial: https://www.st.com/content/st_com/en/support/learning/stm32-education/stm32-moocs/external_QSPI_loader.html
and after some modifications, I managed to successfully run the main_test code and everything seems to work fine. I can also see the data in the memory viewer in the STM32CubeIDE.

I then continued to build the *.stldr which also seem to work fine. However when I import it in STMCubeProgrammer v2.15.0, I can erase certain sectors or the whole chip. But if I try to download a .bin file (256Bytes random ASCII), I get the following error messages:

15:39:48 : Error: failed to download Segment[0]
15:39:48 : Error: failed to download the File

If I go back to the memory viewer, I can see that the data was successfully written to the flash despite the error message. What could be the problem here?

Marcus1_0-1710427586788.png

I already tried with STMCubeProgrammer v2.6.0 but get the same error message.

This is the log I get:

 

 

  15:43:24:265 : Memory Programming ...
  15:43:24:265 : Opening and parsing file: output-onlinefiletools.bin
  15:43:24:266 :   File          : output-onlinefiletools.bin
  15:43:24:266 :   Size          : 256.00 B 
  15:43:24:266 :   Address       : 0x90000000 
  15:43:24:266 : Erasing Segment <0> Address <0x90000000> Size <256>Bytes
  15:43:24:266 : Erasing memory corresponding to segment 0:
  15:43:24:266 : Memory Erase via FlashLoader!
  15:43:24:266 : Memory erase...
  15:43:24:272 : halt ap 0 
  15:43:24:272 : w ap 0 reg 15 PC   (0x20000000)  
  15:43:24:272 : w ap 0 reg 17 MSP  (0x20000500)  
  15:43:24:272 : w ap 0 reg 16 xPSR (0x01000000)  
  15:43:24:276 : w ap 0 @0x20012B60 : 0x00000200 bytes, Data 0x00000000...
  15:43:24:276 : w ap 0 @0x20000000 : 0x00000004 bytes, Data 0x0000BE00...
  15:43:24:778 : w ap 0 @0x20000004 : 0x00012728 bytes, Data 0x00000000...
  15:43:24:778 : Erasing external memory sector 0
  15:43:24:778 : Init flashloader...
  15:43:24:778 : halt ap 0 
  15:43:24:778 : w ap 0 reg 0 R0   0x00000001
  15:43:24:779 : w ap 0 reg 1 R1   0x00000000
  15:43:24:779 : w ap 0 reg 2 R2   0x00000000
  15:43:24:779 : w ap 0 reg 3 R3   0x00000000
  15:43:24:779 : w ap 0 reg 4 R4   0x00000000
  15:43:24:779 : w ap 0 reg 5 R5   0x00000000
  15:43:24:779 : w ap 0 reg 6 R6   0x00000000
  15:43:24:779 : w ap 0 reg 7 R7   0x00000000
  15:43:24:779 : w ap 0 reg 8 R8   0x00000000
  15:43:24:779 : w ap 0 reg 9 R9   0x00000000
  15:43:24:779 : w ap 0 reg 10 R10  0x00000000
  15:43:24:779 : w ap 0 reg 11 R11  0x00000000
  15:43:24:779 : w ap 0 reg 12 R12  0x00000000
  15:43:24:779 : w ap 0 reg 13 SP   0x00000000
  15:43:24:779 : w ap 0 reg 14 LR   0x20000001
  15:43:24:779 : w ap 0 reg 15 PC   0x20000731
  15:43:24:779 : w ap 0 reg 16 xPSR 0x01000000
  15:43:24:779 : w ap 0 reg 17 MSP  0x20012B28
  15:43:24:779 : w ap 0 reg 18 PSP  0x00000000
  15:43:24:779 : run ap 0 
  15:43:24:779 : halt ap 0 
  15:43:24:779 : r ap 0 reg 0 R0   0x00000001
  15:43:24:779 : Loader sector erase...
  15:43:24:779 : w ap 0 reg 0 R0   0x90000000
  15:43:24:779 : w ap 0 reg 1 R1   0x90000000
  15:43:24:780 : w ap 0 reg 2 R2   0x00000002
  15:43:24:796 : w ap 0 reg 3 R3   0x00000000
  15:43:24:799 : w ap 0 reg 4 R4   0x00000000
  15:43:24:801 : w ap 0 reg 5 R5   0x00000000
  15:43:24:801 : w ap 0 reg 6 R6   0x00000000
  15:43:24:802 : w ap 0 reg 7 R7   0x00000000
  15:43:24:802 : w ap 0 reg 8 R8   0x00000000
  15:43:24:802 : w ap 0 reg 9 R9   0x00000000
  15:43:24:802 : w ap 0 reg 10 R10  0x00000000
  15:43:24:802 : w ap 0 reg 11 R11  0x00000000
  15:43:24:802 : w ap 0 reg 12 R12  0x00000000
  15:43:24:802 : w ap 0 reg 13 SP   0x00000000
  15:43:24:802 : w ap 0 reg 14 LR   0x20000001
  15:43:24:802 : w ap 0 reg 15 PC   0x200007CD
  15:43:24:802 : w ap 0 reg 16 xPSR 0x01000000
  15:43:24:802 : w ap 0 reg 17 MSP  0x20012B28
  15:43:24:802 : w ap 0 reg 18 PSP  0x00000000
  15:43:24:802 : run ap 0 
  15:43:24:903 : halt ap 0 
  15:43:24:903 : r ap 0 reg 0 R0   0x00000001
  15:43:24:903 : erase: 0638ms
  15:43:24:903 : Download in Progress:
  15:43:24:904 :   Size          : 256 Bytes
  15:43:24:904 :   Address       : 0x90000000 
  15:43:24:904 : Buffer program...
  15:43:24:912 : halt ap 0 
  15:43:24:912 : w ap 0 reg 15 PC   (0x20000000)  
  15:43:24:912 : w ap 0 reg 17 MSP  (0x20000500)  
  15:43:24:912 : w ap 0 reg 16 xPSR (0x01000000)  
  15:43:24:916 : w ap 0 @0x20012B60 : 0x00000200 bytes, Data 0x00000000...
  15:43:24:916 : w ap 0 @0x20000000 : 0x00000004 bytes, Data 0x0000BE00...
  15:43:25:407 : w ap 0 @0x20000004 : 0x00012728 bytes, Data 0x00000000...
  15:43:25:408 : Loader write range...
  15:43:25:409 : w ap 0 @0x20012B60 : 0x00000100 bytes, Data 0x6A7D2670...
  15:43:25:409 : W B1 in RAM @0x20012B60 size 0x00000100 : 0002ms
  15:43:25:409 : Init flashloader...
  15:43:25:411 : halt ap 0 
  15:43:25:411 : w ap 0 reg 0 R0   0x00000001
  15:43:25:411 : w ap 0 reg 1 R1   0x00000000
  15:43:25:412 : w ap 0 reg 2 R2   0x00000000
  15:43:25:412 : w ap 0 reg 3 R3   0x00000000
  15:43:25:412 : w ap 0 reg 4 R4   0x00000000
  15:43:25:412 : w ap 0 reg 5 R5   0x00000000
  15:43:25:413 : w ap 0 reg 6 R6   0x00000000
  15:43:25:413 : w ap 0 reg 7 R7   0x00000000
  15:43:25:414 : w ap 0 reg 8 R8   0x00000000
  15:43:25:414 : w ap 0 reg 9 R9   0x00000000
  15:43:25:415 : w ap 0 reg 10 R10  0x00000000
  15:43:25:415 : w ap 0 reg 11 R11  0x00000000
  15:43:25:416 : w ap 0 reg 12 R12  0x00000000
  15:43:25:416 : w ap 0 reg 13 SP   0x00000000
  15:43:25:416 : w ap 0 reg 14 LR   0x20000001
  15:43:25:417 : w ap 0 reg 15 PC   0x20000731
  15:43:25:417 : w ap 0 reg 16 xPSR 0x01000000
  15:43:25:417 : w ap 0 reg 17 MSP  0x20012B28
  15:43:25:418 : w ap 0 reg 18 PSP  0x00000000
  15:43:25:418 : run ap 0 
  15:43:25:421 : halt ap 0 
  15:43:25:421 : r ap 0 reg 0 R0   0x00000001
  15:43:25:421 : w ap 0 reg 0 R0   0x90000000
  15:43:25:421 : w ap 0 reg 1 R1   0x00000100
  15:43:25:421 : w ap 0 reg 2 R2   0x20012B60
  15:43:25:421 : w ap 0 reg 3 R3   0x00000002
  15:43:25:422 : w ap 0 reg 4 R4   0x00000000
  15:43:25:423 : w ap 0 reg 5 R5   0x00000000
  15:43:25:423 : w ap 0 reg 6 R6   0x00000000
  15:43:25:425 : w ap 0 reg 7 R7   0x00000000
  15:43:25:425 : w ap 0 reg 8 R8   0x00000000
  15:43:25:426 : w ap 0 reg 9 R9   0x00000000
  15:43:25:426 : w ap 0 reg 10 R10  0x00000000
  15:43:25:426 : w ap 0 reg 11 R11  0x00000000
  15:43:25:426 : w ap 0 reg 12 R12  0x00000000
  15:43:25:426 : w ap 0 reg 13 SP   0x00000000
  15:43:25:426 : w ap 0 reg 14 LR   0x20000001
  15:43:25:427 : w ap 0 reg 15 PC   0x20000789
  15:43:25:428 : w ap 0 reg 16 xPSR 0x01000000
  15:43:25:429 : w ap 0 reg 17 MSP  0x20012B28
  15:43:25:429 : w ap 0 reg 18 PSP  0x00000000
  15:43:25:429 : run ap 0 
  15:43:25:433 : w ap 0 @0x20012B60 : 0x00000100 bytes, Data 0x6A7D2670...
  15:43:25:433 : W B2 in RAM @0x20029460 size 0x00000100: 0020ms
  15:43:25:433 : r ap 0 reg 0 R0   0x00000001
  15:43:25:433 : Wait W B1 in Flash @0x90000000 size 0x00000100: 0001ms
  15:43:25:433 : w ap 0 reg 0 R0   0x90000000
  15:43:25:433 : w ap 0 reg 1 R1   0x00000100
  15:43:25:433 : w ap 0 reg 2 R2   0x20012B60
  15:43:25:433 : w ap 0 reg 3 R3   0x00000002
  15:43:25:433 : w ap 0 reg 4 R4   0x00000000
  15:43:25:433 : w ap 0 reg 5 R5   0x00000000
  15:43:25:435 : w ap 0 reg 6 R6   0x00000000
  15:43:25:436 : w ap 0 reg 7 R7   0x00000000
  15:43:25:436 : w ap 0 reg 8 R8   0x00000000
  15:43:25:436 : w ap 0 reg 9 R9   0x00000000
  15:43:25:445 : w ap 0 reg 10 R10  0x00000000
  15:43:25:446 : w ap 0 reg 11 R11  0x00000000
  15:43:25:446 : w ap 0 reg 12 R12  0x00000000
  15:43:25:447 : w ap 0 reg 13 SP   0x00000000
  15:43:25:447 : w ap 0 reg 14 LR   0x20000001
  15:43:25:448 : w ap 0 reg 15 PC   0x20000789
  15:43:25:448 : w ap 0 reg 16 xPSR 0x01000000
  15:43:25:448 : w ap 0 reg 17 MSP  0x20012B28
  15:43:25:448 : w ap 0 reg 18 PSP  0x00000000
  15:43:25:448 : run ap 0 
  15:43:25:448 : r ap 0 reg 0 R0   0x00000000
  15:43:25:448 : halt ap 0 
  15:43:25:448 : w ap 0 reg 15 PC   (0x20000000)  
  15:43:25:448 : w ap 0 reg 17 MSP  (0x20000500)  
  15:43:25:448 : w ap 0 reg 16 xPSR (0x01000000)  
  15:43:25:448 : Loader write range...
  15:43:25:448 : w ap 0 @0x20012B60 : 0x00000100 bytes, Data 0x6A7D2670...
  15:43:25:448 : W B1 in RAM @0x20012B60 size 0x00000100 : 0002ms
  15:43:25:449 : halt ap 0 
  15:43:25:449 : r ap 0 reg 0 R0   0x00000000
  15:43:25:449 : Error: failed to download Segment[0]
  15:43:25:449 : Error: failed to download the File

 

 

 

9 REPLIES 9
Imen.D
ST Employee

Hello @Marcus1 

Please check this FAQ: Custom external loader "failed to download segment... - STMicroelectronics Community

I hope this will help.

Please keep me informed about your progress on this issue.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Hi @Imen.D,

Thanks for your answer. I already saw that post and tried the suggested modifications but they didn't help. That's also the reason why I switched back to CubeProgrammer v2.6.0.

Maybe the template I used from the following repository is not compatible anymore since it seems outdated? Last change to the repo was 4years ago:

https://github.com/STMicroelectronics/stm32-external-loader/tree/contrib/Loader_Files/other%20devices

 

Doesn't look an unreasonable starting point.

The log seems to indicate it tries to write twice, failing the second time. You can instrument you loader to use any hardware on your board. You can output diagnostic information via an available UART

BTW what's you pin utilization here?

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

@Imen.D Why won't ST implement "universal" QSPI/OSPI loader like Segger did?

If I understand correctly, they've split the loader to MCU specific part (which supports all QSPI pinout variants) and flash memory specific logic that sits on the host. The MCU part reads the standard flash chip info, then the host decides which commands and parameters to use, etc. This way the flash specific algorithm is done only once for all MCUs. As soon as a new flash chip is made known to the host library, all MCUs and boards automatically support it.

There's no more N*M proliferation of loaders, where N are boards/pinouts and M are flash chips. Users won't have to roll their own.

 

I made some more experiments and it seems like the data is not correctly written to the flash from CubeProgrammer. When I write a bin file containing 16bytes "0123456789abcdef", it actually works and I get the message "file download complete" and the memory looks right:

Marcus1_0-1710509573051.png

However, when I download a bin file containing 17bytes "0123456789abcdefg", I get the mentioned error message and the 17bytes get correctly written including 3 garbage bytes (randomly):

Marcus1_1-1710509697835.png

Here's my pin Cube config:

Marcus1_2-1710509780806.pngMarcus1_3-1710509811334.png

I also ran this piece of code to fill every sector with the corresponding sector number:

  for (var = 0; var < SECTORS_COUNT; var++) {
      if (CSP_QSPI_EraseSector(var * MEMORY_SECTOR_SIZE,(var + 1) * MEMORY_SECTOR_SIZE - 1) != HAL_OK) {
          while(1);  //breakpoint - error detected
      }
      for (int i = 0; i < MEMORY_SECTOR_SIZE; i++) {
          buffer_test[i] = (var & 0xff);
      }
      if (CSP_QSPI_WriteMemory(buffer_test, var * MEMORY_SECTOR_SIZE, sizeof(buffer_test)) != HAL_OK) {
          while(1);  //breakpoint - error detected
      }
  }

 That runs fine and I can see the sectors get correctly filled. However I somehow don't manage to erase sectors 128...255. MEMORY_SECTOR_SIZE is 0x10000

next, I will try to print some debug messages over UART as you suggested

IAR had a scripting method.

A start at the .STLDR level might be for the tools to dynamically query the StorageInfo.

Say another exported function, which takes as input a pin table, defining GPIO Bank, Pin and AF#, and returns a StorageInfo structure.

There's a couple of things that could be done quite easily without breaking backward compatibility.

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

Tentative L5 build from my OSPI forks.

https://github.com/cturvey/stm32extldr/blob/main/l5_mt25q256/CLIVEONE-MT25QL256_STM32L552-PA3-PA4-PB1-PB0-PA7-PA6.stldr

PA3:AF10 CLK

PA4:AF3 NCS

PB1:AF10 D0

PB0:AF10 D1

PA7:AF10 D2

PA6:AF10 D3

 

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

Hi @Pavel A.,

Now, ST is providing a new solution to customize and generate the external loaders based on two Middlewares: "STM32_ExtMem_Manager" & "STM32_ExtMem_Loader" that are integrated in CubeMX in order to develop the external memory loaders using CubeMX.
This will allow you to develop your external loaders in all IDEs (Keil MDK-ARM, IAR & CubeIDE) for all the same IDEs.
This solution is deployed on STM32H7RS series for the moment and will be used for the next products.
You can find the template under this new package STM32CubeH7RS and used it for your product:

"STM32Cube_FW_H7RS_V1.0.0\Projects\STM32H7S78-DK\Templates\Template_XIP".

Note that this solution supports NOR, SDcard & PSRAM memories.

PS: For the moment, no plan to deploy this in legacy products.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Unfortunately, this did not work. However, thanks to the debug UART output, I managed to find the issue. There was something wrong with the de-initialisation of the OSPI in the write function. No idea why this only happened when writing the second time.

However the behavior of CubeProgrammer is still a bit mysterious to me. Like mentioned above, writing a 16byte bin file worked correctly because it was written only once. Here the log of my UART output:

Initialisation
LOADER_OK
Write: 0x90000000 0x10 0123456789abcdef
LOADER_OK

(Write: [Address][length][data])

However a 17byte bin file gets written twice and the length transmitted is not correct and thus there is some garbage data:

Initialisation
LOADER_OK
Write: 0x90000000 0x14 0123456789abcdefg▒▒▒
LOADER_OK
Write: 0x90000000 0x14 0123456789abcdefg▒▒▒
LOADER_OK

Is this a bug or a feature?