Skip to content

Commit 6c363a4

Browse files
committed
uart: Add missing critical section wrappers around rx_buffered_len
The missing barriers caused uart_get_buffered_data_len() to (very rarely) return a garbage value. When used in MicroPython, though, this caused select() to return and a subsequent read() to stall indefinitely until a char was actually available. Signed-off-by: Chen Yi Qun <[email protected]> Closes #6397 Merges #6396
1 parent de48a67 commit 6c363a4

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

components/driver/uart.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,9 @@ esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit)
257257
esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit)
258258
{
259259
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
260+
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
260261
uart_hal_get_stop_bits(&(uart_context[uart_num].hal), stop_bit);
262+
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
261263
return ESP_OK;
262264
}
263265

@@ -273,7 +275,9 @@ esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode)
273275
esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode)
274276
{
275277
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
278+
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
276279
uart_hal_get_parity(&(uart_context[uart_num].hal), parity_mode);
280+
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
277281
return ESP_OK;
278282
}
279283

@@ -1262,7 +1266,9 @@ esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size)
12621266
{
12631267
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
12641268
UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL);
1269+
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
12651270
*size = p_uart_obj[uart_num]->rx_buffered_len;
1271+
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
12661272
return ESP_OK;
12671273
}
12681274

@@ -1303,14 +1309,19 @@ esp_err_t uart_flush_input(uart_port_t uart_num)
13031309
}
13041310
data = (uint8_t*) xRingbufferReceive(p_uart->rx_ring_buf, &size, (portTickType) 0);
13051311
if(data == NULL) {
1312+
bool error = false;
1313+
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
13061314
if( p_uart_obj[uart_num]->rx_buffered_len != 0 ) {
1307-
ESP_LOGE(UART_TAG, "rx_buffered_len error");
13081315
p_uart_obj[uart_num]->rx_buffered_len = 0;
1316+
error = true;
13091317
}
13101318
//We also need to clear the `rx_buffer_full_flg` here.
1311-
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
13121319
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
13131320
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
1321+
if (error) {
1322+
// this must be called outside the critical section
1323+
ESP_LOGE(UART_TAG, "rx_buffered_len error");
1324+
}
13141325
break;
13151326
}
13161327
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));

0 commit comments

Comments
 (0)