-
Notifications
You must be signed in to change notification settings - Fork 882
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(embassy-rp): Implementation of generic flash mutation access #951
Conversation
a9052dd
to
feb840c
Compare
Oof this is cursed. I guess yes, or this will be a problem when DMAing from flash.
If the flash code globally disables irqs and stops the other core you have the guarantee that no other code will race you, so you can go ahead and do it unsafely I guess...
Yes... Also, are we sure EN=0/EN=1 pauses/resumes the channel fully seamlessly? Alternatively we can disallow DMAing from flash... nRF has this limitation in hardware and it's not that bad, it means you have to copy through a RAM buffer though. Perhaps it could be feature-gated, so you can either "DMA from flash" OR "write to flash", but not both in the same binary...
In the final version yes, but I'd say it's OK to not do it for now since we don't support muticore yet. Note that code resets core2, we want to pause it instead. It'd have to send an irq to the other core (using the FIFO maybe) so that the other core "parks" itself in a RAM irq handler. Also note it's possible to do flash ops from core2, in this case it should park core1 😓 .
Cargo features with a range of possible options? :P They're always powers of 2 so there shouldn't be too many "reasonable" options...? |
From the RP2040 datasheet:
As I read that, it actually fully pauses any ongoing transfer, so I don't think this is too bad.
Noted.
Hmm, yeah. I'm not super fond of that way of doing it. It just doesn't seem to scale very well :( |
Although a slightly different situation, I've had a similar dilemma in embassy-boot generalizing these, and ended up using const generics for them. What about a combination that allows both uses: a GenericFlash using const generics, and a type alias |
That was actually exactly what I was thinking about. |
Compiler will infer a different lifetime for BootFlash than for the borrowed flash, which makes it require more type annotations than if it was just owning the type. Since it doesn't really matter if it owns or borrows in practical use, change it to own so that it simplifies usage.
Fixes a bug in the partition assertions that ensures that the state page(s) have enough space for 2x active partition range. Add unit test to verify that panic is observed.
Removes feature(generic_associated_types)
…ata functions, which are now part of this HAL as well
It should be one or the other. Having 2 ways of doing the same thing is very confusing. |
Given the kind of extreme limitations of the rom-data flash API, that aims at wide flash support, my suggestion would be to make a repo similar to https://github.com/rp-rs/flash-algo where we can implement a few different implementations (QSPI, Dual-SPI, SPI) in various configurations, compile and link them fully for RAM, and then Then we can do fallback to the flash API in rom-data, if users do not wish the added flash size of an optimized flash API. EDIT: Limitations here being the
W.R.T flash configurations & cargo features vs const generics, how about adding a "custom" peripheral for flash, such that you can only instantiate it once (panic on re-entrance), where you can pass flash-size, erase-size etc., and then you would have to pass around the flash struct like all other microcontrollers? |
Sounds good to me! 👍 I think having to write RAM-linked "flash driver" blobs is inevitable given the ROM limitations...
Not sure what you mean by "custom"? I'd make a normal FLASH peripheral (just the singleton struct, no functionality) and then a Flash driver that you pass all that config when creating it. If we do this, the API would have the same structure as any other peripheral. |
By custom i just meant that it does not come from a pac peripheral. Not sure what the requirements are for the |
Ah! then all our peripherals are already "custom". They're all invented by the HAL, we don't use the PAC ownership model. (rp and stm32 PACs don't have owned singletons at all because they're generated by chiptool. nrf PACs do because we're using the |
Perhaps it would make sense to just have the RAM-blobs implement the CMSIS-Pack ABI? That way it would be re-usable by probe-rs once they figure out how they want to tackle probe-rs/probe-rs#1212 |
@Dirbaio Ready for merge! In case you didn't see it on matrix, I figured out the issue was due to the RTT header residing in flash:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bors d+
✌️ MathiasKoch can now approve this pull request. To approve and merge a pull request, simply reply with |
bors r+ |
bors r- |
Canceled. |
bors r+ |
951: (embassy-rp): Implementation of generic flash mutation access r=MathiasKoch a=MathiasKoch I have attempted to utilize the work done in `rp2040-flash` by implementing `embedded-storage` traits on top, for RP2040. Concerns: 1. ~~Should the DMA be paused where I have put a FIXME note? `DMA_CHx.ctrl_trig().write(|w| { w.set_en(false) })`? If so, how to properly do that without have control over the peripheral for the DMA channels? And if so, I assume we should only re-enable/unpause the ones that were enabled before?~~ 2. ~~Should I make sure core2 is halted as part of this code? I am not sure if https://github.com/jannic/rp2040-flash/blob/ea8ab1ac807a7ab2b28a18bb5ca2e42495bb744d/examples/flash_example.rs#L103-L109 is heavy/slow code to run?~~ 3. ~~Any good way of making this configurable over `FLASH_SIZE`, `WRITE_SIZE` and `ERASE_SIZE` without doing it as generics or parameters, as those make it possible to do differing configs throughout the same program, which feels wrong? Preferably, a compile-time option?~~ **EDIT:** I have implemented the flash API here under the assumption that all external QSPI nor flashes are infact `Multiwrite` capable, as this makes it possible to use the ROM function for writes of 1 bytes at a time. I have also added a HIL test for this, but because HIL tests are running 100% from RAM and I wanted to make sure it still works when running from flash, I have also added an example testing erase/write cycles of entire sectors, as well as single bytes in multi-write style. Ping `@Dirbaio` Co-authored-by: Mathias <mk@blackbird.online> Co-authored-by: Vincent Stakenburg <v.stakenburg@sinewave.nl> Co-authored-by: Joakim Hulthe <joakim@hulthe.net> Co-authored-by: Alex Martens <alex@thinglab.org> Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com> Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Build failed: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work 🚀
bors r+ |
951: (embassy-rp): Implementation of generic flash mutation access r=MathiasKoch a=MathiasKoch I have attempted to utilize the work done in `rp2040-flash` by implementing `embedded-storage` traits on top, for RP2040. Concerns: 1. ~~Should the DMA be paused where I have put a FIXME note? `DMA_CHx.ctrl_trig().write(|w| { w.set_en(false) })`? If so, how to properly do that without have control over the peripheral for the DMA channels? And if so, I assume we should only re-enable/unpause the ones that were enabled before?~~ 2. ~~Should I make sure core2 is halted as part of this code? I am not sure if https://github.com/jannic/rp2040-flash/blob/ea8ab1ac807a7ab2b28a18bb5ca2e42495bb744d/examples/flash_example.rs#L103-L109 is heavy/slow code to run?~~ 3. ~~Any good way of making this configurable over `FLASH_SIZE`, `WRITE_SIZE` and `ERASE_SIZE` without doing it as generics or parameters, as those make it possible to do differing configs throughout the same program, which feels wrong? Preferably, a compile-time option?~~ **EDIT:** I have implemented the flash API here under the assumption that all external QSPI nor flashes are infact `Multiwrite` capable, as this makes it possible to use the ROM function for writes of 1 bytes at a time. I have also added a HIL test for this, but because HIL tests are running 100% from RAM and I wanted to make sure it still works when running from flash, I have also added an example testing erase/write cycles of entire sectors, as well as single bytes in multi-write style. Ping `@Dirbaio` Co-authored-by: Mathias <mk@blackbird.online> Co-authored-by: Vincent Stakenburg <v.stakenburg@sinewave.nl> Co-authored-by: Joakim Hulthe <joakim@hulthe.net> Co-authored-by: Alex Martens <alex@thinglab.org> Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com> Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Build failed: |
1b727a0
to
bc21b6e
Compare
bors r+ |
951: (embassy-rp): Implementation of generic flash mutation access r=MathiasKoch a=MathiasKoch I have attempted to utilize the work done in `rp2040-flash` by implementing `embedded-storage` traits on top, for RP2040. Concerns: 1. ~~Should the DMA be paused where I have put a FIXME note? `DMA_CHx.ctrl_trig().write(|w| { w.set_en(false) })`? If so, how to properly do that without have control over the peripheral for the DMA channels? And if so, I assume we should only re-enable/unpause the ones that were enabled before?~~ 2. ~~Should I make sure core2 is halted as part of this code? I am not sure if https://github.com/jannic/rp2040-flash/blob/ea8ab1ac807a7ab2b28a18bb5ca2e42495bb744d/examples/flash_example.rs#L103-L109 is heavy/slow code to run?~~ 3. ~~Any good way of making this configurable over `FLASH_SIZE`, `WRITE_SIZE` and `ERASE_SIZE` without doing it as generics or parameters, as those make it possible to do differing configs throughout the same program, which feels wrong? Preferably, a compile-time option?~~ **EDIT:** I have implemented the flash API here under the assumption that all external QSPI nor flashes are infact `Multiwrite` capable, as this makes it possible to use the ROM function for writes of 1 bytes at a time. I have also added a HIL test for this, but because HIL tests are running 100% from RAM and I wanted to make sure it still works when running from flash, I have also added an example testing erase/write cycles of entire sectors, as well as single bytes in multi-write style. Ping `@Dirbaio` Co-authored-by: Mathias <mk@blackbird.online> Co-authored-by: Vincent Stakenburg <v.stakenburg@sinewave.nl> Co-authored-by: Joakim Hulthe <joakim@hulthe.net> Co-authored-by: Alex Martens <alex@thinglab.org> Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com> Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Build failed: |
I don't understand why the bors test is failing? |
the CI has a Pico W, not sure if it matters..? |
Hmm, can't see how that should matter :/ |
Hmm. I just tested it on a Pico I had lying around here (non W version), and it works great there as well. Teleprobe tests pass 100% of times. Not sure what is different with the CI, but I don't have a Pico W to test it on :( |
bors r+ |
951: (embassy-rp): Implementation of generic flash mutation access r=Dirbaio a=MathiasKoch I have attempted to utilize the work done in `rp2040-flash` by implementing `embedded-storage` traits on top, for RP2040. Concerns: 1. ~~Should the DMA be paused where I have put a FIXME note? `DMA_CHx.ctrl_trig().write(|w| { w.set_en(false) })`? If so, how to properly do that without have control over the peripheral for the DMA channels? And if so, I assume we should only re-enable/unpause the ones that were enabled before?~~ 2. ~~Should I make sure core2 is halted as part of this code? I am not sure if https://github.com/jannic/rp2040-flash/blob/ea8ab1ac807a7ab2b28a18bb5ca2e42495bb744d/examples/flash_example.rs#L103-L109 is heavy/slow code to run?~~ 3. ~~Any good way of making this configurable over `FLASH_SIZE`, `WRITE_SIZE` and `ERASE_SIZE` without doing it as generics or parameters, as those make it possible to do differing configs throughout the same program, which feels wrong? Preferably, a compile-time option?~~ **EDIT:** I have implemented the flash API here under the assumption that all external QSPI nor flashes are infact `Multiwrite` capable, as this makes it possible to use the ROM function for writes of 1 bytes at a time. I have also added a HIL test for this, but because HIL tests are running 100% from RAM and I wanted to make sure it still works when running from flash, I have also added an example testing erase/write cycles of entire sectors, as well as single bytes in multi-write style. Ping `@Dirbaio` Co-authored-by: Mathias <mk@blackbird.online> Co-authored-by: Vincent Stakenburg <v.stakenburg@sinewave.nl> Co-authored-by: Joakim Hulthe <joakim@hulthe.net> Co-authored-by: Alex Martens <alex@thinglab.org> Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com> Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Build failed: |
bors r+ |
Build succeeded: |
I have attempted to utilize the work done in
rp2040-flash
by implementingembedded-storage
traits on top, for RP2040.Concerns:
Should the DMA be paused where I have put a FIXME note?DMA_CHx.ctrl_trig().write(|w| { w.set_en(false) })
? If so, how to properly do that without have control over the peripheral for the DMA channels? And if so, I assume we should only re-enable/unpause the ones that were enabled before?Should I make sure core2 is halted as part of this code? I am not sure if https://github.com/jannic/rp2040-flash/blob/ea8ab1ac807a7ab2b28a18bb5ca2e42495bb744d/examples/flash_example.rs#L103-L109 is heavy/slow code to run?Any good way of making this configurable overFLASH_SIZE
,WRITE_SIZE
andERASE_SIZE
without doing it as generics or parameters, as those make it possible to do differing configs throughout the same program, which feels wrong? Preferably, a compile-time option?EDIT:
I have implemented the flash API here under the assumption that all external QSPI nor flashes are infact
Multiwrite
capable, as this makes it possible to use the ROM function for writes of 1 bytes at a time.I have also added a HIL test for this, but because HIL tests are running 100% from RAM and I wanted to make sure it still works when running from flash, I have also added an example testing erase/write cycles of entire sectors, as well as single bytes in multi-write style.
Ping @Dirbaio