Skip to end of metadata
Go to start of metadata

Vendor Class Loopback Example

This simple example receives data from a host and re-transmits it, hence creating a loopback. It offers two implementations: one that uses the synchronous API, and another one that uses the asynchronous API. Both implementations can be enabled at the same time, thus creating a composite device.

This example will allow you to accomplish the following tasks:

  • Initialize the Vendor class
  • Create a Vendor class instance
  • Add the Vendor class instance to the Full-Speed configuration
  • Add the Vendor class instance to the High-Speed configuration (if available)
  • Set the Microsoft Extended Property to specify the GUID
  • Create a kernel task that implements the loopback (one task for the synchronous implementation and/or one task for the asynchronous implementation)

Location

The example implementation is located in /examples/usb/device/all/ex_usbd_vendor_loopback.c.

To execute it, you will also need some files on the host side. The files can be downloaded from the Micrium web site.

To install the Windows driver for the device (only if you do not use the Microsoft OS Descriptors), use the .inf file from the Windows application files located in micrium_usb_dev_host_app/OS/Windows/Vendor/INF.

To execute the example application, you will also require a custom executable application on the host side. These files are located in micrium_usb_dev_host_app/OS/Windows/Vendor/Visual Studio 2010/exe/x86.

Configuration

There are two #defines available in the file ex_usbd_vendor_loopback.c, which are used to select the synchronous and/or asynchronous implementation:

  • EX_USBD_VENDOR_LOOPBACK_CFG_SYNC_EN
  • EX_USBD_VENDOR_LOOPBACK_CFG_SYNC_EN

They must be set to either DEF_ENABLED to enable the implementation or DEF_DISABLED to disable the implementation. At least one of the #defines should be enabled at any time. Both can be enabled at the same time.

Running the Demo Application

The application used to demonstrate Vendor class communication between the host and the device is called the Echo demo. This demo implements a simple protocol allowing the device to echo the data sent by the host.

There are two varieties of the Echo demo. The Echo Sync application demonstrates the synchronous communication API, and the Echo Async application demonstrates the asynchronous communication API. These are both discussed in the section Communicating using the USB Device Vendor Class.

Figure - Echo Demo illustrates the Echo demo with host and device interactions:

Figure - Echo Demo

(1) The Windows application executes a simple protocol, which consists of sending a header indicating the total payload size, sending the data payload to the device, and receiving the same data payload back from the device. The data payload is split into small chunks of write and read operations of 512 bytes. The write operation is done using a bulk OUT endpoint, and the read uses a bulk IN endpoint.

(2) On the device, the Echo Sync application performs a series of tasks that execute in lockstep with the Windows PC, and the read and write operations performed on the device mirror those performed on the host. So, a read operation on the device implies a bulk OUT endpoint on the host, while a write on the device implies a bulk IN endpoint on the host. Both the device and host wait until the other has performed its task.

(3) The Echo Async application performs the same steps as the Sync task, but using the asynchronous API. The Async task starts the first asynchronous OUT transfer to receive the header. Then, a callback associated with the header reception is called by the device stack. It prepares the next asynchronous OUT transfer to receive the payload. The read payload callback sends the payload back to the host via an asynchronous IN transfer. The write payload callback is called and either prepares the next header reception if the entire payload has been sent to the host, or prepares a next OUT transfer to receive a new chunk of data payload. A side note: this task is also used in case of error during the protocol communication.

When the vendor device is first connected, Windows enumerates the device by retrieving the standard descriptors. Microsoft does not provide any specific driver for the Vendor class, so if you don't use the Microsoft OS descriptors, you must indicate to Windows which driver to load using an INF file (refer to About INF files for more details about INF). The INF file tells Windows to load the WinUSB generic driver (provided by Microsoft). Indicating the INF file to Windows needs to be done only once. Windows will then automatically recognize the vendor device and load the proper driver for any new connection. The process of indicating the INF file may vary according to the Windows operating system version:

  • Windows XP directly opens the “Found New Hardware Wizard”. Follow the different steps of the wizard until the page where you can indicate the path of the INF file.
  • Windows Vista and later won’t open a “Found New Hardware Wizard”. It will just indicate that no driver was found for the vendor device. You have to manually open the wizard. Open the Device Manager, the vendor device connected appears under the category ‘Other Devices’ with a yellow icon. Right-click on your device and choose ‘Update Driver Software...’ to open the wizard. Follow the different steps of the wizard until the page where you can indicate the path of the INF file.

