What is "usb_cdc_acm: Ring buffer full, drop"

Hello!

I am programming BLE with the nRF52840-DK. [Toolchain Manager: v1.3.0, IDE: Visual Studio Code (VSCode), SDK: ncs v2.6.0, window11 pro]

I am integrating NUS central and  CDC ACM . My current goal is to send data received via Bluetooth to a PC (PuTTY) through USB.

1. The result shows '[00:00:48.676,879] <wrn> usb_cdc_acm: Ring buffer full, drop 704 bytes,' and I’m curious about the meaning of this. I believe the ring buffer mentioned in the error message is different from the ring buffer (ringbuf1) in my code.

2. Could you also suggest a possible solution?

Below are the debugging results of my code.

[00:00:48.494,873] <inf> cho: --------------------------------------------------------------------------------------
[00:00:48.506,103] <inf> cho: ble_data_received - 108th, 244 bytes
[00:00:48.512,695] <inf> cho: ble_data_received - ring_buf_space_get: 108th, 2048 bytes
[00:00:48.521,148] <inf> cho: ble_data_received - ring_buf_get: 244 bytes
[00:00:48.528,350] <inf> cho: ble_data_received - Sent: 244 bytes
[00:00:48.534,851] <inf> cho: --------------------------------------------------------------------------------------
[00:00:48.545,837] <inf> cho: ble_data_received - 109th, 244 bytes
[00:00:48.552,429] <inf> cho: ble_data_received - ring_buf_space_get: 109th, 2048 bytes
[00:00:48.560,882] <inf> cho: ble_data_received - ring_buf_get: 244 bytes
[00:00:48.568,054] <wrn> usb_cdc_acm: Ring buffer full, drop 216 bytes
[00:00:48.575,286] <inf> cho: ble_data_received - Sent: 28 bytes
[00:00:48.581,726] <wrn> cho: ble_data_received - send_len < rb_len: 216
[00:00:48.589,233] <inf> cho: --------------------------------------------------------------------------------------
[00:00:48.600,463] <inf> cho: ble_data_received - 110th, 244 bytes
[00:00:48.607,055] <inf> cho: ble_data_received - ring_buf_space_get: 110th, 1832 bytes
[00:00:48.615,509] <inf> cho: ble_data_received - ring_buf_get: 460 bytes
[00:00:48.622,680] <wrn> usb_cdc_acm: Ring buffer full, drop 460 bytes
[00:00:48.629,913] <inf> cho: ble_data_received - Sent: 0 bytes
[00:00:48.636,291] <wrn> cho: ble_data_received - send_len < rb_len: 460
[00:00:48.643,646] <inf> cho: --------------------------------------------------------------------------------------
[00:00:48.654,632] <inf> cho: ble_data_received - 111th, 244 bytes
[00:00:48.661,224] <inf> cho: ble_data_received - ring_buf_space_get: 111th, 1588 bytes
[00:00:48.669,708] <inf> cho: ble_data_received - ring_buf_get: 704 bytes
[00:00:48.676,879] <wrn> usb_cdc_acm: Ring buffer full, drop 704 bytes
[00:00:48.684,112] <inf> cho: ble_data_received - Sent: 0 bytes
[00:00:48.690,643] <wrn> cho: ble_data_received - send_len < rb_len: 704
[00:00:48.698,028] <inf> cho: --------------------------------------------------------------------------------------
[00:00:48.709,259] <inf> cho: ble_data_received - 112th, 244 bytes
[00:00:48.715,850] <inf> cho: ble_data_received - ring_buf_space_get: 112th, 1344 bytes
[00:00:48.724,365] <inf> cho: ble_data_received - ring_buf_get: 948 bytes
[00:00:48.731,536] <wrn> usb_cdc_acm: Ring buffer full, drop 948 bytes
[00:00:48.738,739] <inf> cho: ble_data_received - Sent: 0 bytes
[00:00:48.745,147] <wrn> cho: ble_data_received - send_len < rb_len: 948
[00:00:48.752,532] <inf> cho: --------------------------------------------------------------------------------------


- Below is the code related to cdc_acm.

static int cdc_acm_init(void){
	int err;
	uint32_t baudrate = 0U;
	 uint32_t dtr = 0U;
	if (!device_is_ready(usbd_dev)) {
        LOG_ERR("CDC ACM device not ready");
        return -ENODEV;
    }
	err = usb_enable(NULL);
	LOG_INF("main - usb_enable>> %d", err);
	while (true) {
        uart_line_ctrl_get(usbd_dev, UART_LINE_CTRL_DTR, &dtr);	
        if (dtr) {
			LOG_INF("DTR set");
            break;
        } else {
            k_sleep(K_MSEC(100));
        }
    }
	err = uart_line_ctrl_set(usbd_dev, UART_LINE_CTRL_DCD, 1);
    err = uart_line_ctrl_set(usbd_dev, UART_LINE_CTRL_DSR, 1);
	err = uart_line_ctrl_get(usbd_dev, UART_LINE_CTRL_BAUD_RATE, &baudrate);
	err = uart_irq_callback_set(usbd_dev, interrupt_handler);
	return err;
}

static void interrupt_handler(const struct device *dev, void *user_data){
//	LOG_INF("interrupt_handler");
}

int main(void) {
    int main_err;

    ring_buf_init(&ringbuf1, sizeof(buffer1), buffer1);
	current_rx_buf = &ringbuf1;

	/*************************        USBD       *************************/ 
	main_err = cdc_acm_init();
    uart_irq_tx_enable(usbd_dev);
	/************************* Bluetooth Central *************************/
	bt_conn_cb_register(&conn_callbacks);
    main_err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
    main_err = bt_enable(NULL);
    if (IS_ENABLED(CONFIG_SETTINGS)) {
        settings_load();
    }

    main_err = scan_init();
    main_err = nus_client_init();
    main_err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);

    return 0;
}

- Below is the callback code for ble_receive.

static uint8_t ble_data_received(struct bt_nus_client *nus, const uint8_t *data, uint16_t len){
 	ARG_UNUSED(nus);
	int rb_len;
	int send_len;
	uint8_t buffer[1024];
	size_t space = ring_buf_space_get(&ringbuf1);
    LOG_INF("ble_data_received - %dth, %d bytes", rx_count, len);
	LOG_INF("ble_data_received - ring_buf_space_get: %dth, %d bytes", rx_count, space);

    rb_len = ring_buf_put(&ringbuf1, data, len);
    if (rb_len < len) {
        LOG_WRN("ble_data_received - %dth  Current RX buffer full, dropped %d bytes", rx_count, len - rb_len);
    }

	rb_len = ring_buf_get(&ringbuf1, buffer, sizeof(buffer));
	LOG_INF("ble_data_received - ring_buf_get: %d bytes", rb_len);

	if (rb_len != 0) {
		send_len = uart_fifo_fill(usbd_dev, buffer, rb_len);
		LOG_INF("ble_data_received - Sent: %d bytes", send_len);
		if (send_len < rb_len) {
			ring_buf_put(current_rx_buf, buffer + send_len, rb_len - send_len);
			LOG_WRN("ble_data_received - send_len < rb_len: %d", rb_len - send_len);
		}
	}
    LOG_INF("--------------------------------------------------------------------------------------");
    rx_count++;
    return BT_GATT_ITER_CONTINUE;
}

  • Is this the only possible solution?

    static uint8_t ble_data_received(struct bt_nus_client *nus, const uint8_t *data, uint16_t len){
     	ARG_UNUSED(nus);
        int rb_len = ring_buf_put(&ringbuf1, data, len);
        if (rb_len < len) {
            LOG_WRN("ble_data_received - %dth  Current RX buffer full, dropped %d bytes", rx_count, len - rb_len);
        }
    
        uart_irq_tx_enable(usbd_dev);
    	
    	if(uart_irq_update(usbd_dev) && uart_irq_is_pending(usbd_dev)){
    		if (uart_irq_tx_ready(usbd_dev)){
    
    			rb_len = ring_buf_get(&ringbuf1, buffer, sizeof(buffer));
    			if (rb_len == 0) {
    				uart_irq_tx_disable(usbd_dev);
    			} else {
    				int send_len = uart_fifo_fill(usbd_dev, buffer, rb_len);
    				if (send_len < rb_len) {
    					ring_buf_put(&ringbuf1, buffer + send_len, rb_len - send_len);
    				}
    
    			}
    		}
    	}
    
    	rx_count++;
        return BT_GATT_ITER_CONTINUE;
    }

  • Hi,

    I see that you run the ringbuffer code at the same time as your bluetooth sample.

    I suggest that you try to reproduce the issue with only the ringbuffer/CDC ACM code, without bluetooth. This way you have a simpler sample and it should be easier to track down what goes wrong.

    Regards,
    Sigurd Hellesvik

Related