samples: cdc_acm: Throttle RX when ringbuf is full

Prevent infinite loop inside interrupt handler when there is incoming
data available and ring buffer is full.

Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
This commit is contained in:
Tomasz Moń 2023-10-13 13:36:53 +02:00 committed by Carles Cufí
parent 26a403d629
commit afc034e294

View file

@ -29,6 +29,8 @@ uint8_t ring_buffer[RING_BUF_SIZE];
struct ring_buf ringbuf;
static bool rx_throttled;
#if defined(CONFIG_USB_DEVICE_STACK_NEXT)
USBD_CONFIGURATION_DEFINE(config_1,
USB_SCD_SELF_POWERED,
@ -106,12 +108,19 @@ static void interrupt_handler(const struct device *dev, void *user_data)
ARG_UNUSED(user_data);
while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
if (uart_irq_rx_ready(dev)) {
if (!rx_throttled && uart_irq_rx_ready(dev)) {
int recv_len, rb_len;
uint8_t buffer[64];
size_t len = MIN(ring_buf_space_get(&ringbuf),
sizeof(buffer));
if (len == 0) {
/* Throttle because ring buffer is full */
uart_irq_rx_disable(dev);
rx_throttled = true;
continue;
}
recv_len = uart_fifo_read(dev, buffer, len);
if (recv_len < 0) {
LOG_ERR("Failed to read UART FIFO");
@ -140,6 +149,11 @@ static void interrupt_handler(const struct device *dev, void *user_data)
continue;
}
if (rx_throttled) {
uart_irq_rx_enable(dev);
rx_throttled = false;
}
send_len = uart_fifo_fill(dev, buffer, rb_len);
if (send_len < rb_len) {
LOG_ERR("Drop %d bytes", rb_len - send_len);