-
Notifications
You must be signed in to change notification settings - Fork 25
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
Rework NorFlash & Storage traits #12
Conversation
1078baa
to
7667a56
Compare
7667a56
to
3eb1428
Compare
f9dd1de
to
adf0f9d
Compare
I think the latest change her addresses most of the concerns people have highlighted, with some limitations?
#13 Should also be addressed by this Stuff left to figure out:
Limitations:
|
To get rid of that error, add
Maybe given this the best way to go is make it generic? I'm not a fan of adding even more generic params but maybe it's the best option :S
I'd say yes. Makes using traits harder otherwise, and I don't think it adds anything of value :|
No idea 🤷 I somewhat prefer a non_exhaustive Enum instead of a |
@Dirbaio Hmm, i can't seem to make the
On the error part how about something like pub enum Error<E> {
CommonErrors,
...,
Custom(E)
}
pub trait NorFlash: ReadNorFlash {
type UserError: Debug;
fn try_write(&mut self, address: u32, bytes: &[u8]) -> Result<(), Error<Self::UserError>> {
...
}
} That way it should be easy to just make |
Do you have the code somewhere? I can try taking a look |
…ase sizes. Split traits into Read and ReadWrite versions
adf0f9d
to
5943283
Compare
Wow, I think it's not possible with the 1.51 min_const_generics. It does work with these features:
An alternative is something like |
Hmm, how would i propagate this PR the remaining distance? It seems like all it is missing is
|
No strong opinion on errors, we could leave it as it is now which is the same as embedded-hal, and revisit it later once it's revisited in embedded-hal? Not sure what to do about the merge buffer. Maybe have the user pass a Is the What's the usecase for Region and OverlapIterator now that we've dropped support for multiregion flash? |
Sounds good, that was exactly my point with postponing it
I think that sounds like a decent tradeoff, i'll see if i can make it work in an elegant way tomorrow.
Not necessarily. Personally i wont be needing it, but it sounded like @Sympatron could make use of it, as it does improve the worst-case performance quite a bit.
Good point! I think they are leftovers from the past.. I'll remove them if they are not needed. |
I agree with @Dirbaio about the errors.
This might be a good idea, but I don't quite see how to get there... Wouldn't you either have to modify the trait or let the storage own the buffer (i.e. provide one with I think |
Yes, I'd do that. It also opens the possibility of optimizations like coalescing multiple writes? When writing load the page from flash into the buffer and apply the modifications but don't write it to flash yet. On next writes, if they're to the same page apply them to the buffer. If they're to other pages, write out the previous page first. The downside is it'd need a flush() method to ensure the last write is actually written out... |
Hmm, at first-hand we seem to run into a double mutable borrow at |
Shouldn't it do try_read on the inner NorFlash, not on self? |
That would make sense yes :p Missing the obvious here! |
deec732
to
95a1196
Compare
@Dirbaio @Sympatron It could probably do with a bit more doc-comments scattered around, so i will se if i can get around to that. One thing. Do you guys prefer |
…e atleast EraseSize long. Introduce RmwMultiwriteNorFlashStorage
95a1196
to
363bce3
Compare
…sh rather than NorFlash
1a3571b
to
931eb63
Compare
…rom peripheral base address
a2fc00c
to
ac8492b
Compare
@Dirbaio @eldruin @Sympatron |
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.
Other than my comments, looks good to me! However, I have no experience with NOR.
Co-authored-by: Diego Barrios Romero <[email protected]>
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.
Looks good to me! (NOR not reviewed)
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.
Reviewed NOR flash stuff. Traits look great modulo a few minor doc nits.
Maybe it's best to add the RMW Storage impls in a later PR, so we don't block the traits release?
I also wonder if the RMW impls might be more readable using index loops and copy_from_slice instead of iterators
src/nor_flash.rs
Outdated
// Check if we can write the data block directly, under the limitations imposed by NorFlash: | ||
// - We can only change 1's to 0's | ||
if is_subset { | ||
self.storage.try_write(addr, data)?; |
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.
This may fail if addr or data len is not a multiple of WRITE_SIZE. For example with a WRITE_SIZE of 4 (like on nrf52s) it'd fail if you try to write a single byte.
Fortunately this is possible to do by "padding" to WRITE_SIZE with 0xFF
s. For example, if you want to write 0x42
to offset 1, you can do so by writing 0xFF 0x42 0xFF 0xFF
to offset 0.
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 this part solves it, if am not mistaken? But it might be possible to do it smarter?
@Dirbaio Thanks for the great comments! I will address them as soon as i get a moment of time ;) |
…mbedded-storage into storage-rework
cb66428
to
e02bda5
Compare
src/nor_flash.rs
Outdated
let offset = addr as usize % S::WRITE_SIZE; | ||
self.merge_buffer[..S::WRITE_SIZE] | ||
.iter_mut() | ||
.for_each(|c| *c = 0u8); |
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.
shouldn't this be 0xFF? 0x00 will set all bits to 0, 0xFF leaves them untouched.
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.
Also you could use .fill(0xff)
instead of using iterators :)
Same for the copies, you could use .copy_from_slice()
which compiles to a memcpy. I don't think the compiler is able to optimize the iterator version to a memcpy.
src/nor_flash.rs
Outdated
self.merge_buffer[..S::WRITE_SIZE] | ||
.iter_mut() | ||
.skip(offset) | ||
.zip(data) |
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.
Not sure this is correct, data
may be bigger than WRITE_SIZE
since it's chunked by ERASE_SIZE
...
I have extracted the Rmw implementations to their own PR #14. Can we merge and release the traits here? |
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.
Aside for the nitpicks, looks good to me!
src/lib.rs
Outdated
/// | ||
/// (start_addr, end_addr) | ||
fn range(&self) -> (Address, Address); | ||
/// This should throw an error in case `bytes.len()` will be larger than |
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.
Could you fix the tab usage clippy warning here?
Cargo.toml
Outdated
@@ -15,6 +15,4 @@ keywords = ["storage"] | |||
categories = ["embedded", "hardware-support", "no-std"] | |||
|
|||
[dependencies] | |||
nb = "1" | |||
no-std-net = "0.4" | |||
heapless = "^0.5" |
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.
Can we bump heapless? The latest version (0.7) requires 1.51.0, though, due to const-generics.
@MathiasKoch I think it is good to go. |
The
RmwNorFlashStorage
implementation might be possible to improve? Please consider that as my crude first attempt. It is tested and works though. I am not 100% into thewrite_size
/erase_size
usage, so please correct me on those.I have added an implementation of
RmwNorFlashStorage
that should be able to utilizeMultiwriteNorFlash
as well, but it is still untested. Also it requires rust-lang/rust#31844 to live alongside the implementation without multiwrite.I currently have an implementation for STM32L4xx_HAL if you are interested.
This is my attempt to encapsulate the discussion going on, so please keep it coming!
@eldruin @Sympatron