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.