Repository navigation
Conversation
- CONFIG_TINYUSB_MSC_ASYNC_IO runs READ10/WRITE10 in a worker task, so the TinyUSB task keeps serving other classes. Needs TinyUSB >= 0.19. - CONFIG_TINYUSB_MSC_ASYNC_WRITE_BEHIND (default y) keeps sync write throughput by reusing the existing storage buffer. - Document both options and their RAM cost.
Measures CDC latency and MSC throughput with async IO off/on, on a RAM disk with optional delay or an SD card. Results in README.
CDC prints USB latency while a file is copied to the drive, so async IO off vs on is visible at a glance.
SD card based storage, copied 104 MB file from host.
omnitex
force-pushed
the
feat/usb-device-msc-async-io
branch
from
October 6, 2026 15:01
60b65f8 to
03d8b48
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Main idea
TinyUSB runs every class in a single task (
tud_task). Without async IO, MSC READ10/WRITE10 callbacks access the storage medium inside that task. While an SD card or flash is busy, CDC, HID and the other classes on the device are not serviced.TinyUSB 0.19 added async MSC IO (hathach/tinyusb#2967): the callback returns
TUD_MSC_RET_ASYNC, and the storage access finishes later withtud_msc_async_io_done(). This PR uses that API in esp_tinyusb, so applications need no code changes:CONFIG_TINYUSB_MSC_ASYNC_IOruns storage IO in a dedicated worker task. The TinyUSB task keeps servicing other classes, and write errors are reported to the host.CONFIG_TINYUSB_MSC_ASYNC_WRITE_BEHIND(defaulty) accepts a write chunk into the existing per-storage buffer and writes it in the background, so the host sends the next chunk in the meantime. This keeps write throughput without extra RAM. A failed buffered write is reported on the next command to the LUN.Results (ESP32-P4, SD card, 40 MHz)
Example: 104 MB file copied from the host while CDC sends a heartbeat every 100 ms (
REMOVElog commit)Benchmark: CDC echo latency under MSC load, async with write-behind (
REMOVECSV commit)With async IO off, CDC latency follows the storage access time. With async IO on, it stays at the idle value of about 0.33 ms, and SD write throughput does not drop (it goes up by 46 % at 0 ms delay). The 20 ms async run had one outlier at 65 ms; I haven't investigated it yet.
Notes
Checklist
Before submitting a Pull Request, please ensure the following: