1# USB DDK Development 2 3## Overview 4 5The USB Driver Development Kit (DDK) is a toolset that helps you develop USB device drivers at the application layer based on the user mode. It provides a series of device access APIs, for example, opening and closing USB interfaces, and performing non-isochronous transfer, isochronous transfer, control transfer, and interrupt transfer over USB pipes. 6 7The USB DDK can be used to develop device drivers for all devices that use the USB protocol to transfer data over a USB bus. For the peripherals that are not supported by standard kernel drivers, you can use the peripheral driver application developed based on the USB DDK to implement unique device capabilities. 8 9### Basic Concepts 10 11Before developing the USB DDK, you must understand the following basic concepts: 12 13- **USB** 14 15 Universal Serial Bus (USB) is a widely used interface technology that connects a computer to various external devices, such as a keyboard, mouse, printer, storage device, and smartphone. The USB is designed to provide a standardized, efficient, and easy-to-use connection mode that replaces the traditional serial and parallel interface communication. 16 17- **DDK** 18 19 DDK is a tool package provided by OpenHarmony for developing drivers for non-standard USB serial port devices based on the peripheral framework. 20 21### Implementation Principles 22 23A non-standard peripheral application obtains the USB device ID by using the peripheral management service, and delivers the ID and the action to the USB driver application through RPC. The USB driver application can obtain or set the device descriptor and initiate a control transfer or interrupt transfer request by calling the USB DDK API. Then, the DDK API uses the HDI service to deliver instructions to the kernel driver, and the kernel driver uses instructions to communicate with the device. 24 25**Figure 1** Principles of invoking the USB DDK 26 27 28 29## Constraints 30 31- The open APIs of USB DDK can be used to develop drivers of non-standard USB peripherals. 32 33- The open APIs of USB DDK can be used only within the lifecycle of **DriverExtensionAbility**. 34 35- To use the open APIs of the USB DDK, you need to declare the matching ACL permissions in **module.json5**, for example, **ohos.permission.ACCESS_DDK_USB**. 36 37## Environment Setup 38 39Before you get started, make necessary preparations by following instructions in [Environment Preparation](environmental-preparation.md). 40 41## How to Develop 42 43### Available APIs 44 45| Name| Description| 46| -------- | -------- | 47| OH_Usb_Init(void) | Initializes the USB DDK.| 48| OH_Usb_Release(void) | Releases the USB DDK.| 49| OH_Usb_GetDeviceDescriptor(uint64_t deviceId, struct UsbDeviceDescriptor *desc) | Obtains the device descriptor of a USB device.| 50| OH_Usb_GetConfigDescriptor(uint64_t deviceId, uint8_t configIndex, struct UsbDdkConfigDescriptor **const config) | Obtains a USB configuration descriptor. To avoid memory leakage, use **OH_Usb_FreeConfigDescriptor()** to release a descriptor after use.| 51| OH_Usb_FreeConfigDescriptor(const struct UsbDdkConfigDescriptor *const config) | Releases a configuration descriptor. To avoid memory leakage, release a descriptor in time after use.| 52| OH_Usb_ClaimInterface(uint64_t deviceId, uint8_t interfaceIndex, uint64_t *interfaceHandle) | Declares a USB interface.| 53| OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle, uint8_t settingIndex) | Activates the alternate setting of a USB interface.| 54| OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle, uint8_t \*settingIndex) | Obtains the alternate setting of a USB interface.| 55| OH_Usb_SendControlReadRequest(uint64_t interfaceHandle, const struct UsbControlRequestSetup \*setup, uint32_t timeout, uint8_t \*data, uint32_t \*dataLen) | Sends a control read transfer request. This API returns the result synchronously.| 56| OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle, const struct UsbControlRequestSetup \*setup, uint32_t, const uint8_t \*data, uint32_t dataLen) | Sends a control write transfer request. This API returns the result synchronously.| 57| OH_Usb_ReleaseInterface(uint64_t interfaceHandle) | Releases a USB interface.| 58| OH_Usb_SendPipeRequest(const struct UsbRequestPipe *pipe, UsbDeviceMemMap *devMmap) | Sends a pipe request. This API returns the result synchronously. It applies to interrupt transfer and bulk transfer.| 59| OH_Usb_CreateDeviceMemMap(uint64_t deviceId, size_t size, UsbDeviceMemMap **devMmap) | Create a buffer. To avoid resource leakage, use **OH_Usb_DestroyDeviceMemMap()** to destroy a buffer after use.| 60| OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap *devMmap) | Destroy a buffer. To avoid resource leakage, destroy a buffer in time after use.| 61| OH_Usb_GetDevices(struct Usb_DeviceArray *devices) | Obtains the USB device ID list. Ensure that the input pointer is valid and the number of devices does not exceed 128. To prevent resource leakage, release the member memory after usage. Besides, make sure that the obtained USB device ID has been filtered by **vid** in the driver configuration information.| 62 63For details about the APIs, see [USB DDK](../../reference/apis-driverdevelopment-kit/_usb_ddk.md). 64 65### How to Develop 66 67To develop a USB driver using the USB DDK, perform the following steps: 68 69**Adding Dynamic Link Libraries** 70 71Add the following libraries to **CMakeLists.txt**. 72```txt 73libusb_ndk.z.so 74``` 75 76**Including Header Files** 77```c++ 78#include <usb/usb_ddk_api.h> 79#include <usb/usb_ddk_types.h> 80``` 81 821. Obtain the device descriptor of a USB device. 83 84 Call **OH_Usb_Init** of **usb_ddk_api.h** to initialize the USB DDK, and call **OH_Usb_GetDeviceDescriptor** to obtain the device descriptor. 85 86 ```c++ 87 // Initialize the USB DDK. 88 OH_Usb_Init(); 89 struct UsbDeviceDescriptor devDesc; 90 uint64_t deviceId = 0; 91 // Obtain the device descriptor. 92 OH_Usb_GetDeviceDescriptor(deviceId, &devDesc); 93 ``` 94 952. Obtain a configuration descriptor, and declare the USB interface. 96 97 Call **OH_Usb_GetConfigDescriptor** of **usb_ddk_api.h** to obtain the configuration descriptor **config**, and call **OH_Usb_ClaimInterface** to declare claiming of the USB interface. 98 99 ```c++ 100 struct UsbDdkConfigDescriptor *config = nullptr; 101 // Obtain the configuration descriptor. 102 OH_Usb_GetConfigDescriptor(deviceId, 1, &config); 103 // Obtain the index of the target USB interface based on the configuration descriptor. 104 uint8_t interfaceIndex = 0; 105 // Declare the USB interface. 106 uint64_t interfaceHandle = 0; 107 OH_Usb_ClaimInterface(deviceId, interfaceIndex, &interfaceHandle); 108 // Release the configuration descriptor. 109 OH_Usb_FreeConfigDescriptor(config); 110 ``` 1113. Obtain the activated alternate setting of a USB interface. 112 113 Call **OH_Usb_GetCurrentInterfaceSetting** of **usb_ddk_api.h** to obtain the alternate setting, and call **OH_Usb_SelectInterfaceSetting** to activate it. 114 115 ```c++ 116 uint8_t settingIndex = 0; 117 // Obtain the alternate setting. 118 OH_Usb_GetCurrentInterfaceSetting(interfaceHandle, &settingIndex); 119 120 // Activate the alternate setting. 121 OH_Usb_SelectInterfaceSetting(interfaceHandle, &settingIndex); 122 ``` 1234. Send control read requests and control write requests. 124 125 Call **OH_Usb_SendControlReadRequest** of **usb_ddk_api.h** to send a control read request, or call **OH_Usb_SendControlWriteRequest** to send a control write request. 126 127 ```c++ 128 // Timeout interval. Set it to 1s. 129 uint32_t timeout = 1000; 130 131 struct UsbControlRequestSetup setupRead; 132 setupRead.bmRequestType = 0x80; 133 setupRead.bRequest = 0x08; 134 setupRead.wValue = 0; 135 setupRead.wIndex = 0; 136 setupRead.wLength = 0x01; 137 uint8_t dataRead[256] = {0}; 138 uint32_t dataReadLen = 256; 139 // Send a control read request. 140 OH_Usb_SendControlReadRequest(interfaceHandle, &setupRead, timeout, dataRead, &dataReadLen); 141 142 struct UsbControlRequestSetup setupWrite; 143 setupWrite.bmRequestType = 0; 144 setupWrite.bRequest = 0x09; 145 setupWrite.wValue = 1; 146 setupWrite.wIndex = 0; 147 setupWrite.wLength = 0; 148 uint8_t dataWrite[256] = {0}; 149 uint32_t dataWriteLen = 256; 150 // Send a control write request. 151 OH_Usb_SendControlWriteRequest(interfaceHandle, &setupWrite, timeout, dataWrite, &dataWriteLen); 152 ``` 153 1545. Create a buffer, and send a request. 155 156 Call **OH_Usb_CreateDeviceMemMap** of **usb_ddk_api.h** to create the buffer **devMmap**, and call **OH_Usb_SendPipeRequest** to send a request. 157 158 ```c++ 159 struct UsbDeviceMemMap *devMmap = nullptr; 160 // Create a buffer for storing data. 161 size_t bufferLen = 10; 162 OH_Usb_CreateDeviceMemMap(deviceId, bufferLen, &devMmap); 163 struct UsbRequestPipe pipe; 164 pipe.interfaceHandle = interfaceHandle; 165 // Obtain the target endpoint based on the configuration descriptor. 166 pipe.endpoint = 128; 167 pipe.timeout = UINT32_MAX; 168 // Send a request. 169 OH_Usb_SendPipeRequest(&pipe, devMmap); 170 ``` 171 1726. Release resources. 173 174 After all requests are processed and before the application exits, call **OH_Usb_DestroyDeviceMemMap** of **usb_ddk_api.h** to destroy the buffer, call **OH_Usb_ReleaseInterface** to release the USB interface, , and call **OH_Usb_Release** to release the USB DDK. 175 176 ```c++ 177 // Destroy the buffer. 178 OH_Usb_DestroyDeviceMemMap(devMmap); 179 // Release the USB interface. 180 OH_Usb_ReleaseInterface(interfaceHandle); 181 // Release the USB DDK. 182 OH_Usb_Release(); 183 ``` 1847. (Optional) Obtain the USB device ID list. 185 186 After the driver is started, call **OH_Usb_GetDevices** to obtain the device ID that matches the VID in the driver configuration for subsequent application development. (VID is the ID of the device vendor and is configured in the driver application to indicate the applicable devices. The queried device IDs need to be filtered by VID.) 187 188 ```c++ 189 OH_Usb_Init(); 190 constexpr size_t MAX_USB_DEVICE_NUM = 128; 191 struct Usb_DeviceArray deviceArray; 192 deviceArray.deviceIds = new uint64_t[MAX_USB_DEVICE_NUM]; 193 // Obtain the USB device list. 194 OH_Usb_GetDevices(&deviceArray); 195 ``` 196