drivers: serial: nrfx_uarte: Fix misbehavior due to preemption
UART_RX_RDY event can be generated from UARTE interrupt or k_timer handler. When ENDRX event occurs then k_timer is stopped (it can be restarted if there is another buffer provided). However, if UARTE interrupt priority is higher than k_timer priority (RTC is used underneath) then k_timer handler may still be executed later. K_timer notifies new bytes based on RXDRDY HW event which is counter by the TIMER (using PPI). It may happen that RXDRDY event arrives due to byte received into RX FIFO but since there is not buffer provided it stays in that FIFO. Given all this, it was possible that RX_RDY event was reported from ENDRX UARTE event, timer was stopped but because UARTE interrupt had higher priority timer handler is executed after UARTE interrupt is handled. In timer handler TIMER counter reports more bytes and calls UART_RX_RDY event with null buffer and non-zero amount of bytes. Fixed by generating UART_RX_RDY event only if RX buffer is not null. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
24b9b60025
commit
5db338c035
|
@ -1047,9 +1047,11 @@ static void rx_timeout(struct k_timer *timer)
|
|||
(data->async->rx_timeout_left
|
||||
< data->async->rx_timeout_slab)) {
|
||||
/* rx_timeout us elapsed since last receiving */
|
||||
notify_uart_rx_rdy(dev, len);
|
||||
data->async->rx_offset += len;
|
||||
data->async->rx_total_user_byte_cnt += len;
|
||||
if (data->async->rx_buf != NULL) {
|
||||
notify_uart_rx_rdy(dev, len);
|
||||
data->async->rx_offset += len;
|
||||
data->async->rx_total_user_byte_cnt += len;
|
||||
}
|
||||
} else {
|
||||
data->async->rx_timeout_left -=
|
||||
data->async->rx_timeout_slab;
|
||||
|
|
Loading…
Reference in a new issue