diff --git a/components/console/esp_console.h b/components/console/esp_console.h index 9bd5317f54c..73c8aed5c07 100644 --- a/components/console/esp_console.h +++ b/components/console/esp_console.h @@ -455,6 +455,7 @@ esp_err_t esp_console_start_repl(esp_console_repl_t *repl); * @brief Stop REPL environment * * @param[in] repl REPL handle returned from esp_console_new_repl_xxx + * @note This function waits for the console task to exit before it returns. * @return * - ESP_OK on success * - others on failure diff --git a/components/console/esp_console_common.c b/components/console/esp_console_common.c index ba80b13806a..cbd58f07b94 100644 --- a/components/console/esp_console_common.c +++ b/components/console/esp_console_common.c @@ -29,10 +29,6 @@ void esp_console_repl_task(void *args) * function is called. */ ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - if (repl_com->state_mux != NULL) { - xSemaphoreTake(repl_com->state_mux, portMAX_DELAY); - } - /* Change standard input and output of the task if the requested UART is * NOT the default one. This block will replace stdin, stdout and stderr. */ @@ -338,6 +334,10 @@ esp_err_t esp_console_new_repl_stdio(const esp_console_repl_config_t *repl_confi _exit: if (universal_repl) { esp_console_deinit(); + /* Only common_deinit() deletes state_mux, and the weak set_event_fd() never creates it. */ + if (universal_repl->repl_com.state_mux) { + vSemaphoreDelete(universal_repl->repl_com.state_mux); + } free(universal_repl); } if (ret_repl) { diff --git a/components/console/esp_console_repl_chip.c b/components/console/esp_console_repl_chip.c index b16c090ce33..cc3c42d9788 100644 --- a/components/console/esp_console_repl_chip.c +++ b/components/console/esp_console_repl_chip.c @@ -152,6 +152,10 @@ static esp_err_t esp_console_new_repl_uart_legacy(const esp_console_dev_uart_con _exit: if (uart_repl) { esp_console_deinit(); + /* Only common_deinit() deletes state_mux, and the weak set_event_fd() never creates it. */ + if (uart_repl->repl_com.state_mux) { + vSemaphoreDelete(uart_repl->repl_com.state_mux); + } free(uart_repl); } if (ret_repl) { diff --git a/components/console/esp_console_repl_internal.c b/components/console/esp_console_repl_internal.c index b2c291d4676..1186c05a64d 100644 --- a/components/console/esp_console_repl_internal.c +++ b/components/console/esp_console_repl_internal.c @@ -85,12 +85,13 @@ esp_err_t esp_console_internal_set_event_fd(esp_console_repl_com_t *repl_com) return ESP_FAIL; } - repl_com->state_mux = xSemaphoreCreateMutex(); + /* Empty on purpose, and the task only ever gives it, never takes it: a + * mutex created given lets a stop take it before the task has run. */ + repl_com->state_mux = xSemaphoreCreateBinary(); if (repl_com->state_mux == NULL) { ESP_LOGE(TAG, "state_mux create error"); return ESP_ERR_NO_MEM; } - xSemaphoreGive(repl_com->state_mux); return ESP_OK; } @@ -103,6 +104,7 @@ esp_err_t esp_console_common_deinit(esp_console_repl_com_t *repl_com) { // set the state to deinit to force the while loop in // esp_console_repl_task to break + const bool was_started = (repl_com->state == CONSOLE_REPL_STATE_START); repl_com->state = CONSOLE_REPL_STATE_DEINIT; if (s_interrupt_reading_fd == -1) { @@ -117,7 +119,9 @@ esp_err_t esp_console_common_deinit(esp_console_repl_com_t *repl_com) // wait for the task to notify that // esp_console_repl_task returned assert(repl_com->state_mux != NULL); - xSemaphoreTake(repl_com->state_mux, portMAX_DELAY); + if (was_started) { + xSemaphoreTake(repl_com->state_mux, portMAX_DELAY); + } // delete the semaphore for the repl state vSemaphoreDelete(repl_com->state_mux);