From afc034e29438cafbe0a4032e364f2a508fa364e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Fri, 13 Oct 2023 13:36:53 +0200 Subject: [PATCH] samples: cdc_acm: Throttle RX when ringbuf is full MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent infinite loop inside interrupt handler when there is incoming data available and ring buffer is full. Signed-off-by: Tomasz Moń --- samples/subsys/usb/cdc_acm/src/main.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/samples/subsys/usb/cdc_acm/src/main.c b/samples/subsys/usb/cdc_acm/src/main.c index 4276bb2a12..6847ed8d11 100644 --- a/samples/subsys/usb/cdc_acm/src/main.c +++ b/samples/subsys/usb/cdc_acm/src/main.c @@ -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);