mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-10-20 22:31:30 +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 baudrate;
|
||||||
uint32_t byte_delay_us = 0;
|
uint32_t byte_delay_us = 0;
|
||||||
BaseType_t res;
|
BaseType_t res;
|
||||||
|
portTickType ticks_cur;
|
||||||
|
portTickType ticks_start = xTaskGetTickCount();
|
||||||
portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait;
|
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
|
// Take tx_mux
|
||||||
res = xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)ticks_to_wait);
|
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);
|
uart_get_baudrate(uart_num, &baudrate);
|
||||||
byte_delay_us = (uint32_t)(10000000 / baudrate); // (1/baudrate)*10*1000_000 us
|
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.
|
// wait for tx done sem.
|
||||||
if (pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, ticks_to_wait)) {
|
if (pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, ticks_to_wait)) {
|
||||||
while (1) {
|
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) {
|
if (UART[uart_num]->status.txfifo_cnt == 0) {
|
||||||
ets_delay_us(byte_delay_us); // Delay one byte time to guarantee transmission completion
|
ets_delay_us(byte_delay_us); // Delay one byte time to guarantee transmission completion
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user