Once the driver is successfully loaded, the Windows host application is ready to be launched. There are two executables:

  • EchoSync.exe for the Windows application with the synchronous communication API of USBDev_API
  • EchoAsync.exe for the Windows application with the asynchronous IN API of USBDev_API

The Windows application interacts with WinUSB driver via USBDev_API, which is a wrapper for the WinUSB driver. USBDev_API is provided by Micrium. Refer to USBDev_API for more details about USBDev_API and the WinUSB driver. The Echo Sync or Async demo will first determine the number of vendor devices connected to the PC. For each detected device, the demo will open a bulk IN and a bulk OUT pipe. Then the demo is ready to send/receive data to/from the device. You will have to enter the maximum number of transfers you want as shown in Figure - Demo Application at Startup.

Figure - Demo Application at Startup
In the example Figure - Demo Application at Startup, the demo handles 10 transfers. Each transfer is sent after the header, following the simple protocol described in Figure - Echo Demo. The first transfer will have a data payload of 1 byte. Then, subsequent transfers will have their size incremented by 1 byte until the last transfer. In our example, the last transfer will have 10 bytes.

Figure - Demo Application Execution (Single Device) shows the execution.

Figure - Demo Application Execution (Single Device)
The demo will prompt you to perform another transfer. Figure - Demo Application Execution (Single Device) shows the example of a single device with one vendor interface. For composite devices, the demo is able to communicate with each vendor interface, and it will open bulk IN and OUT pipes for each one. You will be asked the maximum number of transfers for each interface in the device. Figure - Demo Application Execution (Composite Device) shows an example of a composite device.
Figure - Demo Application Execution (Composite Device)

GUID

A Globally Unique IDentifier (GUID) is a 128-bit value that uniquely identifies a class or other entity. Windows uses GUIDs for identifying two types of devices classes:

  • Device setup class
  • Device interface class

Windows assigns a device setup GUID to devices that are installed in all the same way, and which all use the same class installer and co-installers. Class installers and co-installers are DLLs that provide functions related to the installation of the device.

A device interface GUID provides the mechanism that applications use to communicate with the driver that has been assigned to all devices in a class. Refer to Using GUID for more details about the GUID.

The device setup class GUID is used in WinUSB_single.inf and WinUSB_composite.inf.These INF files define a new device setup class that will be added to the Windows registry under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class when a vendor device is first connected. Listing - New Device Setup Class shows entries in the INF file that define the new device setup class. 

Class = MyDeviceClass ; Name of the device setup class.
ClassGuid = {11111111-2222-3333-4444-555555555555} ; Device setup class GUID
Listing - New Device Setup Class

The INF file allows Windows to register all the information necessary to associate the driver Winusb.sys with the connected vendor device. The Windows Echo application is able to retrieve the attached vendor device thanks to the device interface class GUID. WinUSB_single.inf and WinUSB_composite.inf define the following device interface class GUID: {143f20bd-7bd2-4ca6-9465-8882f2156bd6}. The Echo application includes a header file called usbdev_guid.h. This header file defines the variable shown in  Listing - GUID Global Variable.

GUID USBDev_GUID = {0x143f20bd,0x7bd2,0x4ca6,{0x94,0x65,0x88,0x82,0xf2,0x15,0x6b,0xd6}};
Listing - GUID Global Variable

USBDev_GUID is a structure whose fields represent the device interface class GUID that is defined in WinUSB_single.inf and WinUSB_composite.inf. The USBDev_GUID variable will be passed as a parameter to the function USBDev_Open(). A handle will be returned by USBDev_Open(), and the application uses this handle to access the device.

API

This example uses only one API named Ex_USBD_Vendor_Init(). This function is normally called from a USB device core example.