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:
parent
26a403d629
commit
afc034e294
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue