cancel
Showing results for 
Search instead for 
Did you mean: 

How can I implement an external loader for SMTCubeIDE?

Luca G.
Associate III

Hello

I'm developing an application with an STM32F750Z8 and I need to put the code in the external flash and then debug it. 

I tried to implement the firmware:

1) I created the Launcher with STMCubeIDE and STMCubeMX and programmed the microcontroller with them. This application perform only a jump and a led blink if enter in HardFault.

You can find the Launcher in attached (is with IAR because is a old project but there should not be any problems or differences).

2) I implemented FlashLoader, following the guide https://www.st.com/content/ccc/resource/technical/document/user_manual/e6/10/d8/80/d6/1d/4a/f2/CD00262073.pdf/files/CD00262073.pdf/jcr:content/translations/en.CD00262073.pdf at 3.9 chapter and based on the example in N25Q512A_STM32F769I-EVAL path of STM32 ST-LINK Utility/ST-LINK Utility/ExternalLoader directory (inside STMCubeIDE directory there are no examples for STM32F7): I created the FlashLoader with STMCubeIDE and configured the STM32F750Z8 (it's microcontroller for my application) with STMCubeMX; I added the files in N25Q512A_STM32F769I-EVAL, added my custom library for QSPI (the QSPI.c and QSPI.h files) and all the HAL libraries necessary and set the proper linker file (Target.ld).

I compiled, modified the extension of "elf" file in "stldr" and I moved this file in ExternalLoader directory of STMCubeIDE.

You can find the FlashLoader in attached.

Step3) I implemented an empty application with STMCubeIDE and STMCubeMX and tried to change "External loader" in Debug Configuration -> Debugger.

First of all the file that I copied in 2) doesn't appeare when I click Scan. If I insert manually the name of "stldr" file, the debug starts (I'm using ST-LINK V2) but is not able to debug code and indicates "Break at address "0x8001e9a" with no debug information available, or outside of program code."

In attached you can find a screenshot and application.

What can be my problem/error? 

Why the ST-LINK V2 can't debug code? 

Are there any templates or step-by-step guides for build a custom flash loader for STMCubeIDE?

Thanks in advance.

7 REPLIES 7

There are a small subset of examples provided by the ST-LINK Utilities and STM32 Cube Programmer that replaces it.

The loaders are not normal applications, but rather object files loaded into RAM, this doesn't get done in a way that lends itself to step by step debugging. You can use other peripherals and things like the serial ports to get telemetry. You should exercise the loader in a test application framework you can debug in more normal ways.

These things are complicated and not easy to describe in 5 minute forum posts.​

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

Thanks for reply.

"There are a small subset of examples provided by the ST-LINK Utilities and STM32 Cube Programmer that replaces it."

Yes I know, I created my Flash Loader starting from them.

"The loaders are not normal applications, but rather object files loaded into RAM, this doesn't get done in a way that lends itself to step by step debugging."

Ok but also if the code run in RAM I can't debug it? I tried this, it works and the debug start in "init" function.

"These things are complicated and not easy to describe in 5 minute forum posts.​"

Yes I know it's complicated but...how can I do to solve my problems? Are there specific guides?

>>Ok but also if the code run in RAM I can't debug it? I tried this, it works and the debug start in "init" function.

It is one of these chicken-egg situations, how do debugger writers debug debuggers?

Yes, going to use Init() as the entry point.

You'd need to build a test framework (wrapper), as an app with main(), etc and then call and exercise the loader functions, starting with Init() and then calling the other sub-functions. Debug this in an environment you are comfortable with, and use a BSP you have already tested *thoroughly*. You can use a UART or GPIO, or anything else in your system, to provide diagnostic or telemetry output while working blindly inside the STM32 programming tools themselves. ie to establish why a specific usage is failing, absent the need/ability to single-step everything.

>>Are there specific guides?

No, I think we're expected to know what we're doing. These type of loader have been around for a long time, across a lot of platforms. The ST design is derived from the Keil FLM design, perhaps see if that has better documentation or guides.

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

"You'd need to build a test framework (wrapper), as an app with main(), etc and then call and exercise the loader functions, starting with Init() and then calling the other sub-functions. Debug this is an environment you are comfortable with, and use a BSP you have already tested *thoroughly*. You can use a UART or GPIO, or anything else in your system, to provide diagnostic or telemetry output while working blindly inside the STM32 programming tools themselves. ie to establish why a specific usage is failing, absent the need/ability to single-step everything."

I did it and the code works fine in flash.

I noticed that, unlike when the code is executed in flash, the variables are not initialized to 0, but why? Is it a linker file setting? Personally I didn't find anything.

In addition to this I have found that the "Place function in their own section" option must be removed in the project properties -> C / C ++ Builder -> Settings -> MCC Compiler -> Optimization.

However I can now debug it even in RAM: it starts on the "init" function, executes the initialization and return without problems. I have inserted inside "init" function, only for debug, an erase and a write operation and are executed correctly.

Using this flash loader now the error that returns me is different: it starts but at some point stops and returns the error

"Error! Failed to read target status

Debugger connection lost.

Shutting down ... "

If you have any suggestions I would be grateful.

Thanks in advance.

Luca G.

In GNU/GCC the memory space is cleaned via code in startup.s or constructors called via __libc_init_array, and in Keil via __main

This doesn't occur in the loaders, as the tools just load the ELF section objects directly into RAM, as is, and call the functions.

There's nothing to unpack the Load Regions, so don't use them. Build instead like you would a DLL, or executable on a PC.

Avoid the ">RAM AT> FLASH" type stuff.

Loss of debug connectivity will occur if the pins are reconfigured or the device sleeps. You can't use interrupts and SysTick. Generally your system with use the vector table currently in FLASH, so if you have a Hard Fault routine that outputs useful information to a serial port you can understand what went wrong.

I have posted several .STLDR examples with different pin configurations, and can remap a lot of the ST provided ones.

The STLDR for the STM32F746G-DISCO and STM32F7508-DK are materially very similar.

Would need to know parts-n-pins to generate one.

I also have Keil buildable sources for several platforms and chips that are available in an independent consulting context.

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

"In GNU/GCC the memory space is cleaned via code in startup.s or constructors called via __libc_init_array, and in Keil via __main"

I think in __libc_init_array because the .s file there isn't in my project.

"This doesn't occur in the loaders, as the tools just load the ELF section objects directly into RAM, as is, and call the functions."

Ok, this happens when it is used as a flash loader but starting the debug (only of the flash loader and then in RAM) this should not happen right?

"I have posted several .STLDR examples with different pin configurations, and can remap a lot of the ST provided ones."

Where can I find your .stldr files?

Would either need to replicate the startup code, or explicitly memset() areas being used. Processor just does what it's told, so unless the code is present and executed, it won't happen.

https://community.st.com/s/question/0D50X0000BL5JtoSQF/qspi-with-stm32cubeide-on-custom-stm32f746igt-board

https://community.st.com/s/question/0D50X0000BbL3bcSQC/problem-in-custom-external-loader-n25q128astm32f746gdisco

https://community.st.com/s/question/0D50X0000BUha8TSQR/stm32f469-external-qspi-loader

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