AnsweredAssumed Answered

SDK: Adding a Read/Write Interface for the USB Virtual COM Device

Question asked by Kenny Koller on Nov 28, 2018
Latest reply on Dec 5, 2018 by Kenny Koller

I'm using a K64 with SDK 2.4.2 and FreeRTOS. I'd like to extend the example code to provide read and write functions that block with a timeout. For example:

count = virtual_com_read(buffer, 8, timeout);

Would return after either timeout milliseconds or 8 bytes was read from the bus. It would return the actual number of bytes read.

 

I have experience using the RTOS. My questions are more about interpreting the existing code. Here are my questions:

 

This routine looks promising:

extern usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length);

 

May I pass a buffer of any length? Will it block? Is there a way to specify a timeout?

 

Elsewhere in USB_DeviceCdcVcomCallback when kUSB_DeviceCdcEventSendResponse is handled there is the following (sorry the source code formatting is not working in Chrome ):

 

else if ((1 == _cdcvc.attach) && (1 == _cdcvc.startTransactions))
{
  if ((epCbParam->buffer != NULL) ||

      ((epCbParam->buffer == NULL) && (epCbParam->length == 0)))
  {
    /* User: add your own code for send complete event */
    /* Schedule buffer for next receive event */
    error = USB_DeviceCdcAcmRecv(handle,

                                 USB_CDC_VCOM_BULK_OUT_ENDPOINT,                                                     _receive_buffer,
                                 g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);

I can see how I might use this in combination with USB_DeviceCdcAcmSend to create my virtual_com_send routine by adding an RTOS primitive.

 

Why though is this code called when the callback buffer is not null? What is in this buffer?

 

If I were to add a timeout how may I return the number of bytes actually written to the host?

 

What are some suggestions for implementing my read function?

 

Finally, there is a macro USB_DEVICE_CONFIG_USE_TASK which ultimately allows a task to periodically call:

void USB_DeviceTaskFunction(void *deviceHandle)
{
  usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
  static usb_device_callback_message_struct_t message;

  if (deviceHandle)
  {

    /* Get the message from the queue */

    if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(handle->notificationQueue,

                                                  (uint32_t *)&message, 0U))
    {
      /* Handle the message */
      USB_DeviceNotification(handle, &message);
    }
  }
}

This function is ultimately calling FreeRTOS's xQueueReceive with a timeout of zero. It would be nice to support a timeout as that task will return immediately whether or not a message is in the queue. So this task will starve other tasks at lower priority. I can sleep a bit in the calling task but that will always add that latency rather than only when a message is unavailable (if I understand this correctly).

 

Thanks for reading.

Outcomes