-
Notifications
You must be signed in to change notification settings - Fork 8k
feat(sdmmc): support multi-block read/writes (IDFGH-16505) #17642
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
base: master
Are you sure you want to change the base?
Conversation
👋 Hello jofrev, we appreciate your contribution to this project! 📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more. 🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project. Click to see more instructions ...
Review and merge process you can expect ...
|
aa3b708 to
dddcc57
Compare
dddcc57 to
8a6bb5b
Compare
igrr
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.
@jofrev Regarding the question on setting the buffer size:
Perhaps the best option would be to allow reusing the existing sdmmc_host_t::dma_aligned_buffer which is currently only used for SDIO. That would have two advantages:
- Callers can configure the size of the scratch buffer by simply allocating it with the size they need.
- The buffer is reused between reads or writes.
However that would likely be a much larger change than your PR currently is. I think adding a Kconfig option would be sufficient to accept this PR.
components/sdmmc/sdmmc_cmd.c
Outdated
| #include "esp_private/sdmmc_common.h" | ||
|
|
||
| // the maximum size in blocks of the chunks a SDMMC write/read will be split into | ||
| #define MAX_NUM_BLOCKS_PER_MULTI_BLOCK_RW (16u) |
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.
Let's introduce a Kconfig option to set this value, with the default being 1 to match the current heap usage.
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.
Added the option in 3b3d530.
components/sdmmc/sdmmc_cmd.c
Outdated
| if (err != ESP_OK) { | ||
| ESP_LOGD(TAG, "%s: error 0x%x writing block %d+%d", | ||
| __func__, err, start_block, i); | ||
| ESP_LOGD(TAG, "%s: error 0x%x writing blocks %zu+[%zu..%zu]", |
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 we can't rely on %z format specifier, since it's not supported by newlib-nano (i.e. if CONFIG_NEWLIB_NANO_FORMAT is enabled.)
Same note for sdmmc_read_sectors below.
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.
Reverted back to %d in c6581d0.
6588e0f to
98cbd0a
Compare
98cbd0a to
758c1b8
Compare
758c1b8 to
2e33490
Compare
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 PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
2e33490 to
16fd56c
Compare
This has the potential of speeding up SD card access significantly. Reusing the DMA aligned buffer gives the additional option of having to allocate the transaction buffer only once instead of for every transaction, while still keeping the improved transaction time. To give users the maximum amount of control, the Kconfig option for the transaction buffer size applies only to the temporary buffer, which is only allocated if the DMA aligned buffer has not been pre-allocated.
16fd56c to
e1e8d53
Compare
Description
Making use of the read/write multiple block commands of the SD/MMC has the potential of speeding up SD card access significantly.
On ESP32 and ESP32-S3 and an SD card in SDC mode speed increased from 200kB/s to >2MB/s with 8kiB of additional buffer.
In general, it should speed up access significantly for all ESP devices without a PSRAM capable SDC peripheral when reading/writing data to/from PSRAM.
This PR actually uses these multi-block read/write commands by calling the
sdmmc_read/write_sectors_dmafunctions from their respectivesdmmc_read/write_sectorscounterpart with ablock_countdifferent from1. (Beforesdmmc_read/write_sectorswould callsdmmc_read/write_sectors_dmarepeatedly with ablock_countof1regardless of the amount of data to be read/written.)To limit the temporary buffer size for large transfers, the data is transferred in chunks whose maximum size in number of blocks is defined by the
MAX_NUM_BLOCKS_PER_MULTI_BLOCK_RWmacro.Setting this macro to
1should result in the same behavior as before, while a value of16for example results in a size of16 * 512B = 8192Bfor the temporary buffer improving the speed by one order of magnitude.It may be nice to allow users to change the value of this macro possibly leaving the default at
1to not change the behavior except if explicitly configured by the user since temporary buffer size and transmission speed are a trade off "game".I'm open for suggestions how to enable them to do that. I would have added a Kconfig option, but there is no other Kconfig option present for this component as of v5.5.1 only on
master.Related
Testing
Tested on two custom boards with a
ESP32-WROVER-E/ESP32-S3and ESP-IDFv5.5.1and an SD card in SDC mode.Checklist
Before submitting a Pull Request, please ensure the following:
Note
Adds multi-block SDMMC read/write with chunking controlled by a new Kconfig option, using a DMA-aligned buffer when available and improving error/status handling.
sdmmc_read_sectors/sdmmc_write_sectorsnow chunk unaligned transfers and call*_sectors_dmawithblock_count > 1.host.dma_aligned_buffer; otherwise allocate DMA-capable temp buffer sized by actual allocation and sector size; validate and free as needed.KconfigoptionCONFIG_SD_UNALIGNED_MULTI_BLOCK_RW_MAX_CHUNK_SIZEto bound per-chunk blocks (controls single vs. multi-block ops).sdmmc_host_t.dma_aligned_bufferuse cases (multi-block RW and SDIO IO) and sizing guidance.<sys/param.h>forMIN/MAX.Written by Cursor Bugbot for commit 21df91a. This will update automatically on new commits. Configure here.