28
28
29
29
#if CFG_TUD_MSC
30
30
31
- // Simulate read/write operation time
32
- #define SIM_IO_TIME_MS 0
31
+ #if CFG_EXAMPLE_MSC_ASYNC_IO
33
32
34
- #if CFG_TUD_MSC_ASYNC_IO
35
- TimerHandle_t sim_io_ops_timer ;
36
- static int32_t bytes_processed ;
33
+ #define IO_STACK_SIZE configMINIMAL_STACK_SIZE
34
+
35
+ typedef struct {
36
+ uint8_t lun ;
37
+ bool is_read ;
38
+ uint32_t lba ;
39
+ uint32_t offset ;
40
+ void * buffer ;
41
+ uint32_t bufsize ;
42
+ } io_ops_t ;
43
+
44
+ QueueHandle_t io_queue ;
37
45
#if configSUPPORT_STATIC_ALLOCATION
38
- StaticTimer_t sim_io_ops_timer_buf ;
46
+ uint8_t io_queue_buf [sizeof (io_ops_t )];
47
+ StaticQueue_t io_queue_static ;
48
+ StackType_t io_stack [IO_STACK_SIZE ];
49
+ StaticTask_t io_taskdef ;
39
50
#endif
40
- static void sim_io_ops_done_cb (TimerHandle_t xTimer );
51
+
52
+ static void io_task (void * params );
41
53
#endif
42
54
43
55
void msc_disk_init (void );
@@ -133,20 +145,37 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
133
145
README_CONTENTS
134
146
};
135
147
136
- #if CFG_TUD_MSC_ASYNC_IO
148
+ #if CFG_EXAMPLE_MSC_ASYNC_IO
137
149
void msc_disk_init () {
138
150
139
- #if configSUPPORT_DYNAMIC_ALLOCATION
140
- sim_io_ops_timer = xTimerCreate ("sim_io_ops" , pdMS_TO_TICKS (SIM_IO_TIME_MS ), pdFALSE , NULL , sim_io_ops_done_cb );
151
+ #if configSUPPORT_STATIC_ALLOCATION
152
+ io_queue = xQueueCreateStatic (1 , sizeof (io_ops_t ), io_queue_buf , & io_queue_static );
153
+ xTaskCreateStatic (io_task , "io" , IO_STACK_SIZE , NULL , 2 , io_stack , & io_taskdef );
141
154
#else
142
- 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 );
155
+ io_queue = xQueueCreate (1 , sizeof (io_ops_t ));
156
+ xTaskCreate (io_task , "io" , IO_STACK_SIZE , NULL , 2 , NULL );
143
157
#endif
144
158
}
145
159
146
- static void sim_io_ops_done_cb (TimerHandle_t xTimer ) {
147
- (void ) xTimer ;
148
- tud_msc_async_io_done (bytes_processed );
160
+ static void io_task (void * params ) {
161
+ (void ) params ;
162
+ io_ops_t io_ops ;
163
+ while (1 ) {
164
+ if (xQueueReceive (io_queue , & io_ops , portMAX_DELAY )) {
165
+ if (io_ops .is_read ) {
166
+ uint8_t const * addr = msc_disk [io_ops .lba ] + io_ops .offset ;
167
+ memcpy (io_ops .buffer , addr , io_ops .bufsize );
168
+ } else {
169
+ uint8_t * addr = msc_disk [io_ops .lba ] + io_ops .offset ;
170
+ memcpy (addr , io_ops .buffer , io_ops .bufsize );
171
+ }
172
+
173
+ tusb_time_delay_ms_api (CFG_EXAMPLE_MSC_IO_DELAY_MS );
174
+ tud_msc_async_io_done (io_ops .bufsize );
175
+ }
176
+ }
149
177
}
178
+
150
179
#else
151
180
void msc_disk_init () {}
152
181
#endif
@@ -220,33 +249,31 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo
220
249
int32_t tud_msc_read10_cb (uint8_t lun , uint32_t lba , uint32_t offset , void * buffer , uint32_t bufsize )
221
250
{
222
251
(void ) lun ;
223
- int32_t ret = bufsize ;
224
252
225
253
// out of ramdisk
226
254
if ( lba >= DISK_BLOCK_NUM ) {
227
- ret = -1 ;
255
+ return TUD_MSC_RET_ERROR ;
228
256
}
229
257
230
258
// Check for overflow of offset + bufsize
231
259
if ( lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE ) {
232
- ret = -1 ;
260
+ return TUD_MSC_RET_ERROR ;
233
261
}
234
262
235
- if (ret != -1 ) {
236
- uint8_t const * addr = msc_disk [lba ] + offset ;
237
- memcpy (buffer , addr , bufsize );
238
- }
263
+ #if CFG_EXAMPLE_MSC_ASYNC_IO
264
+ io_ops_t io_ops = { .is_read = true, .lun = lun , .lba = lba , .offset = offset , .buffer = buffer , .bufsize = bufsize };
239
265
240
- #if CFG_TUD_MSC_ASYNC_IO
241
- // Simulate background read operation
242
- bytes_processed = ret ;
243
- xTimerStart ( sim_io_ops_timer , 0 ) ;
244
- #elif SIM_IO_TIME_MS > 0
245
- // Simulate read operation
246
- tusb_time_delay_ms_api ( SIM_IO_TIME_MS );
247
- #endif
266
+ // Send IO operation to IO task
267
+ TU_ASSERT ( xQueueSend ( io_queue , & io_ops , 0 ) == pdPASS );
268
+
269
+ return TUD_MSC_RET_ASYNC ;
270
+ #else
271
+ uint8_t const * addr = msc_disk [ lba ] + offset ;
272
+ memcpy ( buffer , addr , bufsize );
273
+ tusb_time_delay_ms_api ( CFG_EXAMPLE_MSC_IO_DELAY_MS );
248
274
249
- return ret ;
275
+ return bufsize ;
276
+ #endif
250
277
}
251
278
252
279
bool tud_msc_is_writable_cb (uint8_t lun )
@@ -264,38 +291,35 @@ bool tud_msc_is_writable_cb (uint8_t lun)
264
291
// Process data in buffer to disk's storage and return number of written bytes
265
292
int32_t tud_msc_write10_cb (uint8_t lun , uint32_t lba , uint32_t offset , uint8_t * buffer , uint32_t bufsize )
266
293
{
267
- (void ) lun ;
268
- int32_t ret = bufsize ;
269
-
270
294
// out of ramdisk
271
295
if ( lba >= DISK_BLOCK_NUM ) {
272
- ret = -1 ;
296
+ return TUD_MSC_RET_ERROR ;
273
297
}
274
298
275
299
// Check for overflow of offset + bufsize
276
300
if ( lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE ) {
277
- ret = -1 ;
301
+ return TUD_MSC_RET_ERROR ;
278
302
}
279
303
280
- #ifndef CFG_EXAMPLE_MSC_READONLY
281
- if (ret != -1 ) {
282
- uint8_t * addr = msc_disk [lba ] + offset ;
283
- memcpy (addr , buffer , bufsize );
284
- }
285
- #else
286
- (void ) lba ; (void ) offset ; (void ) buffer ;
304
+ #ifdef CFG_EXAMPLE_MSC_READONLY
305
+ (void ) lun ; (void ) buffer ;
306
+ return bufsize ;
287
307
#endif
288
308
289
- #if CFG_TUD_MSC_ASYNC_IO
290
- // Simulate background write operation
291
- bytes_processed = ret ;
292
- xTimerStart (sim_io_ops_timer , 0 );
293
- #elif SIM_IO_TIME_MS > 0
294
- // Simulate write operation
295
- tusb_time_delay_ms_api (SIM_IO_TIME_MS );
296
- #endif
309
+ #if CFG_EXAMPLE_MSC_ASYNC_IO
310
+ io_ops_t io_ops = { .is_read = false, .lun = lun , .lba = lba , .offset = offset , .buffer = buffer , .bufsize = bufsize };
311
+
312
+ // Send IO operation to IO task
313
+ TU_ASSERT (xQueueSend (io_queue , & io_ops , 0 ) == pdPASS );
297
314
298
- return ret ;
315
+ return TUD_MSC_RET_ASYNC ;
316
+ #else
317
+ uint8_t * addr = msc_disk [lba ] + offset ;
318
+ memcpy (addr , buffer , bufsize );
319
+ tusb_time_delay_ms_api (CFG_EXAMPLE_MSC_IO_DELAY_MS );
320
+
321
+ return bufsize ;
322
+ #endif
299
323
}
300
324
301
325
// Callback invoked when received an SCSI command not in built-in list below
0 commit comments