-[Developing Driver Using Host DDK APIs](#section865734181916)
-[Developing Driver Using Host Raw APIs](#section865734181916)
-[Developing Driver Using Device DDK APIs](#section865734181916)
-[Development Examples](#section263714411191)
-[Developing Driver Using Host DDK APIs](#section18249155619195)
-[Developing Driver Using Host Raw APIs](#section3571192072014)
-[Developing Driver Using Device DDK APIs](#section6356758162015)
## Overview <a name="section175431838101617"></a>
USB host development aims to provide host-related functions, including protocol encapsulation, device management, and driver installation and uninstall.
USB device development aims to provide device-related functions, including device management, configuration management, and I/O management. These functions implement creation, configuration, and data communication of USB devices.
The following figures show the UBS host and device driver models.
**Figure 1** USB host driver model<aname="fig10451455446"></a>
- The USB host Driver Development Kit (DDK) provides driver capability APIs that can be directly called in user mode. The APIs can be classified into the DDK initialization class, interface operation class, and request operation class by function. These APIs can be used to perform DDK initialization, bind/release and open/close an interface, allocate/release a request, and implement isochronous or non-isochronous transfer.
- The USB device DDK provides device management, I/O management, and configuration management APIs, which can be used to create and delete a device, obtain/open an interface, and perform isochronous or non-isochronous transfer.
### Available APIs<a name="section17667171301711"></a>
Table 1 describes the APIs provided by the USB host driver model.
**Table 1** APIs provided by the USB host driver model
<tdclass="cellrowborder"valign="top"width="22.912291229122914%"headers="mcps1.2.4.1.3 "><pid="p201331557185512"><aname="p201331557185512"></a><aname="p201331557185512"></a>Initializes the USB host driver DDK.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p161332570553"><aname="p161332570553"></a><aname="p161332570553"></a>Exits the USB host driver DDK.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p131331557175510"><aname="p131331557175510"></a><aname="p131331557175510"></a>Obtains a USB interface.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1470315695811"><aname="p1470315695811"></a><aname="p1470315695811"></a>Releases a USB interface.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1186597589"><aname="p1186597589"></a><aname="p1186597589"></a>Adds or removes a USB interface.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p15832129135813"><aname="p15832129135813"></a><aname="p15832129135813"></a>Opens a USB interface.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1186597589"><aname="p1186597589"></a><aname="p1186597589"></a>Closes a USB interface.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p15832129135813"><aname="p15832129135813"></a><aname="p15832129135813"></a>Sets a USB interface.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1186597589"><aname="p1186597589"></a><aname="p1186597589"></a>Obtains USB pipe information.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p15832129135813"><aname="p15832129135813"></a><aname="p15832129135813"></a>Clears the state of the pipe with the specified index.</p>
</td>
</tr>
<trid="row71857914585"><tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.1 "><pid="p1318619155811"><aname="p1318619155811"></a><aname="p1318619155811"></a>struct UsbRequest *UsbAllocRequest(const UsbInterfaceHandle *interfaceHandle, int isoPackets, int length);</p>
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1186597589"><aname="p1186597589"></a><aname="p1186597589"></a>Allocates a request object.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p15832129135813"><aname="p15832129135813"></a><aname="p15832129135813"></a>Releases a request object.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1186597589"><aname="p1186597589"></a><aname="p1186597589"></a>Sends a request asynchronously.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p15832129135813"><aname="p15832129135813"></a><aname="p15832129135813"></a>Fills in a request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1186597589"><aname="p1186597589"></a><aname="p1186597589"></a>Cancels an asynchronous request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p15832129135813"><aname="p15832129135813"></a><aname="p15832129135813"></a>Sends a synchronous request.</p>
<tdclass="cellrowborder"valign="top"width="22.912291229122914%"headers="mcps1.2.4.1.3 "><pid="p752531095814"><aname="p752531095814"></a><aname="p752531095814"></a>Initializes the USB raw APIs.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1929141611198"><aname="p1929141611198"></a><aname="p1929141611198"></a>Exits the USB raw APIs.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p169531741912"><aname="p169531741912"></a><aname="p169531741912"></a>Opens a USB device.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p4331131817195"><aname="p4331131817195"></a><aname="p4331131817195"></a>Closes a USB device.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Performs a control transfer synchronously.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Performs a bulk transfer synchronously.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Performs an interrupt transfer synchronously.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Obtains the configuration descriptor of a device.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Releases the memory space of a configuration descriptor.</p>
</td>
</tr>
<trid="row12422102092613"><tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.1 "><pid="p194231720102610"><aname="p194231720102610"></a><aname="p194231720102610"></a>int UsbRawGetConfiguration(const UsbRawHandle *devHandle, int *config);</p>
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Obtains the configuration in use.</p>
</td>
</tr>
<trid="row1393181951920"><tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.1 "><pid="p79410191191"><aname="p79410191191"></a><aname="p79410191191"></a>int UsbRawSetConfiguration(const UsbRawHandle *devHandle, int config);</p>
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Sets the configuration in use.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Obtains the device pointer based on the device handle.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Obtains the device descriptor of the specified USB device.</p>
</td>
</tr>
<trid="row1393181951920"><tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.1 "><pid="p79410191191"><aname="p79410191191"></a><aname="p79410191191"></a>int UsbRawClaimInterface(const UsbRawHandle *devHandle, int interfaceNumber);</p>
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Declares the interface on the specified device handle.</p>
</td>
</tr>
<trid="row12422102092613"><tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.1 "><pid="p194231720102610"><aname="p194231720102610"></a><aname="p194231720102610"></a>int UsbRawReleaseInterface(const UsbRawHandle *devHandle, int interfaceNumber);</p>
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Releases the previously declared interface.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Resets a device.</p>
</td>
</tr>
<trid="row12422102092613"><tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.1 "><pid="p194231720102610"><aname="p194231720102610"></a><aname="p194231720102610"></a>struct UsbRawRequest *UsbRawAllocRequest(const UsbRawHandle *devHandle, int isoPackets, int length);</p>
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Allocates a transfer request with the specified number of sync packet descriptors.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Releases the previously allocated transfer request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Fills in the bulk transfer request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Fills in the control setup packet.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Fills in the control transfer request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Fills in the interrupt transfer request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Fills in the isochronous transfer request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Submits a transfer request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Cancels a transfer request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Handles a transfer request event.</p>
</td>
</tr>
</tbody>
</table>
Table 2 describes the APIs provided by the USB device driver model.
**Table 2** APIs provided by the USB device driver model
<tdclass="cellrowborder"valign="top"width="22.912291229122914%"headers="mcps1.2.4.1.3 "><pid="p213285715558"><aname="p213285715558"></a><aname="p213285715558"></a>Creates a USB device.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p113315745519"><aname="p113315745519"></a><aname="p113315745519"></a> Deletes a USB device.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1413365765514"><aname="p1413365765514"></a><aname="p1413365765514"></a>Obtains a USB device.</p>
<tdclass="cellrowborder"valign="top"width="22.912291229122914%"headers="mcps1.2.4.1.3 "><pid="p201331557185512"><aname="p201331557185512"></a><aname="p201331557185512"></a>Starts to receive events.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p131331557175510"><aname="p131331557175510"></a><aname="p131331557175510"></a>Opens an interface.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1470315695811"><aname="p1470315695811"></a><aname="p1470315695811"></a>Closes an interface.</p>
<tdclass="cellrowborder"valign="top"width="22.912291229122914%"headers="mcps1.2.4.1.3 "><pid="p752531095814"><aname="p752531095814"></a><aname="p752531095814"></a>Applies for a control transfer request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1929141611198"><aname="p1929141611198"></a><aname="p1929141611198"></a>Applies for a data request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p169531741912"><aname="p169531741912"></a><aname="p169531741912"></a>Releases a request.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p17948193197"><aname="p17948193197"></a><aname="p17948193197"></a>Sends a request synchronously.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p342315202267"><aname="p342315202267"></a><aname="p342315202267"></a>Cancels a request.</p>
</td>
</tr>
</tbody>
</table>
## Development Guidelines<a name="section65745222184"></a>
The USB driver is developed based on the Hardware Driver Foundation (HDF), platform, and Operating System Abstraction Layer (OSAL) APIs. A unified driver model is provided for USB devices, irrespective of the operating system and chip architecture. This document uses a serial port as an example to describe how to develop drivers for the USB host and USB device.
### How to Develop<a name="section865734181916"></a>
### Developing Driver Using Host DDK APIs<a name="section18249155619195"></a>
1. Configure the driver mapping table.
2. Initialize the USB host DDK.
3. Obtain a **UsbInterface** object.
4. Open the **UsbInterface** object to obtain the **UsbInterfaceHandle** object.
5. Obtain pipe information of the specified **pipeIndex** based on the **UsbInterfaceHandle** object.
6. Allocate an I/O request for the **UsbInterfaceHandle** object.
7. Fill in the I/O request based on the input parameters.
8. Submit the I/O request in synchronous or asynchronous mode.
### Developing Driver Using Host Raw APIs<a name="section18249155619195"></a>
1. Configure the driver mapping table.
2. Initialize the host raw data, open the USB device, obtain the descriptor, and then obtain interface and endpoint information based on the descriptor.
3. Allocate a request and fill in the request based on the transfer type.
4. Submit the I/O request object in synchronous or asynchronous mode.
### Developing Driver Using Device DDK APIs<a name="section18249155619195"></a>
1. Construct a descriptor.
2. Instantiate a USB device using the descriptor constructed.
3. Call **UsbFnDeviceGetInterface** to obtain an interface, call **UsbFnInterfaceGetPipeInfo** to obtain pipe information based on the interface, call **UsbFnInterfaceOpen** to open the interface to obtain the handle, and call **UsbFnRequestAlloc** to obtain the request based on the handle and pipe ID.
4. Call **UsbFnInterfaceStartRecvEvent** to receive events such as Enable and Setup, and respond to the events in **UsbFnEventCallback**.
5. Send and receive data in synchronous or asynchronous mode.
## Development Examples<a name="section263714411191"></a>
The following example helps you better understand the development of the USB serial port driver.
### Developing Driver Using Host DDK APIs<a name="section18249155619195"></a>
```
root {
module = "usb_pnp_device";
usb_pnp_config {
match_attr = "usb_pnp_match";
usb_pnp_device_id = "UsbPnpDeviceId";
UsbPnpDeviceId {
idTableList = [
"host_acm_table"
];
host_acm_table {
// Driver module name, which must be the same as the value of moduleName in the driver entry structure.
moduleName = "usbhost_acm";
// Service name of the driver, which must be unique.
serviceName = "usbhost_acm_pnp_service";
// Keyword for matching private driver data.
deviceMatchAttr = "usbhost_acm_pnp_matchAttr";
// Data length starting from this field, in bytes.
length = 21;
// USB driver matching rule: vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber.
matchFlag = 0x0303;
// Vendor ID.
vendorId = 0x12D1;
// Product ID.
productId = 0x5000;
// The least significant 16 bits of the device sequence number.
bcdDeviceLow = 0x0000;
// The most significant 16 bits of the device sequence number.
bcdDeviceHigh = 0x0000;
// Device class code allocated by the USB.
deviceClass = 0;
// Child class code allocated by the USB.
deviceSubClass = 0;
// Device protocol code allocated by the USB.
deviceProtocol = 0;
// Interface type. You can enter multiple types as needed.
interfaceClass = [0];
// Interface subtype. You can enter multiple subtypes as needed.
interfaceSubClass = [2, 0];
// Protocol that the interface complies with. You can enter multiple protocols as needed.
interfaceProtocol = [1, 2];
// Interface numer. You can enter multiple interface numbers as needed.
HDF_LOGE("%{public}s: interface%{public}d is null", __func__, acm->interfaceIndex[i]);
goto error;
}
}
acm->ctrIface = GetUsbInterfaceById((const struct AcmDevice *)acm, USB_CTRL_INTERFACE_ID); // Obtain the UsbInterface object corresponding to the control interface.
acm->dataInPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_IN); // Obtain pipe information of dataInPipe.
if (acm->dataInPipe == NULL) {
HDF_LOGE("dataInPipe is NULL");
goto error;
}
acm->dataOutPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_OUT); // Obtain pipe information of dataOutPipe.
if (acm->dataOutPipe == NULL) {
HDF_LOGE("dataOutPipe is NULL");
goto error;
}
acm->ctrPipe = EnumePipe(acm, acm->ctrIface->info.interfaceIndex, USB_PIPE_TYPE_CONTROL, USB_PIPE_DIRECTION_OUT); // Obtain pipe information of the control pipe.
if (acm->ctrPipe == NULL) {
HDF_LOGE("ctrPipe is NULL");
goto error;
}
acm->intPipe = GetPipe(acm, USB_PIPE_TYPE_INTERRUPT, USB_PIPE_DIRECTION_IN); // Obtain pipe information of the interrupt pipe.
snd->request = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataOutPipe->interfaceId), 0, acm->writeSize); // Allocate the I/O request object to be sent.
.moduleName = "usbhost_acm_rawapi", // Driver module name, which must be the same as that configured in the .hcs file.
.Bind = UsbSerialDriverBind,
.Init = UsbSerialDriverInit,
.Release = UsbSerialDriverRelease,
};
HDF_INIT(g_usbSerialRawDriverEntry);
```
### Developing Driver Using Device DDK APIs<a name="section6356758162015"></a>
The core code of the USB Abstract Control Model (ACM) device is available in **drivers\peripheral\usb\gadget\function\acm\cdcacm.c**. The following is an example.