cancel
Showing results for 
Search instead for 
Did you mean: 

ST-Link Utility External Bootloader

gokhannsahin
Associate II
Posted on February 24, 2018 at 08:43

Hi everyone,

I have a few question about this external bootloader. In my project has an external flash is 

W25Q32JVZPIQ. I use SPI module not QSPI to communicate with it since QSPI is used in communication with another chip. The using memory of that flash is around 2Mbyte. It's too huge for me.I have tried to send the data via canbus but it takes too long. 

I'm wondering how to transmit to external flash through MCU (STM32L476VCT6). Can I use the st-link for that application? If yes, how? I have read its manual and review examples in external loader folder. However, I can't understand how to run them since it doesn't have main.c. Do I need to make changes to the linker script? In my opinion, its manual is very inadequate.

#st-link-external-loader
7 REPLIES 7
Posted on February 24, 2018 at 23:55

I used the ST-LINK Utility to flash the external flash of STMF746-DISCO through  'external loader' (N128QA_STM32F746..).

Some info is here, how to develop external loader:

http://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

 

https://mvdlande.wordpress.com/2015/10/14/building-an-custom-external-loader-for-st-link/

 

But I have no experience in this area. But the problem itself is interesting.

Posted on February 25, 2018 at 00:28

These are designed to be stand-alone applets downloaded in to RAM and configure interfaces for specific boards and memory.

They don't use main.c or a main() entry point because that is not how they are used or loaded. They are similar in functionality to DLLs in Windows. There is an Init function which initializes the pins and interfaces, and a data structure that the ST-LINK Utilities uses to report the Chip/Board supported, and conveys the memory sizing and addressing within the STM32 address space. For SPI devices that are not directly mappable into the system space this could be a pseudo-address which you use in the linker script to describe the placement.

It is a somewhat complex area for development, but is a common one and a method for those building and bringing up custom boards. The form and structure is very similar to Keil's Flash Algorithms, so docs there might better convey the concepts. I've built these, and similar things for custom SoC and ASIC implementations.

Not sure it is advanced level stuff, but probably beyond the familiarity of intern or junior level engineers.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on February 25, 2018 at 00:31

https://community.st.com/ideas/1010

 
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Andreas Bolsch
Lead II
Posted on February 25, 2018 at 10:24

If you want to give openOCD a try: There is a patch for spi flash (bitbanging!) for Cortex-M. With 4 MHz SWD clock via STLink approx. 150 kByte/s on F030, F746, ...

(with a higher SWD clock more should be possible, though). All you have to configure are the GPIO pins and a (pseudo-) address space. Then, for programming,  the spi flash looks like an internal memory, i. e. you can build a single(!) firmware image containing the program code and the data for the spi flash and upload it in an single operation.

Look for 'msoftspi'. The patch is currently abandoned (since I didn't bother updating it regularly), but if you want to test it, I've an up-to-date version at hand. The openOCD server seems to be down right now, but I might push the current version as soon it's online again.

gokhannsahin
Associate II
Posted on February 26, 2018 at 14:38

I have tried an example has been shared by

Turvey.Clive

‌ in the forum. The stldr file has been generated by TrueStudio works normally, so I can change the memory type and its name.I have to create a new project to use only SPI module and LL library. I have successfully compiled and moved it but it doesn't be seen in external loader list in ST-Link Utility. WhereasI haven't changed the Dev_Inf.c, it's same before compiled. The output of console after compiled is as follows

Print size information

text data bss dec hex filename

1372 8 28 1408 580 Debug.elf

Print size information done

Generate listing file

Output sent to: Debug.list

Generate listing file done

Generate build reports done

cmd.exe /C copy/Y Debug.elf ..\..\N25Q256A_TEST.stldr

1 file(s) copied.

Posted on February 26, 2018 at 16:35

The ST-LINK Utilities probes the structures in the .STLDR files to find the Name/Geometry, the .ELF loader isn't very flexible so has limits in what it scans and what will show up as an available loader.

https://community.st.com/0D50X00009XkeiOSAR

 
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
gokhannsahin
Associate II
Posted on March 01, 2018 at 13:17

Thank you,

Turvey.Clive

‌. Finally, I can read and write the external memory through MCU.I have only one problem is unresolved, I can't it. It's to erase the sectors, The program can erase only one sector. When I select multiple sectors or not select the skip slasherase check box during programming, can't finish the process and give an error is as follows.

14:43:02 : [deneme.bin] opened successfully.

14:43:02 : [deneme.bin] checksum : 0x03E199DA

14:43:25 : Timeout during flash programming

14:43:25 : Error occured during erase operation!

However, after did mass erase, if I select the skip flash erase check box, it can complete the programming successfully. I have tried to use that function which is used to erase sector in another project, it works. (The sector size of external memory = 4Kb and its total size=4Mbyte)

uint32_t BlockAddr;

EraseStartAddress = EraseStartAddress - (EraseStartAddress & 0xFFF);

while (EraseEndAddress>=EraseStartAddress)

{

BlockAddr = EraseStartAddress & 0x0FFFFFFF;

sFLASH_EraseSector( BlockAddr);

EraseStartAddress += 0x1000;

}

return 1;