2023-06-12 07:22 AM
Is it possible to copy data from an sdcard to an external qspi rom to be used as program rom (.romdata)? I am currently reading data from an sdcard card using fatfs to const program in the. (.data) section but it is a memory hog. Are there any examples of loading (or preloading) .romdata on an external qspi eprom?
2023-06-12 08:57 AM
Yes, possible. If you actually mean flash, not ROM.
There are some examples of memory mapping QSPI flash and running code.
There are also "BSP" drivers for several QSPI flash chips. You'll have to put that together.
2023-06-12 10:14 AM
Most any thing should be possible.
Use MicroSD cards as a staging medium here. Whether its .BIN, .HEX or .DFU, or whatever object file format you chose as your delivery method. FatFS is a tad more cumbersome than the STDIO file methods, but not impractically so. You need to be aware of the limitations/compromises made in the implementation, there's not a lot of caching or lazy writing of data you might be accustomed too on a PC with GB of memory, and sophisticated OS and driver stacks. Watch block sizes of the underlying media, and multiple small transactions at the application level.
QSPI NOR Flash can be used in a USB MSC sense too, so you can drag-n-drop content.
Speed tends to be limited by the erase/write timing of the NOR Flash, which is generally not particularly fast as it's optimized for reading.
2023-06-12 10:20 AM
I've already memory mapped the QSPI and the program code is mapped to the '.text' memory region of this with well as initialized constants in 'rodata' .
What I want to achieve is: To write to this area of memory (QSPI->.rodata) from an sdcard...
I'm sorry I have not being very clear .
The loader script is working as expected and the program runs fine.
So how do I best best write const variables into this memory mapped region in ".rodata" (typo not .romdata) from fatfs +sdmmc
Both the peripheral (sdmmc) and the library (fatfs) are a working as expected.
MEMORY{
...
QSPI (rx) : ORIGIN = 0x90000000, LENGTH = 8M
...}
JumpAddress = *(__IO uint32_t*) (OCTOSPI1_BASE+ 4);
JumpToApplication = (pFunction) JumpAddress;
2023-06-12 11:49 AM
Let me be a little more explicit:
Say I have an array 'uint16_t my_ram[SIZE]':
existing within the region
"RAM";"0x24000000";"";"768 KB".
at
".bss";"0x2403fc88";"";"272.84 KB"
and an empty const array:
const uint16_t my_rom[SIZE]
in the region
"QSPI:";"0x90000000";"";"8 MB"
at
".rodata";"0x9003b4e0";"0x9003b4e0";"272.84 "
'my_ram' is populated with data from an sdcard during program execution
I wish to copy 'my_ram' to 'my_rom' so that on reboot the data exists and is accessible within the c code as the const uint16_t my_rom[] array
I hope this is clearer.
Thanks for any help
2023-06-12 12:39 PM
I don't have a chip with OSPI, not sure if OSPI controller can write in memory mapped mode.
But QSPI cannot. So before write you need to switch the QSPI to normal "serial" mode.
In "serial" mode, of course, you cannot access the mapped window at 0x90000000.
Now consider that mapped address 0x90000000 corresponds to offset 0 of the flash (sector 0, offset 0).
Using the "BSP" driver for the QSPI flash (or your own driver if there's no ready one), write the data to the flash, from offset 0 and so on up to the array size. Verify the written data (compare, checksum...).
Then switch back to memory mapped mode and enjoy.
Remember that STM32H7 has data and instruction caches. Make sure they do not get in the way (discard before reading, call __isb() before jump ...)
2023-06-12 12:45 PM
Correct, you can't concurrently access the command space of the memory, and memory map it.
You have to HAL_OSPI_Abort() or similar, to kick it out of memory mapping, but then can't have code, data and interrupts using it.
I'd probably facilitate the update in a loader section of the system, then bring up memory/clocks for the MCU and external parts before transferring control to the application section. Boot back into the loader to update / copy, be a DFU or MSC device, etc
2023-06-13 03:46 AM
Great advice guys. I did play around with HAL_FLASH_Program and other related HAL_FLASH* functions last year and did all the unlocking memory fiasco but I gave up as I didn't need to use it at the time. I have another hacky way to do what I wish. I am just going to write out the contents of the array to UART and copy paste from the terminal to create a const array manually...
2023-06-13 05:14 AM
> I did play around with HAL_FLASH_Program
This is for internal flash. For QSPI flash, look in the Drivers/BSP/... or check collection of all their QSPI flash drivers for all boards on github.
If this looks confusing, unfamiliar or too hard, here you can find helping hands for your project.