Concept question: how to flash external SPI memory for XiP – Embedded


Hey,

I’m totally new to rust, and advanced beginner in embedded programming. I understood the concept of eXecute-in-Place for external flash: a bootloader

  • configures the MCU to access the external flash (SPI peripheral),
  • configures the external flash chip,
  • sets up memory-mapped mode,
  • passes the execution to the entry point of my program on the external flash

So far I’m believed capable to implement that in rust.
But how can I get my application into the external flash? Memory-mapped mode is everywhere reported as read-only (here, here).
I have no other memory to hold the whole application – no internal Flash or RAM big enough, no SD card attached.
So, I think, there’s a need for some MCU-local application to receive the binary application and write it through the SPI interface into the external flash memory. Is this some kind of bridge between the JTAG/SWD interface and the external flash? Is there something like this already available in rust? Or is there any other common way of flashing external memory “through” the target controller and how fits that into my desktop rust toolchain? (I use VScode, rust-analyzer extension and probe-rs, if that matters.)

Thank You very much.

you don’t need “big” RAM, as long your RAM is enough to hold one page of flash data (and a handful of CPU instructions), the debug probe can just download a small program to the RAM, and transfer the data page by page.

typical QSPI nor flash chips (unlike massive NAND flash devices), the page size is not that big at all, typically . in fact, although you have to erase the flash in sectors (usually multiple pages depending on the chip), most of them can be written one word a time, or even one byte a time, it’s just you typically write a whole page using bulk transfer.

the XiP is mode normally configured by the SDK or bootloader, and when you flash your firmware, the device should not enter XiP mode.

but you don’t need to do this low level thing most of the time, debug probes (jlink, stlink, etc, or in this case, probe-rs) will do it transparently for you. for example, probe-rs support most commonly used SoCs out of the box, you just tell it the chip model. even if you have a chip not supported, you can write a custom flashing program. see the list (with link to a flashing algorithm template project) here:

https://probe.rs/targets/

Ok, thank You very much. A little bit too deep already for me. :wink:
I understand about pages and sectors, my page size is 256 B, sector size is 4096 B.
Also, I know how to tell probe-rs my target (I wrote some small rust programs and can run them fine from the internal flash) and I see my target on probe-rs – targets. But there are only internal memory regions configured. No SPI configurations, neither MCU-side, nor memory-chip-side.
My external SPI flash has no memory region until it is configured in memory-mapped mode, and then it is read-only afaik.

So, I doubt, that probe-rs can magically program an external SPI flash. In case, it can, good news for me, but can You explain that concept any further? For instance, what entity is driving the SPI flash, i.e. sending write commands to it, when I send my binary via probe-rs?

Thanks a lot and hopefully I didn’t miss something obvious. But that’s why I’m asking more on the conceptual side of the whole mechanism.



Source link

Leave a Comment