-
Notifications
You must be signed in to change notification settings - Fork 2.1k
drivers: add mtd wrapper for periph_flashpage #8774
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
drivers/Makefile.dep
Outdated
| USEMODULE += mtd | ||
| endif | ||
|
|
||
| ifneq (,$(filter mtd_sdcard,$(USEMODULE))) |
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 all mtd_ sub modules be nested in the generic block mtd_% ? This would avoid confusion I think.
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.
done
3f61679 to
f119787
Compare
kYc0o
left a comment
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.
Just a comment on this, I need more info about the purpose of this PR.
| .sector_count = FLASHPAGE_NUMOF, \ | ||
| .pages_per_sector = _pages_per_sector,\ | ||
| .page_size = FLASHPAGE_SIZE / _pages_per_sector,\ | ||
| } |
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'm not really sure if this is a good idea... What's the purpose of having this wrapper? The biggest problem I see is that you'd hardly know where you can write without precise knowledge about the non-filled flash space left when flashing a firmware... The main purpose of the flashpage driver is to write new program data, or extend the current one (new elf files, scripts of any kind, etc.), and, if I understand correctly, this driver aims to write user 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.
The goal is to be able to use a file system on internal flash.
It's then completely up to the developer to be sure of what's he's doing and it might be dangerous, of course.
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 see the point, but I have the issue of erasing. How do you cope with the small erases case? You need to always backup the whole block in RAM before adding something, then erase the whole block and write it from the buffer...
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 don't understand your point here. This is the case with any flash, either internal or not.
A file system designed to run on a flash will not try to erase a few bytes, but always the entire sector. What is different 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.
So what you're saying is that whenever you do a write using the MTD, you rely on the file system to do it correctly? In some devices the flash page size is huge (2KB for stm32f103re), that's why I'm concerned about using it in that fine-grained way.
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.
Most SPI flashes have a sector size of 4KB, or even 64KB. And a typical "page" size (i.e. maximum number of bytes you can write with a single instruction) is 256B on these flashes.
Then yes, we rely on the file system to manage erases and write cycles.
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.
So, in overall (a bit out of scope now) using ANY file system over a flash-based MTD will take at least as much RAM as the smallest erasable block, is it? I just checked and for the N25Q128 series (the one attached to the iotlab-m3) has 4KB as eraseable sub-sector.
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.
If you take the assumption that a sector will be modified, this will be true. But a good filesystem won't need to modify a byte in the middle of a sector. See littles or spiffs, they don't need a buffer of the size of a sector.
kYc0o
left a comment
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'm ACKing this but I'm still not super convinced about its usefulness. I'd say it's a very experimental feature and since it doesn't break anything it doesn't hurt to have it as an option. If someone else cares about it please express it. Otherwise @vincent-d you can merge it before the feature freeze.
|
Please squash so we have Murdock happy. |
aabadie
left a comment
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 this feature because it allows to use a lot more available space for storing data.
I also agree with @kYc0o that this space is normally meant for program data but most of the time a RIOT based firmware is less than 200kB (and I'm large). Fro example, with a flash of 1MB on a L476, there's quite some space left.
Otherwise I found a minor indentation issue and have a comment regarding the fact by default the MTD can potentially takes the whole flash.
| #endif | ||
|
|
||
| /** | ||
| * @brief The entry point of this test suite. |
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.
Indentation is off in this doxygen block
|
|
||
| #define MTD_FLASHPAGE_INIT_VAL(_pages_per_sector) { \ | ||
| .driver = &mtd_flashpage_driver, \ | ||
| .sector_count = FLASHPAGE_NUMOF, \ |
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.
So by default, IIUC the MTD can take the whole flash. Can we make this configurable at build time with a more reasonable default value (half of the flash) ?
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.
@vincent-d, do you think it would make sense to limit the default size used to half of the flash size ?
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 took a new look to this and there are 2 options:
- we leave it as-is and rely on the configuration of the filesystem for the offset in the mtd (i.e. the mtd allows access to the whole internal flash and the filesystem is configured correctly to not write outside its area)
- we change the mtd_flashpage to let the filesystem access only a part of the internal flash, but we need to have a specific
mtd_flashpage_tdescriptor to store the offset
If we only change sector_count the filesystem will be able to access the number of sector passed through this field, but it will always start from address 0 (the first sector)
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'm not sure to understand everything clearly.
If the first option is kept, we'll have to trust the filesystem implementation and most of them come from external packages. My question in this case is how do you configure this external filesystem ? (I checked littlefs and I'm not sure to understand how to do that)
If the second option is kept, could the offset be automatically determined from the number of sectors defined (using offset = flashsize - number_of_sector) ?
he filesystem will be able to access the number of sector passed through this field, but it will always start from address 0
Is this an issue ?
d11e7d0 to
206f69d
Compare
|
I was pointed here as I was writing a PR to limit the ROM used for a firmware: #9351 It might be of your interest too. |
aabadie
left a comment
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.
@vincent-d, I had another look at this one. I'm still not convinced that letting filesystems managing the whole flash via the mtd is a good idea. But maybe I'm missing obvious things.
I have other minor comments.
|
|
||
| #define MTD_FLASHPAGE_INIT_VAL(_pages_per_sector) { \ | ||
| .driver = &mtd_flashpage_driver, \ | ||
| .sector_count = FLASHPAGE_NUMOF, \ |
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'm not sure to understand everything clearly.
If the first option is kept, we'll have to trust the filesystem implementation and most of them come from external packages. My question in this case is how do you configure this external filesystem ? (I checked littlefs and I'm not sure to understand how to do that)
If the second option is kept, could the offset be automatically determined from the number of sectors defined (using offset = flashsize - number_of_sector) ?
he filesystem will be able to access the number of sector passed through this field, but it will always start from address 0
Is this an issue ?
|
@vincent-d What's the status of this PR? Would love to have this in. |
|
Now that I think twice, I see that this PR worth the "risk" of letting the user use the internal flash at will. I'd ACK it if @aabadie 's comments are addressed. |
|
@aabadie ping. |
From what I see, I still have unaddressed comments. So it should be ping @vincent-d :) |
|
Can we go on this one? |
|
@aabadie ping. |
aabadie
left a comment
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.
ACK, please squash
db2070d to
abf9739
Compare
|
squashed |
|
Static tests are already reporting issues with |
abf9739 to
e3778dc
Compare
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
|
@kYc0o your changes look OK. Maybe someone else should take a look and test (I don't have hardware supporting this at the moment). |
|
Maybe @fjmolinas would like to test? The failures and differences are mostly related to stm32l152 devices, and other cortex-m series uC which I also don't have now. |
|
I can test tomorrow on nucleo-l1 and some other boards. |
aabadie
left a comment
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.
Unfortunately, I found an important problem with this PR: it adds periph_flashpage dependency to the unittests and thus disable them for native and other boards that don't provide support for this feature.
@vincent-d can you move the test in its own application, tests/mtd_flashpage or something equivalent ? (also having a basic python script with it will be a big plus for automatic testing ;) )
Appart from that the unittest are passing on nucleo-l152re and nucleo-l476rg.
|
It would also be great to rebase this PR on top of latest master as it contains other changes for unittests and nucleo-l1. |
f119427 to
fac7730
Compare
|
I guess this one only needs squashing now, @aabadie ? |
aabadie
left a comment
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 re-tested this PR on several boards providing flashpage_raw: arduino-zero, nrf52dk and iotlab-m3. The new test application works like a charm.
Code changes are good, so ACK
@kYc0o, are you also ok to ACK ?
@vincent-d, please squash!
This is a MTD wrapper for flashpage internal flash
123e5ef to
7c8a3ea
Compare
|
@aabadie did you test on a stm32l152? |
Not the very last version (I admit I forgot...), but I tested it before (see #8774 (review)) the test was cut out from the unittest and it was working. |
|
Cold you try again nonetheless? I really have doubts about the differences on those platforms. |
kYc0o
left a comment
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.
ACK. I tested on a lobaro-lorabox which also have a stm32l1 microcontroller. It's enough for me as a test.
| .pages_per_sector = _pages_per_sector,\ | ||
| .page_size = FLASHPAGE_SIZE / _pages_per_sector,\ |
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.
What is the reason to create 'virtual' sectors here?
Usually page is the max transfer unit and sector the min erase unit. For internal flash they tend to be the same. So why artificially make the erase granularity worse (and complicate the code)?
Contribution description
This adds a basic mtd wrapper around perip_flashpage interface. periph_flashpage_raw is needed to write.
Issues/PRs references
Based on #8773