-
Notifications
You must be signed in to change notification settings - Fork 234
Storage Traits for on and off board storage #241
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
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @eldruin (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
hey thanks for the PR, this looks like a super useful abstraction! (and i needed it this week 😂) i am not completely sure whether this is the right level to include in the embedded-hal or not, though it would be great to have a standard flash API for HAL implementations which is a serious point in favour. as it is a reasonably complex abstraction i suspect that there remains some room for experimentation (and some changes may occur during this), so i think my preference at this time would be to create a @rust-embedded/hal how do y'all feel like this, and is it worth a discussion at the next meeting about formalising the experimental-crate approach a bit more? a few miscellaneous thoughts:
|
While the inspiration is that issue, the goal is absolutely a generic storage traits that aren't flash specific. |
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.
Thank you for this PR.
I agree with @ryankurte. I would really like this merged but I also think it still needs a couple iterations. Whether that needs to be done in a separate crate I do not really care.
More thoughts:
- Non-blocking
All methods offer a non-blocking interface. While that makes sense since storage devices take a while to complete, both implementations presented above are actually blocking.
It would be interesting to see how real non-blocking implementations look like. - Paging
The eeprom24x implementation just writes one byte at a time. It would be interesting to see how a more advanced implementation would look like, where actual arrays are written and how to deal with page boundaries, specially in the face of a non-blocking operation. - Storage size
I am also wondering if stateful fallible methods are necessary here or if this can be determined at compile time and associated constants would do just as well.
Anyway example implementations are necessary here. - Example implementation for eeprom24x
This is simple: I think it would be better to implement the storage traits in a separate file. I think this would be easier for other people to understand what the addition is without having to look at the diff.
src/storage.rs
Outdated
/// Allows for Read Only Memory as well as Read and Write Memory | ||
use nb; | ||
|
||
/// Address represents an unsigned int. This allows for devices that have bigger or smaller address spaces than the host. |
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.
nitpick: I would rather refer to an "unsigned integer" (also below)
src/storage.rs
Outdated
type Error; | ||
|
||
/// Erase the page of memory | ||
/// For flash devices, this sets the whole page to 0xFF |
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.
I also think the reset value is probably better left to implementations. Anything written in the documentation of the trait would be part of a contract. (also below)
src/storage.rs
Outdated
type Error; | ||
|
||
/// Returns the start address and the maximum size that can be stored by the device | ||
fn try_total_size(&mut self) -> nb::Result<(Address<U>, AddressOffset<U>), Self::Error>; |
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.
I think two different methods may be better, since it would be fairly easy to make a mistake.
use core::ops::Add; | ||
|
||
/// Implement add for the Address and AddressOffset Types. | ||
impl<'a, 'b, U> Add<&'b AddressOffset<U>> for &'a Address<U> |
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.
Subtraction of an offset from an address is probably also interesting. And if we already at it, maybe addition and subtraction of address offsets. However I start wondering where to stop :) and then if it makes sense to include these implementations at all since the user already needs to deal with the inner values.
src/storage.rs
Outdated
} | ||
|
||
/// Page represents an unsigned int that is a Page ID in the device memory space. | ||
pub struct Page<U>(U); |
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.
I am wondering about a conversion from Page
to Address
but I guess the best way would be adding a From
implementation and that is something that needs to be done in the implementation and not nicely enforcible here.
I think the SPI flash chip library is non blocking. I'll have a crack at that. |
What I have done so far:
What I am planning to do next:
|
I think it would make sense to make Also i think it makes sense to be able to sub two addresses? very common way of getting a length? |
What do you think about starting with a new crate to get this going? I think something like After some time it could still be merging into embedded-hal. |
@Sympatron I think that is the right approach! Currently i am forcing all of my crates into separate branches just to use a storage branch here, and it doesn't quite make sense. Maybe it would make sense to get @eldruin to create it in |
I'm happy to support which ever solution works best for the community. I do have a bit of time this weekend. |
|
I have created this: https://github.com/BlackbirdHQ/embedded-storage in an attempt to bring this forward, knowingly that it does not address all our issues, but at least it is a starting point for discussions.. It is currently a 1:1 copy of #248 I would love to see it become part of the embedded-rust-community, but had to start it somewhere else..? @eldruin If you would be okay with it, i can transfer it? |
@MathiasKoch sure thing. It would be great if this triggers a development impulse like with |
Awesome! Let me introduce: https://github.com/rust-embedded-community/embedded-storage @eldruin can you close #28 with a reference to the new repo? |
Now moved to rust-embedded-community/embedded-storage#8 so closing off for now. |
Closes #28
These are a set of traits that can be used for on and off board storage.
Each function is split into its own trait to deal with the different types of memory (Particularly Read Only vs Read/Write)
MCU Flash impl:
https://github.com/tl8roy/alt-stm32f30x-hal/blob/master/src/storage.rs
I2C EEPROM impl:
https://github.com/tl8roy/eeprom24x-rs/blob/master/src/eeprom24x.rs
SPI PSRAM implementation:
https://github.com/tl8roy/esp_psram
This is a completely new implementation using SPI.
Feedback has come from #28, diondokter/device-driver#1 and twitter https://twitter.com/tl8roy/status/1287254634512310272