2017-01-02 01:40 AM
Hi community
I have to write an external loader that is capable of programming a QSPI flash. My hardware design is mostly the same as the STM32F769I-Discovery board. However the pin configuration is different.
To understand the process of programming an external flash I tried to implement the external loader for this development board on my own. Unfortunately, ST does not deliver the code for this external loader.
Using the example N25Q256A_STM32L476G-EVAL_Cube for the L4 processor I managed to write an external loader that is able to run the library funtion Init() and reads the content of the QSPI directly to the ST-Link utilty.
I have observed that I can not use any interrupts and that the global variables are not zero'd, since __main() (Keil compiler) is not called in such an project.
So one of the problems I observe is the following.
When I try to erase a sector ST-Link reports an error:
External memory sector 0x90010000 is not erased. Verify the memory protection.
However after refreshing the content view, I can see that the sector was erased properly. I have also observed that the callback function Erase() terminates properly. I am using the LEDs as feedback.
After erase Verify() was not called so I thought that ST-Link reads the memory back. I had no luck with disabling and re-enabling the memory mapped mode of the QSPI within the Erase() function.
Writing a binary works for 7 pages but it then stops working and fails.
Do you have any experiences writing an external loader on your own?
Do you have any hints on how to bring erase and write to an success?
Best regards
Daniel B�hmer
#stm32-st-link-utility #external-loader2017-01-02 06:22 AM
So far I have seen, that Write() works perfectly on a total erased flash. SectorErase() however does always result in the fault stated above, even though it returns 1 and indeed erases the specified sector.
Using a normal test application SectorErase() works as specified.
The fault message occurs also if the sector is already erased, and the function SectorErase() does not contain any code except 'return 1'
Can some one tell me, what the ST-Link utility does additionally than executing SectorErase(). Are there any other prerequisites I do not fulfil here?
Thank you and best regards
Daniel
2017-01-02 07:53 AM
Hi Daniel,
Happy new year
I advise you to take a look at application note AN4852 : Programming an external Flash memory using the UART bootloader built-in STM32 microcontrollers.
This application note is delivered with a software (
http://www.st.com/en/embedded-software/x-cube-extboot.html
)
allowing to program an external Quad-SPI flash memory using a developed user boot-code based on the internal UART bootloader protocol.May this help you.
Khouloud.
2017-01-02 03:04 PM
>>Do you have any experiences writing an external loader on your own?
In the general sense, not your specific one.
>>I have observed that I can not use any interrupts and that the global variables are not zero'd, since __main() (Keil compiler) is not called in such an project.
It is a small piece of code uploaded to RAM, it is not designed to be multi-threaded, each task executes to completion, and blocks or spins waiting for the hardware. It uses an ELF file as an upload, it defines the content in RAM (memory) explicitly rather than having to copy a bunch of statics from a FLASH based LOAD REGION into RAM. Use a scatter file and don't put the statics in the wrong load region. ie IRAM *not* inside IROM
The ability to debug is minimal, you could use a USART to output diagnostic/telemetry information, but the primary method would be to paste in code that is thoroughly tested in the first place, or that you can plug into an equivalent framework you have built that emulates the loader. One could build an ELF loader, but that might be a few man-day exercise compared to the USART one. One could instrument the DISCO loaders to review interactions.
2017-01-03 06:17 AM
Thank you for your answers.
Well, the problem is not the communication with the QSPI. That works perfectly. Also the command SectorErase() is executed properly. My question relies what the ST-Link-Utility wants after executing SectorErase().
After deleting a single sector, ST-Link-Utility even shows me all the contents of the flash properly.
The code in question does not contain any magic.
KeepInCompilation int SectorErase (uint32_t EraseStartAddress, uint32_t EraseEndAddress)
{ while (EraseEndAddress>=EraseStartAddress) { uint32_t BlockAddr = EraseStartAddress & 0x0FFFFFFF; uint8_t ret = BSP_QSPI_Erase_Block(BlockAddr); EraseStartAddress += 0x10000; } return 1;}I mean, it executes and terminates perfectly. What I wonder is, what happens afterwards that makes ST-Link-Utility report this error and refuses therefor to erase and program the QSPI flash in one step.
2017-01-05 05:04 AM
Hi Daniel,
Apparently, the ST link utility couldn’t perform the verification process.
Have you implemented a Read function?
Or may be you are using the memory mapped mode in the Init function?
Could you please share the main code? : Init, Read functions.
Khouloud.
2017-09-11 08:49 PM
Hi Daniel,
I found the same problem but it has been solved by calling
SystemInit ( see in system_stm32f7xxx.c ) on Init
int Init( void )
{ __disable_irq( );SystemInit( );
.....
}
I don't know why N25Q256A_STM32L476G-EVAL_Cube works without SystemInit.
May this help you too.