Skip to content

Commit a60ee4e

Browse files
committed
Merge branch 'bugfix/uart_tx_done_timeout_check_v3.4' into 'release/v3.4'
fix: uart tx done timeout check (backport v3.4) See merge request sdk/ESP8266_RTOS_SDK!1607
2 parents 504fa5f + f9aca5a commit a60ee4e

File tree

1 file changed

+24
-1
lines changed
  • components/esp8266/driver

1 file changed

+24
-1
lines changed

components/esp8266/driver/uart.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,18 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait)
257257
uint32_t baudrate;
258258
uint32_t byte_delay_us = 0;
259259
BaseType_t res;
260+
portTickType ticks_cur;
261+
portTickType ticks_start = xTaskGetTickCount();
260262
portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait;
263+
/**
264+
* Considering the overflow of the ticks_end and the ticks_cur (xTaskGetTickCount()),
265+
* the possible tick timestamp is as follows:
266+
* (one start tick timestamp, two end tick timestamps, four current tick timestamps)
267+
*
268+
* ticks: 0 0xFFFFFFFF
269+
* |_______._______._______._______._______._______._______._______|
270+
* cur1 end1 cur2 start cur3 end2 cur4
271+
*/
261272

262273
// Take tx_mux
263274
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)
273284
uart_get_baudrate(uart_num, &baudrate);
274285
byte_delay_us = (uint32_t)(10000000 / baudrate); // (1/baudrate)*10*1000_000 us
275286

276-
ticks_to_wait = ticks_end - xTaskGetTickCount();
287+
ticks_cur = xTaskGetTickCount();
288+
if (ticks_start <= ticks_cur) {
289+
ticks_to_wait = ticks_to_wait - (ticks_cur - ticks_start);
290+
} else {
291+
ticks_to_wait = ticks_to_wait - (portMAX_DELAY - ticks_start + ticks_cur);
292+
}
277293
// wait for tx done sem.
278294
if (pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, ticks_to_wait)) {
279295
while (1) {
296+
ticks_cur = xTaskGetTickCount();
297+
bool end1_timeout = (ticks_end < ticks_start && ticks_cur < ticks_start && ticks_cur > ticks_end);
298+
bool end2_timeout = (ticks_start < ticks_end && (ticks_cur < ticks_start || ticks_end < ticks_cur));
299+
if (end1_timeout || end2_timeout) {
300+
xSemaphoreGive(p_uart_obj[uart_num]->tx_mux);
301+
return ESP_ERR_TIMEOUT;
302+
}
280303
if (UART[uart_num]->status.txfifo_cnt == 0) {
281304
ets_delay_us(byte_delay_us); // Delay one byte time to guarantee transmission completion
282305
break;

0 commit comments

Comments
 (0)