@@ -48,13 +48,25 @@ enum {
4848
4949static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED ;
5050
51- void led_blinking_task (void );
52- void video_task (void );
51+ void led_blinking_task (void * param );
52+ void usb_device_task (void * param );
53+ void video_task (void * param );
5354
54- /*------------- MAIN -------------*/
55+ #if CFG_TUSB_OS == OPT_OS_FREERTOS
56+ void freertos_init_task (void );
57+ #endif
58+
59+
60+ //--------------------------------------------------------------------+
61+ // Main
62+ //--------------------------------------------------------------------+
5563int main (void ) {
5664 board_init ();
5765
66+ // If using FreeRTOS: create blinky, tinyusb device, video task
67+ #if CFG_TUSB_OS == OPT_OS_FREERTOS
68+ freertos_init_task ();
69+ #else
5870 // init device stack on configured roothub port
5971 tud_init (BOARD_TUD_RHPORT );
6072
@@ -64,10 +76,10 @@ int main(void) {
6476
6577 while (1 ) {
6678 tud_task (); // tinyusb device task
67- led_blinking_task ();
68-
69- video_task ();
79+ led_blinking_task (NULL );
80+ video_task (NULL );
7081 }
82+ #endif
7183}
7284
7385//--------------------------------------------------------------------+
@@ -169,7 +181,7 @@ static void fill_color_bar(uint8_t* buffer, unsigned start_position) {
169181
170182#endif
171183
172- void video_task (void ) {
184+ void video_send_frame (void ) {
173185 static unsigned start_ms = 0 ;
174186 static unsigned already_sent = 0 ;
175187
@@ -213,6 +225,21 @@ void video_task(void) {
213225#endif
214226}
215227
228+
229+ void video_task (void * param ) {
230+ (void ) param ;
231+
232+ while (1 ) {
233+ video_send_frame ();
234+
235+ #if CFG_TUSB_OS == OPT_OS_FREERTOS
236+ vTaskDelay (interval_ms / portTICK_PERIOD_MS );
237+ #else
238+ return ;
239+ #endif
240+ }
241+ }
242+
216243void tud_video_frame_xfer_complete_cb (uint_fast8_t ctl_idx , uint_fast8_t stm_idx ) {
217244 (void ) ctl_idx ;
218245 (void ) stm_idx ;
@@ -231,16 +258,92 @@ int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
231258}
232259
233260//--------------------------------------------------------------------+
234- // BLINKING TASK
261+ // Blinking Task
235262//--------------------------------------------------------------------+
236- void led_blinking_task (void ) {
263+ void led_blinking_task (void * param ) {
264+ (void ) param ;
237265 static uint32_t start_ms = 0 ;
238266 static bool led_state = false;
239267
240- // Blink every interval ms
241- if (board_millis () - start_ms < blink_interval_ms ) return ; // not enough time
242- start_ms += blink_interval_ms ;
268+ while (1 ) {
269+ #if CFG_TUSB_OS == OPT_OS_FREERTOS
270+ vTaskDelay (blink_interval_ms / portTICK_PERIOD_MS );
271+ #else
272+ if (board_millis () - start_ms < blink_interval_ms ) return ; // not enough time
273+ #endif
274+
275+ start_ms += blink_interval_ms ;
276+ board_led_write (led_state );
277+ led_state = 1 - led_state ; // toggle
278+ }
279+ }
280+
281+ //--------------------------------------------------------------------+
282+ // FreeRTOS
283+ //--------------------------------------------------------------------+
284+ #if CFG_TUSB_OS == OPT_OS_FREERTOS
285+
286+ #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
287+ #define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4)
288+
289+ #if TU_CHECK_MCU (OPT_MCU_ESP32S2 , OPT_MCU_ESP32S3 )
290+ #define USBD_STACK_SIZE 4096
291+ int main (void );
292+ void app_main (void ) {
293+ main ();
294+ }
295+ #else
296+ // Increase stack size when debug log is enabled
297+ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
298+ #endif
299+
300+ // static task
301+ #if configSUPPORT_STATIC_ALLOCATION
302+ StackType_t blinky_stack [BLINKY_STACK_SIZE ];
303+ StaticTask_t blinky_taskdef ;
304+
305+ StackType_t usb_device_stack [USBD_STACK_SIZE ];
306+ StaticTask_t usb_device_taskdef ;
307+
308+ StackType_t video_stack [VIDEO_STACK_SIZE ];
309+ StaticTask_t video_taskdef ;
310+ #endif
311+
312+ // USB Device Driver task
313+ // This top level thread process all usb events and invoke callbacks
314+ void usb_device_task (void * param ) {
315+ (void ) param ;
316+
317+ // init device stack on configured roothub port
318+ // This should be called after scheduler/kernel is started.
319+ // Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API.
320+ tud_init (BOARD_TUD_RHPORT );
321+
322+ if (board_init_after_tusb ) {
323+ board_init_after_tusb ();
324+ }
243325
244- board_led_write (led_state );
245- led_state = 1 - led_state ; // toggle
326+ // RTOS forever loop
327+ while (1 ) {
328+ // put this thread to waiting state until there is new events
329+ tud_task ();
330+ }
246331}
332+
333+ void freertos_init_task (void ) {
334+ #if configSUPPORT_STATIC_ALLOCATION
335+ xTaskCreateStatic (led_blinking_task , "blinky" , BLINKY_STACK_SIZE , NULL , 1 , blinky_stack , & blinky_taskdef );
336+ xTaskCreateStatic (usb_device_task , "usbd" , USBD_STACK_SIZE , NULL , configMAX_PRIORITIES - 1 , usb_device_stack , & usb_device_taskdef );
337+ xTaskCreateStatic (video_task , "cdc" , VIDEO_STACK_SIZE , NULL , configMAX_PRIORITIES - 2 , video_stack , & video_taskdef );
338+ #else
339+ xTaskCreate (led_blinking_task , "blinky" , BLINKY_STACK_SIZE , NULL , 1 , NULL );
340+ xTaskCreate (usb_device_task , "usbd" , USBD_STACK_SIZE , NULL , configMAX_PRIORITIES - 1 , NULL );
341+ xTaskCreate (video_task , "video" , VIDEO_STACK_SZIE , NULL , configMAX_PRIORITIES - 2 , NULL );
342+ #endif
343+
344+ // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
345+ #if !TU_CHECK_MCU (OPT_MCU_ESP32S2 , OPT_MCU_ESP32S3 )
346+ vTaskStartScheduler ();
347+ #endif
348+ }
349+ #endif
0 commit comments