-
Notifications
You must be signed in to change notification settings - Fork 7.9k
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
This has the potential of speeding up SD card access significantly.
dddcc57
to
8a6bb5b
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.
@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.
#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.
Reusing this buffer gives the additional option of only having to allocate the transaction buffer 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.
6588e0f
to
98cbd0a
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_dma
functions from their respectivesdmmc_read/write_sectors
counterpart with ablock_count
different from1
. (Beforesdmmc_read/write_sectors
would callsdmmc_read/write_sectors_dma
repeatedly with ablock_count
of1
regardless 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_RW
macro.Setting this macro to
1
should result in the same behavior as before, while a value of16
for example results in a size of16 * 512B = 8192B
for 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
1
to 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-S3
and ESP-IDFv5.5.1
and an SD card in SDC mode.Checklist
Before submitting a Pull Request, please ensure the following: