From 2707347decb0ea362fd0a6e4d58102c77f366429 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 31 Jan 2025 16:29:09 +0100 Subject: [PATCH] Update example. Signed-off-by: HiFiPhile --- .../device/cdc_msc_freertos/src/msc_disk.c | 126 +++++++++++------- .../device/cdc_msc_freertos/src/tusb_config.h | 6 +- 2 files changed, 79 insertions(+), 53 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/msc_disk.c b/examples/device/cdc_msc_freertos/src/msc_disk.c index 2f3a1c30b..c75b9ae34 100644 --- a/examples/device/cdc_msc_freertos/src/msc_disk.c +++ b/examples/device/cdc_msc_freertos/src/msc_disk.c @@ -28,16 +28,28 @@ #if CFG_TUD_MSC -// Simulate read/write operation time -#define SIM_IO_TIME_MS 0 +#if CFG_EXAMPLE_MSC_ASYNC_IO -#if CFG_TUD_MSC_ASYNC_IO -TimerHandle_t sim_io_ops_timer; -static int32_t bytes_processed; +#define IO_STACK_SIZE configMINIMAL_STACK_SIZE + +typedef struct { + uint8_t lun; + bool is_read; + uint32_t lba; + uint32_t offset; + void* buffer; + uint32_t bufsize; +} io_ops_t; + +QueueHandle_t io_queue; #if configSUPPORT_STATIC_ALLOCATION -StaticTimer_t sim_io_ops_timer_buf; +uint8_t io_queue_buf[sizeof(io_ops_t)]; +StaticQueue_t io_queue_static; +StackType_t io_stack[IO_STACK_SIZE]; +StaticTask_t io_taskdef; #endif -static void sim_io_ops_done_cb(TimerHandle_t xTimer); + +static void io_task(void *params); #endif void msc_disk_init(void); @@ -133,20 +145,37 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = README_CONTENTS }; -#if CFG_TUD_MSC_ASYNC_IO +#if CFG_EXAMPLE_MSC_ASYNC_IO void msc_disk_init() { -#if configSUPPORT_DYNAMIC_ALLOCATION - sim_io_ops_timer = xTimerCreate("sim_io_ops", pdMS_TO_TICKS(SIM_IO_TIME_MS), pdFALSE, NULL, sim_io_ops_done_cb); +#if configSUPPORT_STATIC_ALLOCATION + io_queue = xQueueCreateStatic(1, sizeof(io_ops_t), io_queue_buf, &io_queue_static); + xTaskCreateStatic(io_task, "io", IO_STACK_SIZE, NULL, 2, io_stack, &io_taskdef); #else - sim_io_ops_timer = xTimerCreateStatic("sim_io_ops", pdMS_TO_TICKS(SIM_IO_TIME_MS), pdFALSE, NULL, sim_io_ops_done_cb, &sim_io_ops_timer_buf); + io_queue = xQueueCreate(1, sizeof(io_ops_t)); + xTaskCreate(io_task, "io", IO_STACK_SIZE, NULL, 2, NULL); #endif } -static void sim_io_ops_done_cb(TimerHandle_t xTimer) { - (void) xTimer; - tud_msc_async_io_done(bytes_processed); +static void io_task(void *params) { + (void) params; + io_ops_t io_ops; + while (1) { + if (xQueueReceive(io_queue, &io_ops, portMAX_DELAY)) { + if (io_ops.is_read) { + uint8_t const* addr = msc_disk[io_ops.lba] + io_ops.offset; + memcpy(io_ops.buffer, addr, io_ops.bufsize); + } else { + uint8_t* addr = msc_disk[io_ops.lba] + io_ops.offset; + memcpy(addr, io_ops.buffer, io_ops.bufsize); + } + + tusb_time_delay_ms_api(CFG_EXAMPLE_MSC_IO_DELAY_MS); + tud_msc_async_io_done(io_ops.bufsize); + } + } } + #else void msc_disk_init() {} #endif @@ -220,33 +249,31 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { (void) lun; - int32_t ret = bufsize; // out of ramdisk if ( lba >= DISK_BLOCK_NUM ) { - ret = -1; + return TUD_MSC_RET_ERROR; } // Check for overflow of offset + bufsize if ( lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE ) { - ret = -1; + return TUD_MSC_RET_ERROR; } - if (ret != -1) { - uint8_t const* addr = msc_disk[lba] + offset; - memcpy(buffer, addr, bufsize); - } +#if CFG_EXAMPLE_MSC_ASYNC_IO + io_ops_t io_ops = { .is_read = true, .lun = lun, .lba = lba, .offset = offset, .buffer = buffer, .bufsize = bufsize }; -#if CFG_TUD_MSC_ASYNC_IO - // Simulate background read operation - bytes_processed = ret; - xTimerStart(sim_io_ops_timer, 0); -#elif SIM_IO_TIME_MS > 0 - // Simulate read operation - tusb_time_delay_ms_api(SIM_IO_TIME_MS); + // Send IO operation to IO task + TU_ASSERT(xQueueSend(io_queue, &io_ops, 0) == pdPASS); + + return TUD_MSC_RET_ASYNC; +#else + uint8_t const* addr = msc_disk[lba] + offset; + memcpy(buffer, addr, bufsize); + tusb_time_delay_ms_api(CFG_EXAMPLE_MSC_IO_DELAY_MS); + + return bufsize; #endif - - return ret; } bool tud_msc_is_writable_cb (uint8_t lun) @@ -264,38 +291,35 @@ bool tud_msc_is_writable_cb (uint8_t lun) // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { - (void) lun; - int32_t ret = bufsize; - // out of ramdisk if ( lba >= DISK_BLOCK_NUM ) { - ret = -1; + return TUD_MSC_RET_ERROR; } // Check for overflow of offset + bufsize if ( lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE ) { - ret = -1; + return TUD_MSC_RET_ERROR; } -#ifndef CFG_EXAMPLE_MSC_READONLY - if (ret != -1) { - uint8_t* addr = msc_disk[lba] + offset; - memcpy(addr, buffer, bufsize); - } +#ifdef CFG_EXAMPLE_MSC_READONLY + (void) lun; (void) buffer; + return bufsize; +#endif + +#if CFG_EXAMPLE_MSC_ASYNC_IO + io_ops_t io_ops = { .is_read = false, .lun = lun, .lba = lba, .offset = offset, .buffer = buffer, .bufsize = bufsize }; + + // Send IO operation to IO task + TU_ASSERT(xQueueSend(io_queue, &io_ops, 0) == pdPASS); + + return TUD_MSC_RET_ASYNC; #else - (void) lba; (void) offset; (void) buffer; -#endif + uint8_t* addr = msc_disk[lba] + offset; + memcpy(addr, buffer, bufsize); + tusb_time_delay_ms_api(CFG_EXAMPLE_MSC_IO_DELAY_MS); -#if CFG_TUD_MSC_ASYNC_IO - // Simulate background write operation - bytes_processed = ret; - xTimerStart(sim_io_ops_timer, 0); -#elif SIM_IO_TIME_MS > 0 - // Simulate write operation - tusb_time_delay_ms_api(SIM_IO_TIME_MS); + return bufsize; #endif - - return ret; } // Callback invoked when received an SCSI command not in built-in list below diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index eb4798017..d70456287 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -114,9 +114,11 @@ // MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_EP_BUFSIZE 512 -// Enable Async IO on MSC -#define CFG_TUD_MSC_ASYNC_IO 0 +// Use async IO in example or not +#define CFG_EXAMPLE_MSC_ASYNC_IO 1 +// Simulate read/write operation delay +#define CFG_EXAMPLE_MSC_IO_DELAY_MS 0 #ifdef __cplusplus }