2025-07-28 6:17 AM - last edited on 2025-07-28 6:37 AM by Andrew Neil
Hello
hope some one can shed some light please,
I have a STM32F446RE board with SPI1 setup for 8pin SPI FRAM memory
I have written my own firmware using DMA / SPI1 to read and write to this FRAM IC
This is a very fast no volatile memory IC that does not have the limitations of standard FLASH memory
Reading and Writing continuously SPI1 40MHz speed
It does not require or use Block / Page / Sector , polling, time delays for write etc.
Its just continually allows write at very high speed, so eliminates all the pain of poor endurance, latency of normal serial flash memory.
Can I find an external flash loader routine for this type of memory so I can use STcube programmer to load the FRAM with my custom data, of course not ????
Could someone please advise in very basic steps how to create a flash loader for my ST32446
I have tried looking at various flash files / github etc. but there is so much code relative to page size, block size, sector size etc. None of that is applicable for me
Just need to be able to read and write to the SPI, from cube programmer
please can someone advise how to make a simple external loader
Thank you
2025-07-29 3:41 AM
To write my own code to program FRAM
I would like to consider the following considerations ?
1) It would be efficient to use DMA for both SPI & UART for larger block transfer of data
2) How can I not waste great deals of 446 memory setting up buffers for the full size of the FRAM if i wanted to program the whole FRAM memory ?
or should I only work on smaller parts of the FRAM at a timer and program it in blocks ?? thus lowering the buffer sizes allocated to copy UART to FRAM.
I would like to ensure I am not using up precious STM32F446 resources for a one time operational process of programming FRAM
hope this makes sense
thank you
2025-07-29 3:42 AM
FRAM is 512Kbit 64K x 8
2025-07-29 12:06 PM - edited 2025-07-29 12:12 PM
1) I don't think your parts permit memory mapped operation, which is why I said pseudo-address, because you a) need a target address for your linker to construct a combined object file, and b) STM32 Cube Programmer needs and "address / range" with which to associate your External Loader. It knows 0x08000000 is internal FLASH memory, so some place else. The address decoders start by using the top 4-bits to ascribe different memory and peripherals.
2) The External Loader is basically a DLL that loads into the STM32's RAM and executes code to configure / communicate with hardware, pins, etc which are outside of THEIR control. ie stuff you've made up for you unique implementation.
3) The External Loader has a header providing geometry details, and this can impact how it interacts. BUT it passes Read() / Write() address and size information, and you're STILL responsible for de-blocking that per the device requirements. ie For QSPI NOR FLASH the page buffer is only 256-bytes, so lengths must be truncated and decomposed, such that you don't span the device's boundaries. Typically it uses the remaining internal RAM, not consumed by the loader/stack to hold a ping-pong buffer, so loading one with content whilst write the other to the device.
4 / 8) Do Segger J-Links work, supposedly. The programmer is going thru the JTAG/SWD interfaces to load data/code into memory and cause the MCU to execute it.
5) You can't debug in a debugger. You can make an application space shim or framework to TEST the functionality of your code, and exercise the entry points / functionality. You can however use any hardware on your board at your discression, ie UARTs, LEDs, Screens, whatever.
6) The MCU will fault if you touch it's memory space, and it's not physically decoding it. So wrap your functions to mask off the high order bits, because you're only interacting with your memory via it's own zero-address based decoding. You obfuscate this via your Read() Write() routines. The source buffer passed to you will be in RAM.
7) You provide the Init() function to bring up the chip, the pins, etc. Your Read() and Write() are basically behaving like memcpy() function which you are wrapping using the functions you already have to read / write your memory device. Imagine you're writing your own application code / library that accesses the memory, and exporting functions for others to use.
2025-07-29 12:18 PM
>>would you suggest using uart peripheral as the preferred method of sending a hex file to the FRAM, it seems the simplest method to me, but always open for suggestions.
You can write whatever application side code you want. If you provide for a serial XMODEM type function you can just send binaries, or whatever that way. ST has "IAP" In-application Programming examples using Y-MODEM. Others pulling data/binaries of SD Cards or USB Flash Sticks, you'd have to pull in File System code too, ie FATFS.
You could make your FRAM appear as a USB-MSC as an FRAM-DISK and you map your read/write code to manage access as a block device with 512-byte sectors.
2025-07-29 12:26 PM
1) DMA and IRQ tend to complicate things, and with QSPI NOR FLASH aren't particularly helpful in improving speed, as the choke points come from other sources, ie waiting for the memory to complete it's operation.
2) you don't need to use the full size, you break things down into blocks, X-MODEM is typically 1024 bytes, but older versions can be 128 byte. It's self pacing as it has it's own flow control and integrity checking, and retry methods. Buffer things in a way that's effective for you.
You can also do staged-loaders, ie your application just has to facilitate code upload to RAM, and then you can call it. That way the only full-time foot-print is for the upload/execution of the next stage. You'd typically do this early in your boot process so all memory/resources are available prior to application execution, so you're not sharing resources or concerned about conflicts or breaking things.
2025-07-29 12:30 PM
So it is only 64 K bytes. Even with slow SPI and UART, nothing to worry about.