cancel
Showing results for 
Search instead for 
Did you mean: 

External Loader Debug Printing

DWeie
Associate III

Hi all,

I'm developing a custom external loader to flash a QUADSPI memory as part of a TouchGFX project. I'm using an STM32F7 processor and developing using the STM32CubeIDE.

I’m struggling with a specific issue that I’m hoping I’ll be able to get help with. Since I’m unable to observe the state of the processor while the external loader is being called from the ST-LINK Utility I’m planning on redirecting stdio to an unused USART to get run time information.

When running in debug mode in the ST32CubeIDE this is working fine, but as soon as I switch to using the .stldr (generated from the same source) through the ST-LINK Utility the functionality goes away. A rundown of what I have done on this so far is below:

I’ve proven that the Init() function is being called and is running by toggling some other GPIO and observing them.

I’ve globally disabled interrupts in Debug mode to verify that interrupts are not needed for functionality of the UART in blocking mode.

I’ve tested removing the stdio redirect from consideration by writing directly to the UART instance’s data register.

I’ve made sure to call SystemInit() before other initialization code. Normally the assembly startup calls this function, but this (along with data initialization) would be skipped when Init() is called directly by the ST-LINK application.

I have not implemented the data (.bss and zero) initialization that would normally occur in the startup code because, if I understand correctly, the ST-LINK should be doing this based on the provided .stldr file. If it is not then I am unsure where to initialize the data from since there is no reference in flash memory as there would be for normal operation.

Despite this, I am getting no print statements. I'm wondering if anyone with more experience in this might have some suggestions for me to try since I'm not able to think of a next step beyond what I've already attempted.

Thank you,

Don

25 REPLIES 25

To put this in context, I'm a linker/loader/disassembler guy with several decades of experience with this stuff, I was programming Acorn hardware in the early 1980s.

I wrote a tool to optimize/refactor the ELF file and basically strip all the cruft out of it, and I hand patched the pin configuration code. I coded some sequences to make the job easier based on side-effects of the routines called, so I just needed to change the GPIO Bank, Pin and AF setting in one place for each pin.

I used an assembler to generate/develop some of the sequences, but ARM code is self-relative, so if you know the basis for the two different code fragments you can have the assembler compute the call targets for you. ie offset-a+b

Why did I approach it this way? Well it's one of those "shortest paths to victory", basically least additional work, for the most advantageous outcome.

I can rebuild the entire thing from an assembler file, but that is going to take some more time to validate as the assembler and disassembler have slightly different ways of expressing detail, so byte exact often is harder to achieve. Plus I'm compelled to do dead-code removal, and optimize things based on the flagging the analysis tools output.

I've also built others from a clean C implementation, but the HAL results in very large and bloated code.

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

Assembled from source

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

Thanks for the continued help Clive. I know that you're volunteering your time and it is much appreciated. Did you generate this by altering the contents of the N25Q512A_STM32F769-EVAL project that comes with the ST-LINK Utility, or did you start somewhere else?

This was reconstructed from the N25Q128A_STM32F746G-DISCO loader. Built with Keil's armasm and armlink tools, and optimized with a tool called fixaxf. The disassembly was done with an in-house disassembler designed for static analysis and code recovery, it is a multi-pass disassembler based on my earlier Sourcer and Windows Source engines.

The original loader was written in C, and used the STM32F5 SPL library for RCC, GPIO, QSPI, and compiled with IAR

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

So many thanks for sharing this loader. I did not realize writing a loader was going to be so difficult a task with somewhat limited information. This was a project within the project I wanted to avoid. I was fortunate to find this post. My connection to the memory was all most the same. Instead of PE-2 I used PF-7 a cut and jumper later and I have working memory. Would have like to use the pinout I had for routing sakes, but this works and a solution I can live with. Again thanks so much for sharing.

It wouldn't be hard to re-pin this, and I've built others, including some Winbond ones, and different STM32 platforms.

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

Super thanks, but that would be asking too much - I already feel like I hit the lotto when I found this. Looking at the scattered documentation this would have been a two or three week distraction. Cheers - you are much appreciated 🙂

This is probably what you're looking for (15-Sep-2020), I can't keep track of the threads here, but this was in my uploaded cache of files.

It was in the build directory for the 3rd custom instance, so others have used the same pin combo.

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

So I got my hardware modified for the remapping of the pins to use PB2, PB6, PF6, PF7, PF8, PF9 which would match the last attachment you provided. I remapped the pins within the .ioc, and within the stm32746g_discovery_qspi.h (which I use in my project) and tried your your modified file (PB2, PB6, PF6, PF7, PF8, PF9) but it failed to erase memory. Any thoughts on what the issue might be?

Any ideas why the new loader would be working would be greatly appreciated.