Skip to content

Commit eb5ac5d

Browse files
committed
fix the _task_pending status change on error
1 parent a9a6d2a commit eb5ac5d

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

device/esp_tinyusb/tinyusb_task.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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
5962
static 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();
202212
err:
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

Comments
 (0)