embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.15k stars 713 forks source link

STMG4 Dual Bank Flash support #2309

Open tomasbarton-stemcell opened 8 months ago

tomasbarton-stemcell commented 8 months ago

I have noticed that STMG4 support was added a few days ago:

https://github.com/embassy-rs/embassy/pull/2294

However, this PR is not going to work correctly on dual bank flash MCUs such as STM32G474VE that I work with. The reason is that dual bank mode uses 2KB page size while single bank uses 4K pages.

image

I worked around this issue by deleting two pages on each call to blocking_erase_sector when I was implementing embassy bootloader several weeks ago. Additionally errata 2.2.2 should be implemented (I reused the same code from f4.rs/save_data_cache_state() as the workaround procedure is the same). Other functions beside erasing the sector work without changes.

(btw I have not tested the PR, however I took the same approach as the author and reused the code from g0.rs so I assume that there are the same issues I faced.)

dgehriger commented 3 months ago

@tomasbarton-stemcell : I'm using the STM32G491RE, which has the same memory layout and modes. I'm unsure about the meaning of your message. Are you saying that the swap algorithm won't work for these chips? If so, do you have a fix, and could you possibly post it? Thank you!

tomasbarton-stemcell commented 3 months ago

I have a quick and dirty fix here: https://github.com/embassy-rs/embassy/pull/2946/files

It works, but I haven't had a chance to clean this up yet

tomasbarton-stemcell commented 3 months ago

@tomasbarton-stemcell : I'm using the STM32G491RE, which has the same memory layout and modes. I'm unsure about the meaning of your message.

The problem is that the current Embassy code assumes single bank mode with 4KB sectors, however the chip by default uses dual bank mode with 2KB pages.

So my solution to get this working quickly was to modify the code in such a way that the erase function erases 2 2KB sectors for each 4KB sector call. The write function does not care about the page size. Another solution might be to switch the chip to single bank mode (I could not do that since I need double bank for something else)

Dirbaio commented 3 months ago

note G4 in dualbank mode has a hole in the address space between the two banks (except in the chips with max amount of flash). You can't pretend the two banks form a single contiguous flash region.

Even worse, all G4 chips are actually the same silicon die, so they actually all have the max amount of flash. The "hole" in the address space is actually working flash that you can use, but is "untested, not guaranteed to work" according to ST. So you might have the wrong memory.x but never notice because it works anyway.

If you don't need dualbank and want one contiguous chunk of flash, you really should actually turn off dualbank.

dgehriger commented 3 months ago

Thanks for the follow up! Maybe I'm missing something, but in the specific case of the STM32G491RE, which has 512K (2 x 256K in dual-bank config), the flash driver should work just fine in dual-bank mode.

If you look at https://github.com/embassy-rs/stm32-data-generated/blob/main/stm32-metapac/src/chips/stm32g491re/metadata.rs, the erase_size is "correctly" specified as 2048, and since there isn't a gap, the two banks are simply a contiguous memory block of 512K.

So, again for this chip specifically, using dualbank mode will work with the embassy Flash driver.

Dirbaio commented 3 months ago

yeah it happens to work fine if your chip has 512K which is the max amount, because then there's no hole.