-
Notifications
You must be signed in to change notification settings - Fork 2k
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
sam0 flashpage_write issue #7667
Comments
For a quick workaround, use |
Your workaround actually points to yet-another solution:
Is there an appetite for a PR for any of these solutions? I really do think one of them should be done, even it's just adjusting the documentation. I spent a good day of time pulling hair out with intermittent stack corruptions caused by this. |
Changing the argument type is not possible. That means an API change for the general periph flashpage interface, but this API is designed to be as platform agnostic as possible, and forcing the argument to uint32_t makes assumptions about the underlying hardware platform. |
Back to the original 3 then :) |
I agree this is an issue. It requires either an API change, with a per board alignment requirement, or a safe implementation. |
A non breaking API change is to add a |
I will work up a PR for proposed solution #3 if I had some assurances it wasn't going to rot on the review pile... just say go. |
@kaspar030 @kYc0o you have a grip on this issue, right? |
I can look into it after this week. |
@travisgriggs can you check if #7970 solves this issue? |
@PeterKietzmann : I believe that, at the time of this issue, there were a bunch of problems in the driver. One was the byte alignment issue (solved by #7970), one was the fact that a write has to be done in more steps (solved by #10069) and last but not least we weren't waiting also for chip to be ready (which was seemingly not a problem but the datasheet says we should, and maybe happens very seldom, solved in #10880). |
@fedepell thanks for the detailed report. Sounds like great improvement – so I'm gonna consider this issue as solved. |
This took a while to chase this down. On the samd21 issue, the flash page_write function casts the
void* data
argument to auint32_t*
pointer. This works fine when the compiler places the memory for your argument aligned. But I've found that it doesn't always. I was declaring aThe compiler was alternately placing this memory at
x20002402
orx20002400
. At the latter, the cast to auint32_t*
was fine, but at the former, chip level exception occured. This kind of bug is no fun to figure out.I have three proposals I'd like to consider for a fix. With some direction, I'll work up the appropriate PR.
Require a client side fix. In this case, we put the onus of getting the
data
argument 32bit aligned. One can use an expression like:static __attribute__((aligned(4))) u8 Row[NVMCTRL_ROW_SIZE];
to force the alignment. If this is the preferred solution, then the change that I believe should be made is the documentation of
flashpage_write()
should be modified to make this clear to those who decide to use this function.This is not my personally preferred solution.
Use
uint16_t
instead ofuint32_t
. I think it's OK to assume that memory is 2 byte aligned (see Interrupt-Handling on msp430 is buggy #3 otherwise).page_addr
anddata_addr
becomeuint16_t*
and the loop looks like:There is a pathological case where someone does not have the argument short aligned, e.g.:
In this case, it's again not safe to cast data as a
uint16_t*
. Sodata_addr
must become auint8_t*
(page_addr
remainsuint16_t*
). And the loop must do the work directly:This is my preferred solution, I think. It's the most robust and safe. It also matches the ASF implementation most closely.
(aside: I had hoped to use memcpy or wmemcpy, since they often dynamically deal with aligned/unaligned data nicely, but I could not get them to work--the data_addr is "special" enough to require explicit code apparently)
The text was updated successfully, but these errors were encountered: