sf_el_ux_comms_v2, check RX before reading

I'm using the communication framework on USBX, I've noticed that the read function ( that is SF_EL_UX_COMMS_Read) is blocking and wait for the given number of bytes to be read before returning.

I was wondering if there is a way to know in advance how many bytes are available in the RX buffer before calling this.  Or eventually having a callback so that I know when there are some new bytes available on the RX buffer.

Is that possible?

  • David,

    It is not possible to know the number of bytes in the buffer because a USB CDC transfer is complete when all requested bytes or a packet size less than wMaxPacketSize is received.

    I suggest that you request 1 byte and change the TX_WAIT_FOREVER to then number of system ticks to wait for the data. The return status will be SSP_ERR_TIMEOUT if you timed out waiting for data or SSP_SUCCESS if you have received the requested number of bytes.

    status = g_sf_comms0.p_api->read(g_sf_comms0.p_ctrl, &byte, 1 ,TX_WAIT_FOREVER);

    -Gary
  • In reply to garyj:

    Hi garyj,
    Thank you for your reply. I've tried to do that but no matter which timeout I put if there are no bytes to be read the g_sf_comms0.p_api->read() is blocking. I took a look in the source code and it seems like that the timeout is the timeout for the mutex to get exclusive access to the driver. As stated in the Communication framework on USBX document for the read API: "Read data from communications driver. This call returns after the number of bytes requested
    is read or if a timeout occurs while waiting for access to the driver."
    In another forum thread ( that I cannot find now..) someone suggested creating a thread for the receiving part. I would have avoided that but if it is the only possible solution I will go for it.
  • In reply to davide_hanhaa:

    Hello,
    When using the comms framework with USB-CDC then g_sf_comms0.p_api->read() is blocking, regardless of the timeout. The timeout is as you correctly mentioned, for getting the mutex.
    g_sf_comms0.p_api->read() will only return when the number of bytes specified is received. Therefore, do as Gary suggested and read a single byte.
    Because the read does block, then in my examples I do have a dedicated thread just for reading. Potentially a bit annoying having to have another thread just for this, but it does seem to provide a reliable way of asynchronously receiving data.
    But, I do believe that the lower level USBX API calls have been updated to use a timeout on the data reception. I will check this and see how this can be implemented.
    Regards,
    Richard
  • In reply to Richard:

    Hello,
    Further to my post yesterday please find attached an example that shows USB CDC data read / write in a non blocking single thread application.

    Please note that this does not use the comms framework.  It operates one level down via the USBX Device Class CDC-ACM stack.

    Additionally, its uses the function:

    ux_device_class_cdc_acm_ioctl()

    with two callback functions for handling data write and data read.

    The use of the callbacks allow for non-blocking functionality.

     

    In this example any data received is double buffered and the address of the active buffer is posted to a queue.

    Any data sent to the queue is echoed back to the host

    Hope this is of interest.

     

    BR, Richard

     

    S5D5_TB_CDC_ACM_non_blocking.zip