-
Notifications
You must be signed in to change notification settings - Fork 3k
Q/OSPIFBlockDevice: fix misconception in minimum program size #13848
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
Not sure what to do about this. Maybe we do have to set the program size configuration in a chip-by-chip basis, but it's hard to check without having all the boards at hands. Or, keep the program size equal to the page size (as it is), which is the safest but far from optimal... |
Reopening this PR for discussion. |
@LDong-Arm, thank you for your changes. |
ff6e39d
to
bfae577
Compare
This is ready for review. I've listed QSPI flash models and their program sizes based on existing materials, but haven't tried some of them on physical boards. Is it enough, or shall we ask silicon vendors to confirm them, or ask engineers with those boards to try them out? |
I ran the QSPI HAL, BlockDevice, and KVStore tests on CY8CKIT-062-WIFI-BT and CY8CPROTO-062-4343W.
I'm not sure if this is a true failure in the sense of the test hanging, or if the smaller program size is just slowing down the test so much that it hits the timeout. |
@kyle-cypress Thanks a lot for trying it out. I think it's highly possible the test is way too slow, because it now programs one by at a time on that target. From your log,
Did the test pass on that target, without this PR? |
@pan- FYI, this is the PR I mentioned. |
Only DISCO_L4R9I in targets.json has support for OSPIF : https://github.com/ARMmbed/mbed-os/blob/master/targets/targets.json/#L3559 This target has 2 x OctoSPI memory interface. OSPI_MIN_PROG_SIZE is set to 256: https://github.com/ARMmbed/mbed-os/blob/master/storage/blockdevice/COMPONENT_OSPIF/mbed_lib.json/#L26 |
From the datasheet of the OctoSPI flash, section 2:
So I think the write size should be one byte (i.e. the minimum granularity that applications can program). I can do the change for OSPIFBlockDevice too, but then it'd be good if someone from @ARMmbed/team-st-mcd tries that on the target. |
@rogeryou Maybe you could comment? |
I've added the change to OSPIFBlockDevice, so an easy way to check is to give it a try |
Indeed - printed at the beginning of the test:
Yes, after I saw the failure on the PR branch I checked out master and confirmed that the test passes there (in significantly less time)
|
@kyle-cypress I've just optimized Could you fetch my last update and try the test again? Thanks. |
d8861aa
to
d7222fa
Compare
// (which should be a power of 2) is greater than that. If it's less than | ||
// that, the test finishes quickly anyway... | ||
if ((program_size < 256) && (256 % program_size == 0) | ||
&& (contiguous_erase_size >= 256) && (contiguous_erase_size % 256 == 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.
Checks of (256 % program_size == 0)
and (contiguous_erase_size % 256 == 0)
shouldn't be necessary (if the other two conditions are satisfied), because sector and program sizes are always powers of 2. We're just trying to be rigorous...
d7222fa
to
d26398b
Compare
Thanks, that fixed the failure. Reran on CY8CKIT-062-WIFI-BT and confirmed things are still passing there as well. |
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.
I've checked one log for disco, it contains a failure in |
Prior to this PR, the minimum program size (QSPI_MIN_PROG_SIZE) of QSPIFBlockDevice was 256 by default and 512 for some targets. Those values were in fact page sizes, not program sizes. Here's an explanation: * Most QSPI flashes can be programmed to a granularity of a single byte or a few bytes - no need to be a whole page. This should be the value of QSPI_MIN_PROG_SIZE. Applications need to align buffer sizes to this granularity when programming QSPI flashes. * Each sending of the underlying QSPI program signal requires destination bytes to be located within the same page. If a QSPIFBlockDevice::program() call crosses page boundaries, this function breaks down the operation into multiple chunks, so it's not a concern for the application. So this PR changes the default program size to 1 (byte), and for targets with a 4-byte (1-word) read size it overrides the program size. Note: No config is needed for the page size, as it comes from the SFDP table parsed during initialisation.
From the datasheet of the only OctaSPI flash we currently support (http://www.mt-system.ru/sites/default/files/docs/Macronix/mx25lm51245g_3v_512mb_v0.01.pdf): After program/erase command is issued, auto program/erase algorithms which program/erase and verify the specified page or sector/block locations will be executed. Program command is executed on byte basis, or page (256 bytes) basis, or word basis. Erase command is executed on sector (4K-byte), or block (64K-byte), or whole chip basis. So the minimum write size is one byte.
…fer size for large-sector flashes
d26398b
to
68a816c
Compare
Pull request has been modified.
Thanks, I just fixed it in the last commit. What happened was, after we fixed the QSPIFBlockDevice's write size, the test doesn't allocate enough space for |
…e enough The test case set_add_data_set_key_value_five_Kbytes stores 5KB of value, and to allow for overheads, we allocate at least 8KB per area of TDBStore (so 16KB for two areas of a whole TDBStore).
68a816c
to
13c5b64
Compare
CI started |
Jenkins CI Test : ❌ FAILEDBuild Number: 2 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Ci restarted (K64 failed to sync) |
Jenkins CI Test : ❌ FAILEDBuild Number: 3 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Jenkins CI Test : ✔️ SUCCESSBuild Number: 4 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Summary of changes
Fixes: #13795
Prior to this PR, the minimum program size (
QSPI_MIN_PROG_SIZE
) ofQSPIFBlockDevice
andOSPIFBlockDevice
were 256 by default and 512 for some targets. Those values were in fact page sizes, not program/write sizes. Consequently the value returned byQSPIFBlockDevice::get_program_size()
is the large page size, and taking out a whole page to just write a few bytes is highly inefficient.Here's an explanation of the concepts:
QSPI_MIN_PROG_SIZE
. Applications need to align buffer sizes to this granularity when programming QSPI flash.::program()
call crosses page boundaries, the function breaks down the operation into multiple chunks, so it's not a concern for the application.So this PR changes the default program size to 1 (byte), and overrides it to 4 for some targets.
Minimum program size/granularity for all supported QSPI/OSPI flash model (for targets with
QSPIF
in targets.json):Cy_SMIF_MemWrite()
handles any number of bytes (incl. bytes not aligned to pages or anything)@ARMmbed/team-cypress Could you confirm this is the write size of the flash?Update: Tested by @kyle-cypressqspi_write()
enforces word-size access (note: its read size is also 4-byte as per existing configuration) @ARMmbed/team-silabs Could you confirm this is the write size of the flash?qspi_write()
enforces word-sized access @ARMmbed/team-nxp Could you confirm this is the write size of the flash?Notes:
The same issue may exist for OSPIFlashBlockDevice too, but I didn't change it without having a target to test.Change made for OSPIFBlockDevice too.Impact of changes
QSPIFBlockDevice::get_program_size()
andOSPIFBlockDevice::get_program_size()
return the correct value (1 or 4 normally) instead of the 256 or 512.Migration actions required
None.
Documentation
None.
Pull request type
Test results
Note: This change is tested by general_block_device.test_program_read_small_data_sizes - it programs 1-7 bytes using
BufferedBlockDevice
, which in turn uses the minimum program size ofQSPIFBlockDevice
to program (1 or 4 bytes).Reviewers
@ARMmbed/mbed-os-core @VeijoPesonen @SeppoTakalo