-
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
cpu/stm32-common: slightly rework flashpage driver and fix iotlab-m3 #9068
cpu/stm32-common: slightly rework flashpage driver and fix iotlab-m3 #9068
Conversation
The test I mention in the #9065 issue works now on both iotlab-m3 and iotlab-a8-m3. I did not have time to review the code for the moment. |
dd7c3cc
to
ed6791a
Compare
@kYc0o can you take a look at this? |
On it. However I'd need quite a bit of time to understand all the changes. AFAIR flashpage worked integrally for this CPU, and with all the recent modifications ended in this state. Thus I need to compare all the version to catch what's missing. |
Before #8768 |
cpu/stm32_common/periph/flashpage.c
Outdated
@@ -140,6 +136,11 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len) | |||
assert(((unsigned)target_addr + len) < | |||
(CPU_FLASH_BASE + (FLASHPAGE_SIZE * FLASHPAGE_NUMOF)) + 1); | |||
|
|||
#ifndef CPU_FAM_STM32F1 | |||
DEBUG("[flashpage_raw] unlocking the flash module\n"); | |||
_unlock(); |
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.
Is it really true that for all the following boards, it is not necessary to _unlock
for flashpage_write_raw
?
cpu/sam0_common/Makefile.features:FEATURES_PROVIDED += periph_flashpage_raw
cpu/stm32f0/Makefile.features: FEATURES_PROVIDED += periph_flashpage_raw
cpu/stm32l0/Makefile.features:FEATURES_PROVIDED += periph_flashpage_raw
cpu/stm32l1/Makefile.features:FEATURES_PROVIDED += periph_flashpage_raw
If yes is it necessary to do _unlock
for _erase_page
for them ?
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.
Sorry misread the ifndef
.
I tried understanding what was happening and played a version of this one looking more like master and also with master version. And at the point I am now, I think that maybe the changes in this PR are not required as it does not look like it is related to timing. It works on master with both the two following diffs: diff --git a/cpu/stm32_common/periph/Makefile b/cpu/stm32_common/periph/Makefile
index bcc3fe2..7ae2d98 100644
--- a/cpu/stm32_common/periph/Makefile
+++ b/cpu/stm32_common/periph/Makefile
@@ -1,3 +1,4 @@
MODULE = stm32_common_periph
+CFLAGS += -O0
include $(RIOTMAKE)/periph.mk Or also this one diff --git a/cpu/stm32_common/periph/flashpage.c b/cpu/stm32_common/periph/flashpage.c
index 1884579..1de1d8e 100644
--- a/cpu/stm32_common/periph/flashpage.c
+++ b/cpu/stm32_common/periph/flashpage.c
@@ -95,6 +95,7 @@ static void _erase_page(void *page_addr)
/* make sure no flash operation is ongoing */
DEBUG("[flashpage] erase: waiting for any operation to finish\n");
while (FLASH->SR & FLASH_SR_BSY) {}
+ __asm__ __volatile__("":::"memory");
/* set page erase bit and program page address */
DEBUG("[flashpage] erase: setting the erase bit\n");
CNTRL_REG |= FLASH_CR_PER; And putting this So maybe we are just in a case of compiler re-ordering instructions so requires checking the compiled output and fix it properly. |
Thanks @cladmi ! Your analysis seems very good. Without the compiler optimization option and with just adding the |
Here is the disassembled code (using gdb). Just showing the loop in flashpage_write_raw function.
The block of instructions from |
I had a look at the STM32 cube code and there the 'end of operation' bit (EOP) in status register is cleared after BSY bit goes back to 0. I tried this instead of the assembly hack and it also works. Will push the change, so you can have a look. The disassemble code is the following in this case:
|
44f20e3
to
7f39a4f
Compare
I re-tested this PR on iotlab-m3, nucleo-l073, nucleo-f070 and nucleo-l152 and everything (full page write + raw bytes write) is working now. |
@aabadie can you squash and write the explanations in the commit messages ? It would be easier for me to review with the summarized details. |
Do you want that the change related to
Is it ok for your @cladmi ? |
901aa8f
to
b80691f
Compare
@cladmi, I reworked the commit history of this PR. The last one contains the real fix for iotlab-m3, the others are cosmetic. |
@cladmi, is it ok for you here ? |
b80691f
to
f120107
Compare
@kYc0o, can you check that this PR actually fixes the flashpage feature on iotlab-m3 ? |
f120107
to
988c8b2
Compare
@cladmi maybe you want to have a look at this one during hack'n'ack ? |
cpu/stm32_common/periph/flashpage.c
Outdated
{ | ||
DEBUG("[flashpage] waiting for any pending operation to finish\n"); | ||
while (FLASH->SR & FLASH_SR_BSY) {} | ||
if (FLASH->SR & FLASH_SR_EOP) { |
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.
The if
section is not necessary to make it work on M3 nodes. I tested it.
So if needed it should go in its own commit with justification.
What makes it work is that now the while
is in a function so it is not getting re-ordered by gcc.
I think a comment on the function and a message in the commit is necessary.
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 is what is done in the STM32 Cube code, I just did the same. I have no idea if/when this may happen.
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.
Yes, then it should not be in a "fix M3" commit but in a "make it look more like stm32 cube code just in case".
KEY_REG = FLASH_KEY1; | ||
KEY_REG = FLASH_KEY2; | ||
} | ||
} | ||
|
||
void _lock(void) | ||
{ | ||
DEBUG("[flash-common] locking the flash module\n"); | ||
CNTRL_REG |= CNTRL_REG_LOCK; | ||
if (!(CNTRL_REG & CNTRL_REG_LOCK)) { |
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.
Is there still a case where this is necessary ?
But maybe this would also be needed to ask it for _unlock
.
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.
At least 'test 255' and 'write_raw 0x807f808 abcdefgh' work on M3 nodes without both protections.
But there may be good reasons for it just asking.
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.
There is the same check in the _unlock function, I wanted it to be consistent. The idea is "if already locked, do nothing".
- improve debug messages - fix missing space before comment - use a comment instead of debug message (the same message is displayed by the function called after)
Moving the while loop in a separate function ensures no ordering optimizations is applied silently by gcc. This commit fixes the flashpage not working on iotlab-m3.
This was taken from STM32 Cube generated code
988c8b2
to
6007274
Compare
@cladmi, I reworked the commit history. Let me know if this is ok for you. |
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 like it now. The changes are now also documented appropriately for me.
tests/periph_flashpage
works on:
iotlab-m3
withtest 255
andwrite_raw 0x807f808 abcdefgh
samr21-xpro
withtest 255
andwrite_raw 0xff10 abcdefgh12345678
.
@kYc0o: can you also take a look and test your boards ?
Unfortunately I have no boards working now. I trust you with this. |
Tested on nucleo-l152re and b-l072z-lrwan1. Everything alright so go! |
Contribution description
This PR is an attempt to fix the #9065 issue that was introduced by #8768. Regarding the differences, the calls to lock/unlock functions were moved in different places in #8768, wrapping each calls to erase and write_raw internal functions.
This change seems to have introduced timing issues on iotlab-m3 but not on the other boards I tested (nucleo-l073, l152 and f070).
Reverting this change and adding extra checks fixes the issue. One last thing it still not working (but it was already the case before #8768):
flashpage_raw
. I tested different things but none worked on iotlab-m3. I can disable this feature for STM32F1 family if requested.Other CPUs (l0, l1, f0) are still working for both write and write_raw functions.
Issues/PRs references
Fixes #9065