Skip to content
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

Implement flash read/erase/program #239

Closed
wants to merge 1 commit into from
Closed

Conversation

astro
Copy link
Member

@astro astro commented Dec 10, 2020

No description provided.

@astro astro force-pushed the flash branch 5 times, most recently from b5532de to 45d804d Compare December 13, 2020 00:12
@astro astro changed the title [WIP] Implement flash read/erase/program Implement flash read/erase/program Dec 13, 2020
Copy link
Member

@thalesfragoso thalesfragoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, nice work. I left a few comments, but something that I didn't quite understand from the manual is this:

It is not allowed to program data to the Flash memory that would cross the 128-bit row
boundary. In such a case, the write operation is not performed and a program alignment
error flag (PGAERR) is set in the FLASH_SR register.

This seems to bound the programming operation to a maximum of 64 16 bytes (and all inside the same 128-bit aligned "row"), I see that you are checking for this error, but I think this is also important to document.

And also, missing changelog entry.

src/flash.rs Outdated Show resolved Hide resolved
src/flash.rs Outdated Show resolved Hide resolved
@astro astro force-pushed the flash branch 2 times, most recently from a34e0de to 72ae805 Compare December 13, 2020 21:00
@astro
Copy link
Member Author

astro commented Dec 13, 2020

I have now taken care of the 128-bit row alignment, and added a changelog entry.

@TheRealBluesun
Copy link

Really well-structured, nice work! This makes me want to migrate your work to the stm32f1xx-hal crate as well 😄.

Were you working on read/write protection? If not, I'll gladly take that up. I just "finished" a basic implementation for the stm32f1xx-hal, I imagine the F4 is very similar.

Hope to see this merged soon!

/// aligned to 128-bit rows
pub fn program<I>(&mut self, mut offset: usize, mut bytes: I) -> Result<(), Error>
where
I: Iterator<Item = u8>,
Copy link

@TheRealBluesun TheRealBluesun Dec 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this may be more easily used as IntoIterator<Item = &'a u8>.

That or just change bytes to a slice?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't Iterator more flexible than IntoInterator ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. IntoIterator allows you to work with collection types as well as Iterator (which automatically implements IntoIterator) which is super-handy (but probably not that important in this particular usecase).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, just realized that the suggestion was with Item = &'a u8

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be best to just pass a &[u8], even. Ultimately, I don't think you gain much by using IntoIter<Item = &u8> really. Definitely willing to be convinced (insofar as my opinion matters, hah!).


impl FlashExt for FLASH {
fn address(&self) -> usize {
0x0800_0000
Copy link

@TheRealBluesun TheRealBluesun Dec 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be a static fn instead? Same question applies to len().

This could allow for FlashExt::read() to also be static.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read needs to borrow self, otherwise the user would be able to have a & and &mut to the same memory.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, not &mut, but they would be able to mutate the memory while it has a live immutable reference to it.

Copy link

@TheRealBluesun TheRealBluesun Jan 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read needs to borrow self, otherwise the user would be able to have a & and &mut to the same memory.
Sorry, not &mut, but they would be able to mutate the memory while it has a live immutable reference to it.

EDIT: Disregard

I don't think you're carrying around a reference to memory, though; only the results of a read (i.e. copied bytes). I believe I see what you mean if you think of the entirety of Flash as an object to which you have a slice into, but I don't think very much is gained from treating it that way. I'm really curious to hear what you/others think about it. I do see how this could become a problem in environments where two threads could simultaneously access flash, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean if you think of the entirety of Flash as an object to which you have a slice into, but I don't think very much is gained from treating it that way.

read is doing exactly that, it gives the user a &[u8] pointing directly to flash memory. Without the borrow, the user would be able to create an UnlockedFlash and modify the flash contents, and then use the same &[u8] after, which is UB in rust, since you can't mutable alias with references.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read doesn't copy. But even if it did (which isn't really desirable), without borrowing Self you couldn't prevent the user from using read on main and program in an interrupt, which is a data race.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right -- I was thinking of my own implementation for read(), not the one included here 🤦‍♂️ . Apologies.

@therealprof therealprof marked this pull request as draft January 10, 2021 14:16
@therealprof
Copy link
Member

@astro Thanks for the PR. I like the ideas proposed by @TheRealBluesun, what are your opinions on that? Also the unsafe warnings are a bit curious; I haven't checked whether they're actually valid or caused by differences in the patched SVD files.

@xoviat
Copy link
Contributor

xoviat commented Mar 27, 2021

@therealprof Is there an update on this?

@therealprof
Copy link
Member

@therealprof Is there an update on this?

@thalesfragoso needs to withdraw the concern, otherwise bors will not let me merge it.

@burrbull
Copy link
Member

burrbull commented Jul 5, 2021

What status of this?

@samcrow
Copy link
Contributor

samcrow commented Jul 8, 2021

I have no authority here, but I've been using a forked version with these changes for a while with no problems. I'd love to see this merged so I can switch back to the main (non-forked) source.

Can I do anything to help with this? Do we need someone to create a new pull request with the same changes that won't be stuck?

@burrbull
Copy link
Member

burrbull commented Jul 8, 2021

The code looks good enough for me.
I can merge this after rebase and fixing warnings (inc. clippy) if they are present.

I: Iterator<Item = u8>,
{
let ptr = self.flash.address() as *mut u8;
let mut bytes_written = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the use of bytes_written ?

@thalesfragoso
Copy link
Member

We probably should change the IntoInterator thing to use Item = &u8, update the branch and get rid of the warnings, I suggest getting in touch with the author and/or creating a new PR on top of this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants