AnsweredAssumed Answered

USB Host CDC Serial Blocking Issue

Question asked by v.k on Dec 17, 2014
Latest reply on Feb 1, 2015 by Daniel Chen

I'm using MQX 4.0 USB Host stack with the CDC serial driver to operate with a USB modem on the other end. I want to operate the USB "virtual" port in non-blocking mode, but the CDC driver blocks on a read (or for that matter CHAR_AVAIL), after issuing a request to usb stack. It waits on an lwevent, which is set in the callback of the transaction request. As per the MQXUSBHOSTRM, the read transaction will complete only when the requested number of bytes are sent received from the device, therefore effectively blocking the reading task.


I tried to modify the code to lwevent_wait for few ticks instead of infinitely, and then if the transaction times out, cancel the transaction. But, by doing this, I soon run out of memory and no new transactions can be placed.


Has anybody been able to find a workaround for this?


The extract from the usb_host_cdc file for the _io_cdc_serial_read function is below.


while (num_left) {

        usb_hostdev_tr_init(&tr, (tr_callback) usb_class_cdc_in_data_callback, (pointer) fd_ptr);

        if (num_left > block_len) {

            tr.G.RX_BUFFER = (uchar_ptr) data_ptr;

            tr.G.RX_LENGTH = block_len * (num_left / block_len);

            if_ptr->RX_BUFFER_DRV = NULL;


        else {

            /* last packet must be always written to the local buffer, because device can send more bytes than we need to read */

            if_ptr->RX_BUFFER_APP = if_ptr->RX_BUFFER;

            if_ptr->RX_BUFFER_DRV = if_ptr->RX_BUFFER;

            tr.G.RX_BUFFER = (uchar_ptr) if_ptr->RX_BUFFER;

            tr.G.RX_LENGTH = block_len;




        if (event != NULL) {

            _lwevent_clear(event, USB_DATA_READ_COMPLETE);


        status = _usb_host_recv_data(if_ptr->CDC_G.G.host_handle, if_ptr->in_pipe, &tr);

        if (status == USB_STATUS_TRANSFER_QUEUED) {


            if (event != NULL) {


                /* serialize requests by waiting for pipe */

                /* wait while data will be available */

                _lwevent_wait_ticks(event, USB_DATA_READ_COMPLETE | USB_DATA_DETACH, FALSE, 0);