summaryrefslogtreecommitdiff
path: root/examples/device
diff options
context:
space:
mode:
Diffstat (limited to 'examples/device')
-rw-r--r--examples/device/cdc_msc_freertos/src/msc_disk.c126
-rw-r--r--examples/device/cdc_msc_freertos/src/tusb_config.h6
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);
-#endif
+ // 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 ret;
+ return bufsize;
+#endif
}
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);
- }
-#else
- (void) lba; (void) offset; (void) buffer;
+#ifdef CFG_EXAMPLE_MSC_READONLY
+ (void) lun; (void) buffer;
+ return bufsize;
#endif
-#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);
-#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 ret;
+ return TUD_MSC_RET_ASYNC;
+#else
+ uint8_t* addr = msc_disk[lba] + offset;
+ memcpy(addr, buffer, bufsize);
+ tusb_time_delay_ms_api(CFG_EXAMPLE_MSC_IO_DELAY_MS);
+
+ return bufsize;
+#endif
}
// 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
}