Task Model

µC/USB-Device requires two tasks: One core task and one optional task for tracing debug events. The core task has three main responsibilities:

  • Process USB bus events: Bus events such as reset, suspend, connect and disconnect are processed by the core task. Based on the type of bus event, the core task sets the state of the device.
  • Process USB requests: USB requests are sent by the host using the default control endpoint. The core task processes all USB requests. Some requests are handled by the USB class driver, for those requests the core calls the class-specific request handler.
  • Process I/O asynchronous transfers: Asynchronous I/O transfers are handled by the core. Under completion, the core task invokes the respective callback for the transfer.
Figure - µC/USB-Device Task Model shows a simplified task model of µC/USB-Device along with application tasks.

Figure - µC/USB-Device Task Model


Sending and Receiving Data

Figure - Sending and Receiving a Packet shows a simplified task model of µC/USB-Device when data is transmitted and received through the USB device controller. With µC/USB-Device, data can be sent asynchronously or synchronously. In a synchronous operation, the application blocks execution until the transfer operation completes, or an error or a time-out has occurred. In an asynchronous operation, the application does not block and several transfers on a same endpoint can be queued, if the driver allows it. The core task notifies the application when the transfer operation has completed through a callback function.

Figure - Sending and Receiving a Packet

Sending and Receiving a Packet

(1) An application task that wants to receive or send data, interfaces with µC/USB-Device through the USB classes API. The USB classes API interfaces with the core API, which in turn, interfaces with the endpoint layer API.

(2) The endpoint layer API prepares the data depending on the endpoint characteristics.

(3) When the USB device controller is ready, the driver prepares the transmission or the reception.

(4) Once the transfer has completed, the USB device controller generates an interrupt. Depending on the operation (transmission or reception) the USB device controller’s driver ISR invokes the transmit complete or receive complete function from the core.

(5) If the operation is synchronous, the transmit or receive complete function will signal the transfer ready counting semaphore. If the operation is asynchronous, the transmit or receive complete function will put a message in the USB core event queue for deferred processing by the USB core task.

(6) If the operation is synchronous, the endpoint layer will wait on the counting semaphore. The operation repeats steps 2 to 5 until the whole transfer has completed.

(7) The core task waits on events to be put in the core event queue. In asynchronous transfers, the core task will call the endpoint layer until the operation is completed.

(8) In asynchronous mode, after the transfer has completed, the core task will call the application completion callback to notify the end of the I/O operation.

Processing Setup Packets (USB Requests)

USB requests are processed by the core task. Figure - Processing Setup Packets (USB Requests) shows a simplified task diagram of a USB request processing.

Figure - Processing Setup Packets (USB Requests)

Processing USB Requests

(1) USB requests are sent using control transfers. During the setup stage of the control transfer, the USB device controller generates an interrupt to notify the driver that a new setup packet has arrived.

(2) The USB device controller driver ISR notifies the core by pushing the event in the core event queue.

(3) The core task receives the message from the queue, and starts parsing the USB request by calling the request handler.

(4) The request handler analyzes the request type and determines if the request is a standard, vendor or class specific request.

(5) Standard requests are processed by the core layer. Vendor and class specific requests are processed by the class driver, in the class layer.

Processing Bus Events

USB bus events such as reset, resume, connect, disconnect, and suspend are processed in the same way as the USB requests. The core processes the USB bus events to modify and update the current state of the device. The application can be notified of any bus event by registering a callback function via the Bus Event callback structure. Figure - Processing Bus Events shows a simplified diagram of the USB events process.

Figure - Processing Bus Events

Processing Bus Events

(1) The USB device controller will generate an interrupt when a bus state change (reset, suspend, etc.) occurs.

(2) The USB device controller driver ISR notifies the core by pushing the event in the core event queue.

(3) The core task receives the message from the queue, and starts parsing the Bus Event by calling the bus event handler.

(4) The bus event handler analyzes the event type and takes the appropriate action (reset, suspend or resume the device, call the notification callbacks if any, etc.).


Bus Event Callback Structure

This structure allows the application to register callback functions that will be called whenever a bus event happens, allowing the user to implement any application-specific action depending on the bus event. The address of this structure must be passed as a parameter to USBD_DevAdd(). See the Modify USB Application Initialization Code section for more details on the initialization of a device or the Application Callback Functions API reference for more details on these callback functions. The Table - Bus Event Callbacks Execution gives details about when a callback is executed based on the device states detailed by Figure 9-1 in the USB 2.0 Specification.

Table - Bus Event Callbacks Execution
Bus EventDevice State TransitionAssociated Callback
ResetFrom any state to Default.Reset()
SuspendFrom any state to Suspended.Suspend()
ResumeFrom Suspended to previous state.Resume()
Configuration SetFrom Addressed to Configured.CfgSet()
Configuration ClearFrom Configured to Addressed.CfgClr()
Connection of the deviceFrom disconnected to connected.Conn()
Disconnection of the deviceFrom connected to disconnected.Disconn()


Listing - Sample Bus Event Callback Structure shows a sample bus event callback structure.

static  void  App_USBD_EventReset  (CPU_INT08U   dev_nbr);

static  void  App_USBD_EventSuspend(CPU_INT08U   dev_nbr);

static  void  App_USBD_EventResume (CPU_INT08U   dev_nbr);

static  void  App_USBD_EventCfgSet (CPU_INT08U   dev_nbr,
                                    CPU_INT08U   cfg_val);

static  void  App_USBD_EventCfgClr (CPU_INT08U   dev_nbr,
                                    CPU_INT08U   cfg_val);

static  void  App_USBD_EventConn   (CPU_INT08U   dev_nbr);

static  void  App_USBD_EventDisconn(CPU_INT08U   dev_nbr);

static  USBD_BUS_FNCTS  App_USBD_BusFncts = {
    App_USBD_EventReset,
    App_USBD_EventSuspend,
    App_USBD_EventResume,
    App_USBD_EventCfgSet,
    App_USBD_EventCfgClr,
    App_USBD_EventConn,
    App_USBD_EventDisconn
};


Processing Debug Events

µC/USB-Device contains an optional debug and trace feature. Debug events are managed in the core layer using a dedicated task. Figure - Processing USB Debug Events shows how the core manages debug events.

Figure - Processing USB Debug Events

Processing USB Debug Events

(1) The debug and trace module in the core contains a free list of USB debug events. The debug events objects contain useful information such as the endpoint number, interface number or the layer that generates the events.

(2) Multiple µC/USB-Device layers take available debug event objects to trace useful information about different USB related events.

(3) Trace and debug information events are pushed in the debug event list.

(4) The debug task is dormant until a new debug event is available in the debug event list. The debug task will parse the information contained in the debug event object and it will output it in a human readable format using the application specific output trace function USBD_Trace.

(5) The application specific output function outputs the debug trace information.

For more information on the debug and trace module, see the Debug and Trace page.