mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-18 07:36:43 +08:00
Merge branch 'bugfix/uart_tx_done_timeout_check' into 'master'
fix(uart): potential blocking code when call uart_wait_tx_done() See merge request sdk/ESP8266_RTOS_SDK!1599
This commit is contained in:
@ -257,7 +257,18 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait)
|
||||
uint32_t baudrate;
|
||||
uint32_t byte_delay_us = 0;
|
||||
BaseType_t res;
|
||||
portTickType ticks_cur;
|
||||
portTickType ticks_start = xTaskGetTickCount();
|
||||
portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait;
|
||||
/**
|
||||
* Considering the overflow of the ticks_end and the ticks_cur (xTaskGetTickCount()),
|
||||
* the possible tick timestamp is as follows:
|
||||
* (one start tick timestamp, two end tick timestamps, four current tick timestamps)
|
||||
*
|
||||
* ticks: 0 0xFFFFFFFF
|
||||
* |_______._______._______._______._______._______._______._______|
|
||||
* cur1 end1 cur2 start cur3 end2 cur4
|
||||
*/
|
||||
|
||||
// Take tx_mux
|
||||
res = xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)ticks_to_wait);
|
||||
@ -273,10 +284,22 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait)
|
||||
uart_get_baudrate(uart_num, &baudrate);
|
||||
byte_delay_us = (uint32_t)(10000000 / baudrate); // (1/baudrate)*10*1000_000 us
|
||||
|
||||
ticks_to_wait = ticks_end - xTaskGetTickCount();
|
||||
ticks_cur = xTaskGetTickCount();
|
||||
if (ticks_start <= ticks_cur) {
|
||||
ticks_to_wait = ticks_to_wait - (ticks_cur - ticks_start);
|
||||
} else {
|
||||
ticks_to_wait = ticks_to_wait - (portMAX_DELAY - ticks_start + ticks_cur);
|
||||
}
|
||||
// wait for tx done sem.
|
||||
if (pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, ticks_to_wait)) {
|
||||
while (1) {
|
||||
ticks_cur = xTaskGetTickCount();
|
||||
bool end1_timeout = (ticks_end < ticks_start && ticks_cur < ticks_start && ticks_cur > ticks_end);
|
||||
bool end2_timeout = (ticks_start < ticks_end && (ticks_cur < ticks_start || ticks_end < ticks_cur));
|
||||
if (end1_timeout || end2_timeout) {
|
||||
xSemaphoreGive(p_uart_obj[uart_num]->tx_mux);
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
if (UART[uart_num]->status.txfifo_cnt == 0) {
|
||||
ets_delay_us(byte_delay_us); // Delay one byte time to guarantee transmission completion
|
||||
break;
|
||||
|
Reference in New Issue
Block a user