@@ -24,6 +24,9 @@ static portMUX_TYPE tusb_task_lock = portMUX_INITIALIZER_UNLOCKED;
2424#define TINYUSB_TASK_ENTER_CRITICAL () portENTER_CRITICAL(&tusb_task_lock)
2525#define TINYUSB_TASK_EXIT_CRITICAL () portEXIT_CRITICAL(&tusb_task_lock)
2626
27+ // Timeout for taking the start/stop semaphore in milliseconds
28+ #define TINYUSB_TASK_SEM_TAKE_TIMEOUT_MS (5000)
29+
2730#define TINYUSB_TASK_CHECK (cond , ret_val ) ({ \
2831 if (!(cond)) { \
2932 return (ret_val); \
@@ -59,7 +62,7 @@ static tinyusb_task_ctx_t *p_tusb_task_ctx = NULL; // TinyUSB task context
5962static void tinyusb_device_task (void * arg )
6063{
6164 tinyusb_task_ctx_t * task_ctx = (tinyusb_task_ctx_t * )arg ;
62- bool pending_stop = false;
65+ bool stop_in_pending = false;
6366
6467 // Sanity check
6568 assert (task_ctx != NULL );
@@ -103,7 +106,7 @@ static void tinyusb_device_task(void *arg)
103106 0 // no wait; just poll the bit
104107 ) == pdTRUE && (notif & TASK_NOTIF_STOP_BIT )) {
105108 // Stop requested
106- pending_stop = true;
109+ stop_in_pending = true;
107110 break ;
108111 }
109112 // TinyUSB Device task
@@ -125,7 +128,7 @@ static void tinyusb_device_task(void *arg)
125128 p_tusb_task_ctx = NULL ; // Clear global task context pointer
126129 TINYUSB_TASK_EXIT_CRITICAL ();
127130
128- if (pending_stop ) {
131+ if (stop_in_pending ) {
129132 // Notify that TinyUSB stack was stopped
130133 xSemaphoreGive (task_ctx -> start_stop_sem );
131134 }
@@ -158,14 +161,11 @@ esp_err_t tinyusb_task_start(tinyusb_port_t port, const tinyusb_task_config_t *c
158161
159162 esp_err_t ret ;
160163 tinyusb_task_ctx_t * task_ctx = heap_caps_calloc (1 , sizeof (tinyusb_task_ctx_t ), MALLOC_CAP_DEFAULT );
161- if (task_ctx == NULL ) {
162- return ESP_ERR_NO_MEM ;
163- }
164-
165164 SemaphoreHandle_t sem = xSemaphoreCreateBinary ();
166- if (sem == NULL ) {
165+
166+ if (task_ctx == NULL || sem == NULL ) {
167167 ret = ESP_ERR_NO_MEM ;
168- goto err ;
168+ goto no_task ;
169169 }
170170
171171 task_ctx -> start_stop_sem = sem ; // TunyUSB Device task start stop semaphore
@@ -187,18 +187,28 @@ esp_err_t tinyusb_task_start(tinyusb_port_t port, const tinyusb_task_config_t *c
187187 if (task_hdl == NULL ) {
188188 ESP_LOGE (TAG , "Create TinyUSB main task failed" );
189189 ret = ESP_ERR_NOT_FINISHED ;
190- goto err ;
190+ goto no_task ;
191191 }
192192
193- // Wait until the Task notify that port is active, 5 sec is more than enough
194- if (xSemaphoreTake (task_ctx -> start_stop_sem , pdMS_TO_TICKS (5000 )) != pdTRUE ) {
193+ // Wait for "start" semophore with timeout
194+ if (xSemaphoreTake (task_ctx -> start_stop_sem , pdMS_TO_TICKS (TINYUSB_TASK_SEM_TAKE_TIMEOUT_MS )) != pdTRUE ) {
195195 ESP_LOGE (TAG , "Task wasn't able to start TinyUSB stack" );
196196 ret = ESP_ERR_TIMEOUT ;
197197 goto err ;
198198 }
199199
200+ // Check the global task context pointer and pending state
201+ TINYUSB_TASK_ENTER_CRITICAL ();
202+ TINYUSB_TASK_CHECK_FROM_CRIT (!_task_is_pending , ESP_ERR_INVALID_STATE );
203+ TINYUSB_TASK_CHECK_FROM_CRIT (p_tusb_task_ctx == task_ctx , ESP_ERR_NOT_FOUND );
204+ TINYUSB_TASK_EXIT_CRITICAL ();
205+
200206 return ESP_OK ;
201207
208+ no_task :
209+ TINYUSB_TASK_ENTER_CRITICAL ();
210+ _task_is_pending = false; // Clear pending flag
211+ TINYUSB_TASK_EXIT_CRITICAL ();
202212err :
203213 if (sem ) {
204214 vSemaphoreDelete (sem );
@@ -222,12 +232,18 @@ esp_err_t tinyusb_task_stop(void)
222232 return ESP_ERR_INVALID_STATE ;
223233 }
224234
225- /* Wait for "stop" semaphore with timeout, usually 5 sec is enough */
226- if (xSemaphoreTake (task_ctx -> start_stop_sem , pdMS_TO_TICKS (5000 )) != pdTRUE ) {
235+ /* Wait for "stop" semaphore with timeout */
236+ if (xSemaphoreTake (task_ctx -> start_stop_sem , pdMS_TO_TICKS (TINYUSB_TASK_SEM_TAKE_TIMEOUT_MS )) != pdTRUE ) {
227237 ESP_LOGE (TAG , "Timeout while TinyUSB task stop" );
228238 return ESP_ERR_TIMEOUT ;
229239 }
230240
241+ /* Check the global task context pointer and pending state */
242+ TINYUSB_TASK_ENTER_CRITICAL ();
243+ TINYUSB_TASK_CHECK_FROM_CRIT (!_task_is_pending , ESP_ERR_INVALID_STATE );
244+ TINYUSB_TASK_CHECK_FROM_CRIT (p_tusb_task_ctx == NULL , ESP_ERR_INVALID_STATE );
245+ TINYUSB_TASK_EXIT_CRITICAL ();
246+
231247 /* Cleanup */
232248 vSemaphoreDelete (task_ctx -> start_stop_sem );
233249 heap_caps_free (task_ctx );
0 commit comments