1# USB 2 3## 概述 4 5### 功能简介 6 7USB(Universal Serial Bus)通用串行总线,包含了主机端(Host)和设备端(Device)。主机端负责USB总线中的数据传输及端口管理,设备端则可以连接各种外设,所以USB驱动开发又分为主机端驱动开发和设备端驱动开发。 8 9OpenHarmony系统USB模块支持USB业务的开发,提供USB相关的功能,提供用户态第三方功能驱动的USB设备数据读写接口,以及提供创建和删除USB设备,接口的事件获取、打开和关闭等,管道同步异步读写通信,设置USB自定义属性等。 10 11USB DDK(USB DriverDevelop Kit)是HDF驱动框架为开发者提供的USB驱动程序开发套件,包括USB Host DDK及USB Device DDK两部分,支持基于用户态开发USB设备驱动的同时,还提供了丰富的USB驱动开发能力,让广大开发者能精准且高效的开发USB驱动程序。 12 13### 基本概念 14 15- 管道 16 17 管道(Pipe)是主机端和设备端点之间数据传输的模型。任何USB设备一旦上电就存在一个信息管道,即默认的控制管道,USB主机通过该管道来获取设备的描述、配置、状态,并对设备进行配置;管道和端点关联,两者有相同的属性,如支持的传输类型、最大包长度、传输方向等。 18 19- 端点 20 21 端点(Endpoint)是USB设备中的可以进行数据收发的最小单元,支持单向或者双向的数据传输。一个USB设备可以包括若干个端点,不同的端点以端点编号和方向区分。不同端点可以支持不同的传输类型、访问间隔以及最大数据包大小。除端点0外,所有的端点只支持一个方向的数据传输。端点0是一个特殊的端点,它支持双向的控制传输。 22 23- 接口 24 25 应用软件通过和设备之间的数据交换来完成设备的控制和数据传输。由于同一管道只支持一种类型的数据传输,因此这个过程中通常需要多个管道来完成数据交换。像这样用在一起来对设备进行控制的若干管道的集合称为接口。 26 27- 描述符 28 29 描述符(Descriptor)是用于描述设备属性(Attributes)的数据结构,第一个字节表示描述符的大小(字节数),第二个字节表示描述符的类型(Type)。 30 31### 运作机制 32 33#### USB Host DDK 34 35USB Host DDK为开发者提供了主机端USB驱动开发能力,按照功能分为三大类,分别是DDK初始化类、interface对象操作类及request对象操作类。 36 37 **图1** USB Host驱动模型图 38 39 ![image](figures/USB-Host驱动模型图.png "USB-Host驱动模型图") 40 41- USB Interface Pool负责USB Interface管理。提供USB Interface接口对象的申请和回收,USB Interface接口对象用来记录设备端口信息以及资源。USB Interface Pool按照USB Port对USB Interface进行分类管理。同时,此模块还提供了USB DDK API,方便开发者进行USB数据读写操作。 42 43- USB Protocol Layer提供USB协议封装,根据USB协议对设备IO/控制命令进行翻译和解析”,同时负责设备描述符的管理,根据USB Device上报的枚举信息,匹配对应的描述符;构建对应的USB Interface接口对象,并将其加入到USB Interface Pool中管理。 44 45- Device IO Manager负责USB IO请求管理,提供了同步IO和异步IO管理机制,对于异步IO,IO Manager负责将该请求记录下来,然后通过Raw API Library提供的接口依次处理待发送的IO请求;当收到USB控制器应答的处理结果后,IO接收线程负责解析并上报处理结果给上层调用者。 46 47- Raw API Library抽象了底层OS能力,定义了统一的OS能力接口,对外提供了USB RAW API,方便开发者实现更加复杂的驱动功能。 48 49- OS Adapter用于封装与平台(Linux和LiteOS)相关的操作,根据不同平台配置编译对应平台的封装接口。在Linux平台上,访问USB FS的操作,全部都封装在这个模块中;而在LiteOS平台上,基于FreeBSD USB框架的设备访问操作,也都全部封装在这个模块中。 50 51- PNP Notify用于动态监测USB状态变化,当有新设备添加/移除时,变化设备信息。同时将所有USB设备信息都通过KHDF上报给UHDF侧的PNP Notify Manager模块来完成加载/卸载第三方功能驱动。 52 53#### USB Device DDK 54 55USB Device DDK向开发者提供了设备端USB驱动开发能力。例如,USB端口动态注册和去注册能力,开发者可以基于能力实现USB端口的动态添加和组合;动态实例化能力,支持根据动态下发设备、配置、接口及端点描述符创建设备实例及传输通道;用户态的数据发送及接收能力,支持用户态下发送及接收数据;复合设备能力,支持一个物理设备上多个逻辑设备,实现多个逻辑设备间隔离,并支持不同逻辑设备同时被不同的应用进程访问。 56 57 **图2** USB Device驱动模型图 58 59 ![image](figures/USB-Device驱动模型图.png "USB-Device驱动模型图") 60 61- SDK IF负责将USB设备按照设备、接口、管道进行逻辑划分,对配置管理、设备管理、IO管理进行封装。此模块还向开发者提供了设备创建、获取接口、接收Event事件、收发数据等设备测驱动开发的能力接口。 62 63- Configuration Manager负责解析HCS文件描述的USB描述符信息,得到的USB描述符信息用于设备创建,同时模块还提供了自定义属性的读取、创建、删除、修改等操作。 64 65- Device Manager负责根据配置模块解析USB描述符,并根据USB描述符创建设备。同时还负责获取设备、删除设备、获取设备状态,获取设备上面接口信息。 66 67- IO Manager负责数据的读写,包括Events事件、数据读写完成后事件的接收,支持同步和异步模式数据读写。 68 69- Adapter IF主要是对复合设备配置驱动及通用功能驱动设备节点操作进行封装,为上层提供统一的设备管理接口。 70 71- Adapter该模块由复合设备配置驱动及通用功能驱动提供。 72 73## 开发指导 74 75由于内核态开发USB驱动较复杂,需要开发者对USB协议要有较深的了解才能很好的使用,对开发者的要求相对较高。USB DDK的引入是为了让开发者能在用户态更方便的开发USB驱动。 76 77### 场景介绍 78 79USB Host DDK为开发者提供了普通模式和专家模式,普通模式下,开发者可通过USB DDK API直接完成相关USB数据读写操作,不需要过多关注底层的传输细节。专家模式下,开发者通过USB RAW API直接访问OS平台中USB通道的接口,自定义实现更加复杂的功能。USB Device DDk为开发者提供了管理USB设备、接口定义及USB数据请求等功能。下文将介绍相关API。 80 81### 接口说明 82 83USB主机端驱动程序开发相关接口(普通模式)如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/host/usb_ddk_interface.h)。 84 85 **表1** USB主机端驱动程序开发相关接口(普通模式) 86 87| 接口名称 | 功能描述 | 88| -------- | -------- | 89| int32_t UsbInitHostSdk(struct UsbSession \*\*session); | USB主机端驱动开发工具包初始化 | 90| const struct UsbInterface \*UsbClaimInterface(const<br/>struct UsbSession \*session, uint8_t busNum, uint8_t<br/>usbAddr, uint8_t interfaceIndex); | 获取USB接口对象 | 91| UsbInterfaceHandle \*UsbOpenInterface(const struct<br/>UsbInterface \*interfaceObj); | 打开USB对象接口 | 92| int32_t UsbGetPipeInfo(const UsbInterfaceHandle<br/>\*interfaceHandle, uint8_t settingIndex, uint8_t pipeId,<br/>struct UsbPipeInfo \*pipeInfo); | 获取指定可选设置的管道信息 | 93| struct UsbRequest \*UsbAllocRequest(const<br/>UsbInterfaceHandle \*interfaceHandle, int32_t isoPackets<br/>, int32_t length); | 分配请求对象 | 94| int32_t UsbFillRequest(const struct UsbRequest<br/>\*request, const UsbInterfaceHandle \*interfaceHandle,<br/>const struct UsbRequestParams \*params); | 填充请求 | 95| int32_t UsbSubmitRequestSync(const struct UsbRequest<br/>\*request); | 发送同步请求 | 96 97USB主机端驱动程序开发相关接口(专家模式)如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/host/usb_raw_api.h)。 98 99 **表2** USB主机端驱动程序开发相关接口(专家模式) 100 101| 接口名称 | 功能描述 | 102| -------- | -------- | 103| int32_t UsbRawInit(struct UsbSession \*\*session); | USB驱动开发工具包专家模式初始化 | 104| UsbRawHandle \*UsbRawOpenDevice(const struct<br/>UsbSession \*session, uint8_t busNum, uint8_t<br/>usbAddr); | 打开USB设备对象 | 105| int32_t UsbRawSendControlRequest(const struct<br/>UsbRawRequest \*request, const UsbRawHandle<br/>\*devHandle, const struct UsbControlRequestData<br/>\*requestData); | 执行同步控制传输 | 106| int32_t UsbRawSendBulkRequest(const struct<br/>UsbRawRequest \*request, const UsbRawHandle<br/>\*devHandle, const struct UsbRequestData<br/>\*requestData); | 执行同步批量传输 | 107| int32_t UsbRawSendInterruptRequest(const struct<br/>UsbRawRequest \*request, const UsbRawHandle<br/>\*devHandle, const struct UsbRequestData<br/>\*requestData); | 执行同步中断传输 | 108| int32_t UsbRawGetConfigDescriptor(const UsbRawDevice<br/>\*rawDev, uint8_t configIndex, struct<br/>UsbRawConfigDescriptor \*\*config); | 获取给定设备指定ID的设备配置描述符 | 109| int32_t UsbRawFillInterruptRequest(const struct UsbRawRequest<br/>\*request, const UsbRawHandle \*devHandle, const struct<br/>UsbRawFillRequestData \*fillData); | 填充中断传输请求所需信息 | 110| int32_t UsbRawFillIsoRequest(const struct UsbRawRequest<br/>\*request, const UsbRawHandle \*devHandle, const struct<br/>UsbRawFillRequestData \*fillData); | 填充同步传输(Isochronous Transfers)请求所需信息 | 111| int32_t UsbRawSubmitRequest(const struct UsbRawRequest<br/>\*request); | 提交一个传输请求 | 112| int32_t UsbRawCancelRequest(const struct UsbRawRequest<br/>\*request); | 取消一个传输请求 | 113| int32_t UsbRawHandleRequests(const UsbRawHandle<br/>\*devHandle); | 传输请求事件完成处理 | 114 115USB设备端用于管理USB设备的相关接口如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/device/usbfn_device.h)。 116 117 **表3** USB设备端用于管理USB设备的相关接口 118 119| 接口名称 | 功能描述 | 120| -------- | -------- | 121| const struct UsbFnDevice \*UsbFnCreateDevice(const<br/>char \*udcName, const struct UsbFnDescriptorData<br/>\*descriptor); | 创建USB设备 | 122| int32_t UsbFnRemoveDevice(struct UsbFnDevice<br/>\*fnDevice); | 删除USB设备 | 123| const struct UsbFnDevice \*UsbFnGetDevice(const char<br/>\*udcName); | 获取USB设备 | 124 125USB设备端用于USB接口定义的相关接口如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/device/usbfn_interface.h)。 126 127 **表4** USB设备端用于USB接口定义的相关接口 128 129| 接口名称 | 功能描述 | 130| -------- | -------- | 131| int32_t UsbFnStartRecvInterfaceEvent(struct<br/>UsbFnInterface \*interface, uint32_t eventMask,<br/>UsbFnEventCallback callback, void \*context); | 开始接受Event事件 | 132| int32_t UsbFnStopRecvInterfaceEvent(struct<br/>UsbFnInterface \*interface); | 停止接受Event事件 | 133| UsbFnInterfaceHandle UsbFnOpenInterface(struct UsbFnInterface \*interface); | 打开一个接口 | 134| int32_t UsbFnCloseInterface(UsbFnInterfaceHandle handle); | 关闭一个接口 | 135| int32_t UsbFnGetInterfacePipeInfo(struct UsbFnInterface<br/>\*interface, uint8_t pipeId, struct UsbFnPipeInfo \*info); | 获取管道信息 | 136| int32_t UsbFnSetInterfaceProp(const struct UsbFnInterface<br/>\*interface, const char \*name, const char \*value); | 设置自定义属性 | 137 138USB设备端用于管理USB数据请求的相关接口如下,具体接口定义[见源码](https://gitee.com/openharmony/drivers_peripheral/blob/master/usb/interfaces/ddk/device/usbfn_request.h)。 139 140 **表5** USB设备端用于管理USB数据请求的相关接口 141 142| 接口名称 | 功能描述 | 143| -------- | -------- | 144| struct UsbFnRequest<br/>\*UsbFnAllocCtrlRequest(UsbFnInterfaceHandle handle,<br/>uint32_t len); | 申请一个控制请求 | 145| struct UsbFnRequest \*UsbFnAllocRequest(UsbFnInterfaceHandle handle,<br/>uint8_t pipe, uint32_t len); | 申请一个数据请求 | 146| int32_t UsbFnFreeRequest(struct UsbFnRequest \*req); | 释放一个请求 | 147| int32_t UsbFnSubmitRequestAsync(struct UsbFnRequest<br/>\*req); | 发送异步请求 | 148| int32_t UsbFnSubmitRequestSync(struct UsbFnRequest<br/>\*req, uint32_t timeout); | 发送同步请求 | 149| int32_t UsbFnCancelRequest(struct UsbFnRequest \*req); | 取消请求 | 150 151 152### 开发步骤 153 154USB驱动基于HDF框架、Platform和OSAL基础接口进行开发,不区分操作系统和芯片平台,为不同USB器件提供统一的驱动模型。此处以串口为例,分别介绍USB Host和USB Device驱动开发的详细过程。 155 156#### Host DDK API驱动开发 157 1581. 在设备私有数据HCS中配置,完成主机端驱动总体信息的配置,具体如下: 159 160 ```cpp 161 root { 162 module = "usb_pnp_device"; 163 usb_pnp_config { 164 match_attr = "usb_pnp_match"; 165 usb_pnp_device_id = "UsbPnpDeviceId"; 166 UsbPnpDeviceId { 167 idTableList = [ 168 "host_acm_table" 169 ]; 170 host_acm_table { 171 // 驱动模块名,该字段的值必须和驱动入口结构的moduleName一致 172 moduleName = "usbhost_acm"; 173 // 驱动对外发布服务的名称,必须唯一 174 serviceName = "usbhost_acm_pnp_service"; 175 // 驱动私有数据匹配关键字 176 deviceMatchAttr = "usbhost_acm_pnp_matchAttr"; 177 // 从该字段开始(包含该字段)之后数据长度,以byte为单位 178 length = 21; 179 // USB驱动匹配规则vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber 180 matchFlag = 0x0303; 181 // 厂商编号 182 vendorId = 0x12D1; 183 // 产品编号 184 productId = 0x5000; 185 // 设备出厂编号,低16位 186 bcdDeviceLow = 0x0000; 187 // 设备出厂编号,高16位 188 bcdDeviceHigh = 0x0000; 189 // USB分配的设备类代码 190 deviceClass = 0; 191 // USB分配的子类代码 192 deviceSubClass = 0; 193 // USB分配的设备协议代码 194 deviceProtocol = 0; 195 // 接口类型,根据实际需要可填写多个 196 interfaceClass = [0]; 197 // 接口子类型,根据实际需要可填写多个 198 interfaceSubClass = [2, 0]; 199 // 接口所遵循的协议,根据实际需要可填写多个 200 interfaceProtocol = [1, 2]; 201 // 接口的编号,根据实际需要可填写多个 202 interfaceNumber = [2, 3]; 203 } 204 } 205 } 206 } 207 ``` 208 2092. USB主机端驱动开发工具包初始化。 210 211 ```cpp 212 int32_t UsbInitHostSdk(struct UsbSession **session); 213 ``` 214 2153. 步骤2初始化完后获取UsbInterface对象。 216 217 ```cpp 218 const struct UsbInterface *UsbClaimInterface(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr, uint8_t interfaceIndex); 219 ``` 220 2214. 打开步骤3获取到的UsbInterface接口对象,获取相应接口的UsbInterfaceHandle对象。 222 223 ```cpp 224 UsbInterfaceHandle *UsbOpenInterface(const struct UsbInterface *interfaceObj); 225 ``` 226 2275. 根据步骤4获取到的UsbInterfaceHandle对象,获取指定索引为pipeIndex的pipeInfo信息。 228 229 ```cpp 230 int32_t UsbGetPipeInfo(const UsbInterfaceHandle *interfaceHandle, uint8_t settingIndex, uint8_t pipeId, struct UsbPipeInfo *pipeInfo); 231 ``` 232 2336. 为步骤4获取到的UsbInterfaceHandle预先分配待发送的IO Request对象。 234 235 ```cpp 236 struct UsbRequest *UsbAllocRequest(const UsbInterfaceHandle *interfaceHandle, int32_t isoPackets, int32_t length); 237 ``` 238 2397. 根据输入参数params填充步骤6预先分配的IO Request。 240 241 ```cpp 242 int32_t UsbFillRequest(const struct UsbRequest *request, const UsbInterfaceHandle *interfaceHandle, const struct UsbRequestParams *params); 243 ``` 244 2458. 提交IO Request对象,可以选择同步或异步两种模式。 246 247 ```cpp 248 int32_t UsbSubmitRequestSync(const struct UsbRequest *request); //发送同步IO请求 249 int32_t UsbSubmitRequestAsync(const struct UsbRequest *request); //发送异步IO请求 250 ``` 251 252#### Host RAW API驱动开发 253 2541. 同Host DDK API的步骤1一样,在设备私有数据HCS中配置。 255 2562. 初始化Host RAW,并打开USB设备,然后获取描述符,通过描述符获取接口、端点信息。 257 258 ```cpp 259 int32_t UsbRawInit(struct UsbSession **session); 260 ``` 261 2623. 待步骤2完成后打开USB设备。 263 264 ```cpp 265 UsbRawHandle *UsbRawOpenDevice(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr); 266 ``` 267 2684. 待步骤3完成后获取描述符,通过描述符获取接口、端点信息。 269 270 ```cpp 271 int32_t UsbRawGetConfigDescriptor(const UsbRawDevice *rawDev, uint8_t configIndex, struct UsbRawConfigDescriptor **config); 272 ``` 273 2745. 分配Request,并根据传输类型使用相应接口对Request进行填充。 275 276 ```cpp 277 int32_t UsbRawFillBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData); // 填充用于批量传输的请求 278 int32_t UsbRawFillControlSetup(const unsigned char *setup, const struct UsbControlRequestData *requestData); 279 int32_t UsbRawFillControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData); // 填充用于控制传输的请求 280 int32_t UsbRawFillInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData); // 填充用于中断传输的请求 281 int32_t UsbRawFillIsoRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData); // 填充用于同步传输的请求 282 ``` 283 2846. 提交IO Request对象,可以选择同步或异步两种模式。 285 286 ```cpp 287 int32_t UsbRawSendControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbControlRequestData *requestData); //发送同步USB控制传输请求 288 int32_t UsbRawSendBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData); //发送同步USB批量传输请求 289 int32_t UsbRawSendInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData); //发送同步执行USB中断传输请求 290 int32_t UsbRawSubmitRequest(const struct UsbRawRequest *request); //提交异步IO请求 291 ``` 292 293#### Device DDK API驱动开发 294 2951. 在设备功能代码中构造描述符。 296 297 ```cpp 298 static struct UsbFnFunction g_acmFunction = { // 功能描述符 299 .enable = true, 300 .funcName = "f_generic.a", 301 .strings = g_acmStrings, 302 .fsDescriptors = g_acmFsFunction, 303 .hsDescriptors = g_acmHsFunction, 304 .ssDescriptors = g_acmSsFunction, 305 .sspDescriptors = NULL, 306 }; 307 struct UsbFnFunction *g_functions[] = { 308 #ifdef CDC_ECM 309 &g_ecmFunction, 310 #endif 311 #ifdef CDC_ACM 312 &g_acmFunction, 313 #endif 314 NULL 315 }; 316 static struct UsbFnConfiguration g_masterConfig = { // 配置描述符 317 .configurationValue = 1, 318 .iConfiguration = USB_FUNC_CONFIG_IDX, 319 .attributes = USB_CFG_BUS_POWERED, 320 .maxPower = POWER, 321 .functions = g_functions, 322 }; 323 static struct UsbFnConfiguration *g_configs[] = { 324 &g_masterConfig, 325 NULL, 326 }; 327 static struct UsbDeviceDescriptor g_cdcMasterDeviceDesc = { // 设备描述符 328 .bLength = sizeof(g_cdcMasterDeviceDesc), 329 .bDescriptorType = USB_DDK_DT_DEVICE, 330 .bcdUSB = CpuToLe16(BCD_USB), 331 .bDeviceClass = 0, 332 .bDeviceSubClass = 0, 333 .bDeviceProtocol = 0, 334 .bMaxPacketSize0 = USB_MAX_PACKET_SIZE, 335 .idVendor = CpuToLe16(DEVICE_VENDOR_ID), 336 .idProduct = CpuToLe16(DEVICE_PRODUCT_ID), 337 .bcdDevice = CpuToLe16(DEVICE_VERSION), 338 .iManufacturer = USB_FUNC_MANUFACTURER_IDX, 339 .iProduct = USB_FUNC_PRODUCT_IDX, 340 .iSerialNumber = USB_FUNC_SERIAL_IDX, 341 .bNumConfigurations = 1, 342 }; 343 static struct UsbFnDeviceDesc g_masterFuncDevice = { // 描述符入口 344 .deviceDesc = &g_cdcMasterDeviceDesc, 345 .deviceStrings = g_devStrings, 346 .configs = g_configs, 347 }; 348 ``` 349 3502. 创建设备。描述符构造完成后,使用UsbFnDeviceCreate函数创建一个USB设备,并传入UDC控制器和UsbFnDescriptorData结构体。 351 352 ```cpp 353 if (useHcs == 0) { // 使用代码编写的描述符 354 descData.type = USBFN_DESC_DATA_TYPE_DESC; 355 descData.descriptor = &g_acmFuncDevice; 356 } else { // 使用hcs编写的描述符 357 descData.type = USBFN_DESC_DATA_TYPE_PROP; 358 descData.property = acm->device->property; 359 } 360 // 创建设备 361 fnDev = (struct UsbFnDevice *) UsbFnCreateDevice(acm->udcName, &descData); 362 ``` 363 3643. 设备创建后,使用UsbFnGetInterface函数获取UsbInterface接口对象,并通过UsbFnGetInterfacePipeInfo函数获取USB管道信息。 365 366 ```cpp 367 // 获取接口 368 fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i); 369 // 获取Pipe信息 370 UsbFnGetInterfacePipeInfo(fnIface, i, &pipeInfo); 371 // 获取Handle 372 handle = UsbFnOpenInterface(fnIface); 373 // 获取控制(EP0)Request 374 req = UsbFnAllocCtrlRequest(acm->ctrlIface.handle, 375 sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); 376 // 获取Request 377 req = UsbFnAllocCtrlRequest(acm->ctrlIface.handle, 378 sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); 379 ``` 380 3814. 通过UsbFnStartRecvInterfaceEvent函数接收Event事件,并通过UsbFnEventCallback回调函数对Event事件做出响应。 382 383 ```cpp 384 // 开始接收Event事件 385 ret = UsbFnStartRecvInterfaceEvent(acm->ctrlIface.fn, 0xff, UsbAcmEventCallback, acm); 386 // Event处理回调函数 387 static void UsbAcmEventCallback(struct UsbFnEvent *event) 388 { 389 struct UsbAcmDevice *acm = NULL; 390 if (event == NULL || event->context == NULL) { 391 HDF_LOGE("%s: event is null", __func__); 392 return; 393 } 394 395 acm = (struct UsbAcmDevice *)event->context; 396 switch (event->type) { 397 case USBFN_STATE_BIND: 398 HDF_LOGI("%s: receive bind event", __func__); 399 break; 400 case USBFN_STATE_UNBIND: 401 HDF_LOGI("%s: receive unbind event", __func__); 402 break; 403 case USBFN_STATE_ENABLE: 404 HDF_LOGI("%s: receive enable event", __func__); 405 AcmEnable(acm); 406 break; 407 case USBFN_STATE_DISABLE: 408 HDF_LOGI("%s: receive disable event", __func__); 409 AcmDisable(acm); 410 acm->enableEvtCnt = 0; 411 break; 412 case USBFN_STATE_SETUP: 413 HDF_LOGI("%s: receive setup event", __func__); 414 if (event->setup != NULL) { 415 AcmSetup(acm, event->setup); 416 } 417 break; 418 case USBFN_STATE_SUSPEND: 419 HDF_LOGI("%s: receive suspend event", __func__); 420 AcmSuspend(acm); 421 break; 422 case USBFN_STATE_RESUME: 423 HDF_LOGI("%s: receive resume event", __func__); 424 AcmResume(acm); 425 break; 426 default: 427 break; 428 } 429 } 430 ``` 431 4325. 收发数据,可以选择同步异步发送模式。 433 434 ```cpp 435 notify = (struct UsbCdcNotification *)req->buf; 436 ... 437 if (memcpy_s((void *)(notify + 1), length, data, length) != EOK) { 438 return HDF_FAILURE; 439 } 440 ret = UsbFnSubmitRequestAsync(req); // 异步发送 441 ``` 442 443### 开发实例 444 445本实例提供USB串口驱动开发示例,并简要对具体关键点进行开发说明。 446 447#### Host DDK API驱动开发 448 449```cpp 450#include "usb_serial.h" 451#include "hdf_base.h" 452#include "hdf_log.h" 453#include "osal_mem.h" 454#include "osal_time.h" 455#include "securec.h" 456#include "usb_ddk_interface.h" 457#include "hdf_usb_pnp_manage.h" 458 459#define HDF_LOG_TAG USB_HOST_ACM 460#define STR_LEN 512 461 462static struct UsbRequest *g_syncRequest = NULL; // 定义一个USB请求 463static struct UsbRequest *g_ctrlCmdRequest = NULL; 464static bool g_acmReleaseFlag = false; 465static uint8_t *g_acmReadBuffer = NULL; 466... 467static int32_t SerialCtrlMsg(struct AcmDevice *acm, uint8_t request, 468 uint16_t value, void *buf, uint16_t len) 469{ 470 int32_t ret; 471 uint16_t index = acm->intPipe->interfaceId; 472 struct UsbControlParams controlParams; 473 struct UsbRequestParams params; // 定义一个USB请求参数对象 474 if (acm == NULL || buf == NULL) { 475 return HDF_ERR_IO; 476 } 477 if (acm->ctrlReq == NULL) { 478 // 为获取到的UsbInterfaceHandle预先分配待发送的IO Request对象 479 acm->ctrlReq = UsbAllocRequest(acm->ctrDevHandle, 0, len); 480 if (acm->ctrlReq == NULL) { 481 return HDF_ERR_IO; 482 } 483 } 484 485 controlParams.request = request; 486 controlParams.target = USB_REQUEST_TARGET_INTERFACE; // 接口对象 487 controlParams.reqType = USB_REQUEST_TYPE_CLASS; // 请求类型 488 controlParams.direction = USB_REQUEST_DIR_TO_DEVICE; // 从主机到设备的数据传输 489 controlParams.value = value; 490 controlParams.index = index; 491 controlParams.data = buf; 492 controlParams.size = len; 493 494 params.interfaceId = USB_CTRL_INTERFACE_ID; // 定义USB控制接口的默认ID 495 params.pipeAddress = acm->ctrPipe->pipeAddress; 496 params.pipeId = acm->ctrPipe->pipeId; 497 params.requestType = USB_REQUEST_PARAMS_CTRL_TYPE; // 控制类型 498 params.timeout = USB_CTRL_SET_TIMEOUT; // 设置超时时间 499 params.ctrlReq = UsbControlSetUp(&controlParams); 500 // 根据params填充预先分配的IO Request 501 ret = UsbFillRequest(acm->ctrlReq, acm->ctrDevHandle, ¶ms); 502 if (ret != HDF_SUCCESS) { 503 return ret; 504 } 505 // 发送同步IO Request 506 ret = UsbSubmitRequestSync(acm->ctrlReq); 507 if (ret != HDF_SUCCESS) { 508 return ret; 509 } 510 if (!acm->ctrlReq->compInfo.status) { 511 HDF_LOGE("%s status=%d ", __func__, acm->ctrlReq->compInfo.status); 512 } 513 return HDF_SUCCESS; 514} 515... 516static struct UsbInterface *GetUsbInterfaceById(const struct AcmDevice *acm, 517 uint8_t interfaceIndex) 518{ 519 struct UsbInterface *tmpIf = NULL; 520 // 获取UsbInterface接口对象 521 tmpIf = (struct UsbInterface *)UsbClaimInterface(acm->session, acm->busNum, acm->devAddr, interfaceIndex); 522 return tmpIf; 523} 524... 525static struct UsbPipeInfo *EnumePipe(const struct AcmDevice *acm, 526 uint8_t interfaceIndex, UsbPipeType pipeType, UsbPipeDirection pipeDirection) 527{ 528 uint8_t i; 529 int32_t ret; 530 struct UsbInterfaceInfo *info = NULL; // 定义一个USB接口信息对象 531 UsbInterfaceHandle *interfaceHandle = NULL; // 定义一个USB接口操作句柄,就是void *类型 532 if (pipeType == USB_PIPE_TYPE_CONTROL) 533 { 534 info = &acm->ctrIface->info; 535 interfaceHandle = acm->ctrDevHandle; 536 } 537 else 538 { 539 info = &acm->iface[interfaceIndex]->info; 540 // 根据interfaceIndex获取设备句柄 541 interfaceHandle = InterfaceIdToHandle(acm, info->interfaceIndex); 542 } 543 544 for (i = 0; i <= info->pipeNum; i++) { 545 struct UsbPipeInfo p; 546 // 获取指定索引为i的pipeInfo信息 547 ret = UsbGetPipeInfo(interfaceHandle, info->curAltSetting, i, &p); 548 if (ret < 0) { 549 continue; 550 } 551 if ((p.pipeDirection == pipeDirection) && (p.pipeType == pipeType)) { 552 struct UsbPipeInfo *pi = OsalMemCalloc(sizeof(*pi)); // 开辟内存并初始化 553 if (pi == NULL) { 554 return NULL; 555 } 556 p.interfaceId = info->interfaceIndex; 557 *pi = p; 558 return pi; 559 } 560 } 561 return NULL; 562} 563 564static struct UsbPipeInfo *GetPipe(const struct AcmDevice *acm, 565 UsbPipeType pipeType, UsbPipeDirection pipeDirection) 566{ 567 uint8_t i; 568 if (acm == NULL) { 569 return NULL; 570 } 571 for (i = 0; i < acm->interfaceCnt; i++) { 572 struct UsbPipeInfo *p = NULL; 573 if (!acm->iface[i]) { 574 continue; 575 } 576 // 获取控制pipe的pipeInfo信息 577 p = EnumePipe(acm, i, pipeType, pipeDirection); 578 if (p == NULL) { 579 continue; 580 } 581 return p; 582 } 583 return NULL; 584} 585 586/* HdfDriverEntry implementations */ 587static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device) 588{ 589 struct UsbPnpNotifyServiceInfo *info = NULL; 590 errno_t err; 591 struct AcmDevice *acm = NULL; 592 if (device == NULL) { 593 return HDF_ERR_INVALID_OBJECT; 594 } 595 acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm)); 596 if (acm == NULL) { 597 return HDF_FAILURE; 598 } 599 // 初始化互斥锁,&acm->lock表示指向互斥量的指针 600 if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) { 601 goto error; 602 } 603 info = (struct UsbPnpNotifyServiceInfo *)device->priv; 604 if (info != NULL) { 605 acm->busNum = info->busNum; 606 acm->devAddr = info->devNum; 607 acm->interfaceCnt = info->interfaceLength; 608 err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, 609 (const void*)info->interfaceNumber, info->interfaceLength); 610 if (err != EOK) { 611 goto lock_error; 612 } 613 } else { 614 goto lock_error; 615 } 616 acm->device = device; 617 device->service = &(acm->service); 618 acm->device->service->Dispatch = UsbSerialDeviceDispatch; 619 return HDF_SUCCESS; 620 621lock_error: 622 if (OsalMutexDestroy(&acm->lock)) { 623 HDF_LOGE("%s:%d OsalMutexDestroy failed", __func__, __LINE__); 624 } 625error: 626 OsalMemFree(acm); 627 acm = NULL; 628 return HDF_FAILURE; 629} 630... 631static int32_t AcmAllocReadRequests(struct AcmDevice *acm) 632{ 633 int32_t ret; 634 struct UsbRequestParams readParams; 635 for (int32_t i = 0; i < ACM_NR; i++) { 636 // 分配待发送的readReq IO Request对象 637 acm->readReq[i] = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), 0, acm->readSize); 638 if (!acm->readReq[i]) { 639 goto error; 640 } 641 readParams.userData = (void *)acm; 642 readParams.pipeAddress = acm->dataInPipe->pipeAddress; 643 readParams.pipeId = acm->dataInPipe->pipeId; 644 readParams.interfaceId = acm->dataInPipe->interfaceId; 645 readParams.callback = AcmReadBulk; 646 readParams.requestType = USB_REQUEST_PARAMS_DATA_TYPE; /* Data type */ 647 readParams.timeout = USB_CTRL_SET_TIMEOUT; 648 readParams.dataReq.numIsoPackets = 0; 649 readParams.dataReq.direction = (acm->dataInPipe->pipeDirection >> USB_PIPE_DIR_OFFSET) & 0x1; 650 readParams.dataReq.length = acm->readSize; 651 // 根据readParams填充预先分配待发送的readReq IO Request对象 652 ret = UsbFillRequest(acm->readReq[i], InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), &readParams); 653 if (ret != HDF_SUCCESS) { 654 goto error; 655 } 656 } 657 return HDF_SUCCESS; 658 659error: 660 AcmFreeReadRequests(acm); 661 return HDF_ERR_MALLOC_FAIL; 662} 663 664static int32_t AcmAllocNotifyRequest(struct AcmDevice *acm) 665{ 666 int32_t ret; 667 struct UsbRequestParams intParams = {}; 668 // 分配待发送的中断IO Request对象 669 acm->notifyReq = UsbAllocRequest(InterfaceIdToHandle(acm, acm->intPipe->interfaceId), 0, acm->intSize); 670 if (!acm->notifyReq) { 671 return HDF_ERR_MALLOC_FAIL; 672 } 673 intParams.userData = (void *)acm; 674 intParams.pipeAddress = acm->intPipe->pipeAddress; 675 intParams.pipeId = acm->intPipe->pipeId; 676 intParams.interfaceId = acm->intPipe->interfaceId; 677 intParams.callback = AcmCtrlIrq; 678 intParams.requestType = USB_REQUEST_PARAMS_DATA_TYPE; 679 intParams.timeout = USB_CTRL_SET_TIMEOUT; 680 intParams.dataReq.numIsoPackets = 0; 681 intParams.dataReq.direction = (acm->intPipe->pipeDirection >> USB_PIPE_DIR_OFFSET) & DIRECTION_MASK; 682 intParams.dataReq.length = acm->intSize; 683 // 填充预先分配的中断IO Request 684 ret = UsbFillRequest(acm->notifyReq, InterfaceIdToHandle(acm, acm->intPipe->interfaceId), &intParams); 685 if (ret != HDF_SUCCESS) { 686 goto error; 687 } 688 return HDF_SUCCESS; 689 690error: 691 AcmFreeNotifyRequest(acm); 692 return ret; 693} 694 695static void AcmReleaseInterfaces(struct AcmDevice *acm) 696{ 697 for (int32_t i = 0; i < acm->interfaceCnt; i++) { 698 if (acm->iface[i]) { 699 // 释放一个USB接口对象 700 UsbReleaseInterface(acm->iface[i]); 701 acm->iface[i] = NULL; 702 } 703 } 704 if (acm->ctrIface) { 705 UsbReleaseInterface(acm->ctrIface); 706 acm->ctrIface = NULL; 707 } 708} 709 710static int32_t AcmClaimInterfaces(struct AcmDevice *acm) 711{ 712 for (int32_t i = 0; i < acm->interfaceCnt; i++) { 713 // 获取UsbInterface接口对象 714 acm->iface[i] = GetUsbInterfaceById((const struct AcmDevice *)acm, acm->interfaceIndex[i]); 715 if (acm->iface[i] == NULL) { 716 goto error; 717 } 718 } 719 720 // 获取控制接口对应的UsbInterface接口对象 721 acm->ctrIface = GetUsbInterfaceById((const struct AcmDevice *)acm, USB_CTRL_INTERFACE_ID); 722 if (acm->ctrIface == NULL) { 723 goto error; 724 } 725 726 return HDF_SUCCESS; 727 728 error: 729 // 根据acm->interfaceCnt循环释放接口对象 730 AcmReleaseInterfaces(acm); 731 return HDF_FAILURE; 732} 733 734static void AcmCloseInterfaces(struct AcmDevice *acm) 735{ 736 for (int32_t i = 0; i < acm->interfaceCnt; i++) { 737 if (acm->devHandle[i]) { 738 // 关闭一个USB设备对象 739 UsbCloseInterface(acm->devHandle[i]); 740 acm->devHandle[i] = NULL; 741 } 742 } 743 if (acm->ctrDevHandle) { 744 UsbCloseInterface(acm->ctrDevHandle); 745 acm->ctrDevHandle = NULL; 746 } 747} 748 749static int32_t AcmOpenInterfaces(struct AcmDevice *acm) 750{ 751 for (int32_t i = 0; i < acm->interfaceCnt; i++) { 752 if (acm->iface[i]) { 753 // 打开获取到的UsbInterface接口对象 754 acm->devHandle[i] = UsbOpenInterface(acm->iface[i]); 755 if (acm->devHandle[i] == NULL) { 756 goto error; 757 } 758 } 759 } 760 acm->ctrDevHandle = UsbOpenInterface(acm->ctrIface); 761 if (acm->ctrDevHandle == NULL) { 762 goto error; 763 } 764 765 return HDF_SUCCESS; 766 767error: 768 // 关闭所有UsbInterface接口对象 769 AcmCloseInterfaces(acm); 770 return HDF_FAILURE; 771} 772 773static int32_t AcmGetPipes(struct AcmDevice *acm) 774{ 775 // 获取dataInPipe的pipeInfo信息 776 acm->dataInPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_IN); 777 if (acm->dataInPipe == NULL) { 778 goto error; 779 } 780 781 // 获取dataOutPipe的pipeInfo信息 782 acm->dataOutPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_OUT); 783 if (acm->dataOutPipe == NULL) { 784 goto error; 785 } 786 787 // 获取控制pipe的pipeInfo信息 788 acm->ctrPipe = EnumePipe(acm, acm->ctrIface->info.interfaceIndex, USB_PIPE_TYPE_CONTROL, USB_PIPE_DIRECTION_OUT); 789 if (acm->ctrPipe == NULL) { 790 goto error; 791 } 792 793 // 获取中断pipe的pipeInfo信息 794 acm->intPipe = GetPipe(acm, USB_PIPE_TYPE_INTERRUPT, USB_PIPE_DIRECTION_IN); 795 if (acm->intPipe == NULL) { 796 goto error; 797 } 798 799 acm->readSize = acm->dataInPipe->maxPacketSize; 800 acm->writeSize = acm->dataOutPipe->maxPacketSize; 801 acm->ctrlSize = acm->ctrPipe->maxPacketSize; 802 acm->intSize = acm->intPipe->maxPacketSize; 803 return HDF_SUCCESS; 804 805error: 806 // 释放设备中所有的管道信息 807 AcmFreePipes(acm); 808 return HDF_FAILURE; 809} 810 811static void AcmFreeRequests(struct AcmDevice *acm) 812{ 813 if (g_syncRequest != NULL) { 814 UsbFreeRequest(g_syncRequest); 815 g_syncRequest = NULL; 816 } 817 AcmFreeReadRequests(acm); 818 AcmFreeNotifyRequest(acm); 819 AcmFreeWriteRequests(acm); 820 AcmWriteBufFree(acm); 821} 822 823static int32_t AcmAllocRequests(struct AcmDevice *acm) 824{ 825 int32_t ret; 826 827 if (AcmWriteBufAlloc(acm) < 0) { 828 return HDF_ERR_MALLOC_FAIL; 829 } 830 831 for (int32_t i = 0; i < ACM_NW; i++) { 832 struct AcmWb *snd = &(acm->wb[i]); 833 // 分配待发送的IO Request对象 834 snd->request = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataOutPipe->interfaceId), 0, acm->writeSize); 835 snd->instance = acm; 836 if (snd->request == NULL) { 837 goto error_alloc_write_req; 838 } 839 } 840 841 ret = AcmAllocNotifyRequest(acm); // 分配并填充中断IO Request对象 842 if (ret != HDF_SUCCESS) { 843 goto error_alloc_int_req; 844 } 845 846 ret = AcmAllocReadRequests(acm); // 分配并填充readReq IO Request对象 847 if (ret) { 848 goto error_alloc_read_req; 849 } 850 851 return HDF_SUCCESS; 852 853error_alloc_read_req: 854 AcmFreeNotifyRequest(acm); 855error_alloc_int_req: 856 AcmFreeWriteRequests(acm); 857error_alloc_write_req: 858 AcmWriteBufFree(acm); 859 return HDF_FAILURE; 860} 861 862static int32_t AcmInit(struct AcmDevice *acm) 863{ 864 int32_t ret; 865 struct UsbSession *session = NULL; 866 867 if (acm->initFlag == true) { 868 return HDF_SUCCESS; 869 } 870 871 // 初始化Host DDK 872 ret = UsbInitHostSdk(NULL); 873 if (ret != HDF_SUCCESS) { 874 return HDF_ERR_IO; 875 } 876 acm->session = session; 877 878 // 根据acm->interfaceIndex[i]分别获取UsbInterface接口对象 879 ret = AcmClaimInterfaces(acm); 880 if (ret != HDF_SUCCESS) { 881 goto error_claim_interfaces; 882 } 883 884 // 根据acm->iface[i]分别打开UsbInterface接口对象 885 ret = AcmOpenInterfaces(acm); 886 if (ret != HDF_SUCCESS) { 887 goto error_open_interfaces; 888 } 889 890 // 获取管道信息的指针 891 ret = AcmGetPipes(acm); 892 if (ret != HDF_SUCCESS) { 893 goto error_get_pipes; 894 } 895 896 ret = AcmAllocRequests(acm); 897 if (ret != HDF_SUCCESS) { 898 goto error_alloc_reqs; 899 } 900 901 acm->lineCoding.dwDTERate = CpuToLe32(DATARATE); // 转换为小端数据 902 acm->lineCoding.bCharFormat = CHARFORMAT; // 8 903 acm->lineCoding.bParityType = USB_CDC_NO_PARITY; 904 acm->lineCoding.bDataBits = USB_CDC_1_STOP_BITS; 905 acm->initFlag = true; 906 return HDF_SUCCESS; 907 908error_alloc_reqs: 909 AcmFreePipes(acm); 910error_get_pipes: 911 // 关闭所有UsbInterface接口对象 912 AcmCloseInterfaces(acm); 913error_open_interfaces: 914 // 释放所有UsbInterface接口对象 915 AcmReleaseInterfaces(acm); 916error_claim_interfaces: 917 // 在主机端退出USB DDK,acm->session代表指向会话上下文的指针 918 UsbExitHostSdk(acm->session); 919 acm->session = NULL; 920 return ret; 921} 922 923static void AcmRelease(struct AcmDevice *acm) 924{ 925 if (acm->initFlag == false) { 926 return; 927 } 928 929 AcmFreeRequests(acm); 930 AcmFreePipes(acm); 931 AcmCloseInterfaces(acm); 932 AcmReleaseInterfaces(acm); 933 // 在主机端退出USB DDK 934 UsbExitHostSdk(acm->session); 935 acm->session = NULL; 936 acm->initFlag = false; 937} 938 939static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) 940{ 941 int32_t ret; 942 struct AcmDevice *acm = NULL; 943 944 if (device == NULL) { 945 return HDF_ERR_INVALID_OBJECT; 946 } 947 acm = (struct AcmDevice *)device->service; 948 // 初始化互斥锁,&acm->readLock表示指向互斥量的指针 949 OsalMutexInit(&acm->readLock); 950 OsalMutexInit(&acm->writeLock); 951 HDF_LOGD("%s:%d busNum=%d,devAddr=%d", __func__, __LINE__, acm->busNum, acm->devAddr); 952 953 // 给USB串口设备信息开辟空间并赋值 954 ret = UsbSerialDeviceAlloc(acm); 955 if (ret != HDF_SUCCESS) { 956 HDF_LOGE("%s: Serial Device alloc failed", __func__); 957 } 958 959 acm->initFlag = false; 960 g_acmReleaseFlag = false; 961 return ret; 962} 963 964static void UsbSerialDriverRelease(struct HdfDeviceObject *device) 965{ 966 struct AcmDevice *acm = NULL; 967 968 if (device == NULL) { 969 return; 970 } 971 acm = (struct AcmDevice *)device->service; 972 if (acm == NULL) { 973 return; 974 } 975 976 g_acmReleaseFlag = true; 977 978 if (acm->initFlag == true) { 979 AcmRelease(acm); 980 } 981 // 释放usb串口设备信息 982 UsbSeriaDevicelFree(acm); 983 // 释放互斥锁 984 OsalMutexDestroy(&acm->writeLock); 985 OsalMutexDestroy(&acm->readLock); 986 OsalMutexDestroy(&acm->lock); 987 OsalMemFree(acm); 988 acm = NULL; 989} 990 991// 驱动的Bind、Init、及Release操作 992struct HdfDriverEntry g_usbSerialDriverEntry = { 993 .moduleVersion = 1, 994 .moduleName = "usbhost_acm", // 驱动模块名称,必须与hcs文件中配置的名称一致 995 .Bind = UsbSerialDriverBind, 996 .Init = UsbSerialDriverInit, 997 .Release = UsbSerialDriverRelease, 998}; 999HDF_INIT(g_usbSerialDriverEntry); // 驱动入口 1000``` 1001 1002#### Host RAW API驱动开发 1003 1004```cpp 1005root { 1006 module = "usb_pnp_device"; 1007 usb_pnp_config { 1008 match_attr = "usb_pnp_match"; 1009 usb_pnp_device_id = "UsbPnpDeviceId"; 1010 UsbPnpDeviceId { 1011 idTableList = [ 1012 "host_acm_rawapi_table" 1013 ]; 1014 host_acm_rawapi_table { // 驱动配置匹配表信息 1015 // 驱动模块名,该字段的值必须和驱动入口结构的moduleName一致 1016 moduleName = "usbhost_acm_rawapi"; 1017 // 驱动对外发布服务的名称,必须唯一 1018 serviceName = "usbhost_acm_rawapi_service"; 1019 // 驱动私有数据匹配关键字 1020 deviceMatchAttr = "usbhost_acm_rawapi_matchAttr"; 1021 // 从该字段开始(包含该字段)之后数据长度,以byte为单位 1022 length = 21; 1023 // USB驱动匹配规则vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber 1024 matchFlag = 0x0303; 1025 // 厂商编号 1026 vendorId = 0x12D1; 1027 // 产品编号 1028 productId = 0x5000; 1029 // 设备出厂编号,低16位 1030 bcdDeviceLow = 0x0000; 1031 // 设备出厂编号,高16位 1032 bcdDeviceHigh = 0x0000; 1033 // USB分配的设备类代码 1034 deviceClass = 0; 1035 // USB分配的子类代码 1036 deviceSubClass = 0; 1037 // USB分配的设备协议代码 1038 deviceProtocol = 0; 1039 // 接口类型,根据实际需要可填写多个 1040 interfaceClass = [0]; 1041 // 接口子类型,根据实际需要可填写多个 1042 interfaceSubClass = [2, 0]; 1043 // 接口所遵循的协议,根据实际需要可填写多个 1044 interfaceProtocol = [1, 2]; 1045 // 接口的编号,根据实际需要可填写多个 1046 interfaceNumber = [2, 3]; 1047 } 1048 } 1049 } 1050} 1051``` 1052 1053```cpp 1054#include "usb_serial_rawapi.h" 1055#include <unistd.h> 1056#include "osal_mem.h" 1057#include "osal_time.h" 1058#include "securec.h" 1059#include "hdf_base.h" 1060#include "hdf_log.h" 1061#include "hdf_usb_pnp_manage.h" 1062 1063#define HDF_LOG_TAG USB_HOST_ACM_RAW_API // 日志中可查寻的标签 1064#define USB_CTRL_REQ_SIZE 64 1065#define USB_IO_THREAD_STACK_SIZE 8192 1066#define USB_RAW_IO_SLEEP_MS_TIME 100 1067#define USB_RAW_IO_STOP_WAIT_MAX_TIME 3 1068 1069static struct UsbRawRequest *g_syncRequest = NULL; 1070static UsbRawIoProcessStatusType g_stopIoStatus = USB_RAW_IO_PROCESS_RUNNING; 1071struct OsalMutex g_stopIoLock; 1072static bool g_rawAcmReleaseFlag = false; 1073...... 1074 1075static int32_t UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConfigDescriptor **config) 1076{ 1077 UsbRawDevice *dev = NULL; 1078 int32_t activeConfig; 1079 int32_t ret; 1080 1081 if (devHandle == NULL) { 1082 return HDF_ERR_INVALID_PARAM; 1083 } 1084 1085 // 获取主用设备配置 1086 ret = UsbRawGetConfiguration(devHandle, &activeConfig); 1087 if (ret != HDF_SUCCESS) { 1088 return HDF_FAILURE; 1089 } 1090 1091 // 根据指定的设备句柄获取设备指针 1092 dev = UsbRawGetDevice(devHandle); 1093 if (dev == NULL) { 1094 return HDF_FAILURE; 1095 } 1096 1097 // 根据指定的设备ID获取设备配置描述符 1098 ret = UsbRawGetConfigDescriptor(dev, activeConfig, config); 1099 if (ret != HDF_SUCCESS) { 1100 HDF_LOGE("UsbRawGetConfigDescriptor failed, ret=%d\n", ret); 1101 } 1102 return ret; 1103} 1104... 1105static int32_t UsbAllocWriteRequests(struct AcmDevice *acm) 1106{ 1107 int32_t i; 1108 1109 for (i = 0; i < ACM_NW; i++) { 1110 struct AcmWb *snd = &acm->wb[i]; 1111 // 分配一个具有指定数目的同步传输分组描述符的传输请求 1112 snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataOutEp->maxPacketSize); 1113 snd->instance = acm; 1114 if (snd->request == NULL) { 1115 return HDF_ERR_MALLOC_FAIL; 1116 } 1117 } 1118 1119 return HDF_SUCCESS; 1120} 1121... 1122/* HdfDriverEntry implementations */ 1123static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device) 1124{ 1125 struct AcmDevice *acm = NULL; 1126 struct UsbPnpNotifyServiceInfo *info = NULL; 1127 errno_t err; 1128 1129 if (device == NULL) { 1130 return HDF_ERR_INVALID_OBJECT; 1131 } 1132 1133 acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm)); 1134 if (acm == NULL) { 1135 return HDF_FAILURE; 1136 } 1137 if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) { 1138 goto error; 1139 } 1140 1141 info = (struct UsbPnpNotifyServiceInfo *)device->priv; 1142 if (info != NULL) { 1143 acm->busNum = info->busNum; 1144 acm->devAddr = info->devNum; 1145 acm->interfaceCnt = info->interfaceLength; 1146 err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, 1147 (const void*)info->interfaceNumber, info->interfaceLength); 1148 if (err != EOK) { 1149 goto lock_error; 1150 } 1151 } else { 1152 goto lock_error; 1153 } 1154 1155 device->service = &(acm->service); 1156 device->service->Dispatch = UsbSerialDeviceDispatch; 1157 acm->device = device; 1158 return HDF_SUCCESS; 1159 1160lock_error: 1161 if (OsalMutexDestroy(&acm->lock)) { 1162 HDF_LOGE("%s:%d OsalMutexDestroy failed", __func__, __LINE__); 1163 } 1164error: 1165 OsalMemFree(acm); 1166 acm = NULL; 1167 return HDF_FAILURE; 1168} 1169... 1170static int32_t UsbAllocReadRequests(struct AcmDevice *acm) 1171{ 1172 struct UsbRawFillRequestData reqData; 1173 int32_t size = acm->dataInEp->maxPacketSize; 1174 int32_t ret; 1175 1176 for (int32_t i = 0; i < ACM_NR; i++) { 1177 // 分配一个具有指定数目的同步传输分组描述符的传输请求 1178 acm->readReq[i] = UsbRawAllocRequest(acm->devHandle, 0, size); 1179 if (!acm->readReq[i]) { 1180 return HDF_ERR_MALLOC_FAIL; 1181 } 1182 1183 reqData.endPoint = acm->dataInEp->addr; 1184 reqData.numIsoPackets = 0; 1185 reqData.callback = AcmReadBulkCallback; 1186 reqData.userData = (void *)acm; 1187 reqData.timeout = USB_CTRL_SET_TIMEOUT; 1188 reqData.length = size; 1189 1190 // 在批量传输请求中填写所需信息 1191 ret = UsbRawFillBulkRequest(acm->readReq[i], acm->devHandle, &reqData); 1192 if (ret != HDF_SUCCESS) { 1193 return HDF_FAILURE; 1194 } 1195 } 1196 1197 return HDF_SUCCESS; 1198} 1199... 1200static int32_t UsbAllocNotifyRequest(struct AcmDevice *acm) 1201{ 1202 struct UsbRawFillRequestData fillRequestData; 1203 int32_t size = acm->notifyEp->maxPacketSize; 1204 int32_t ret; 1205 1206 // 分配一个具有指定数目的同步传输分组描述符的传输请求 1207 acm->notifyReq = UsbRawAllocRequest(acm->devHandle, 0, size); 1208 if (!acm->notifyReq) { 1209 return HDF_ERR_MALLOC_FAIL; 1210 } 1211 1212 fillRequestData.endPoint = acm->notifyEp->addr; 1213 fillRequestData.length = size; 1214 fillRequestData.numIsoPackets = 0; 1215 fillRequestData.callback = AcmNotifyReqCallback; 1216 fillRequestData.userData = (void *)acm; 1217 fillRequestData.timeout = USB_CTRL_SET_TIMEOUT; 1218 1219 // 在中断传输请求中填充所需的信息 1220 ret = UsbRawFillInterruptRequest(acm->notifyReq, acm->devHandle, &fillRequestData); 1221 if (ret != HDF_SUCCESS) { 1222 return HDF_FAILURE; 1223 } 1224 1225 return HDF_SUCCESS; 1226} 1227... 1228static int32_t UsbSerialInit(struct AcmDevice *acm) 1229{ 1230 struct UsbSession *session = NULL; 1231 UsbRawHandle *devHandle = NULL; 1232 int32_t ret; 1233 1234 if (acm->initFlag == true) { 1235 return HDF_SUCCESS; 1236 } 1237 1238 // 以专家模式初始化USB DDK 1239 ret = UsbRawInit(NULL); 1240 if (ret != HDF_SUCCESS) { 1241 return HDF_ERR_IO; 1242 } 1243 acm->session = session; 1244 1245 // 打开一个USB设备对象 1246 devHandle = UsbRawOpenDevice(session, acm->busNum, acm->devAddr); 1247 if (devHandle == NULL) { 1248 ret = HDF_FAILURE; 1249 goto err_open_device; 1250 } 1251 acm->devHandle = devHandle; 1252 // 获取主用设备配置、设备指针及配置描述符 1253 ret = UsbGetConfigDescriptor(devHandle, &acm->config); 1254 if (ret != HDF_SUCCESS) { 1255 ret = HDF_FAILURE; 1256 goto err_get_desc; 1257 } 1258 ret = UsbParseConfigDescriptor(acm, acm->config); 1259 if (ret != HDF_SUCCESS) { 1260 ret = HDF_FAILURE; 1261 goto err_parse_desc; 1262 } 1263 1264 ret = AcmWriteBufAlloc(acm); 1265 if (ret < 0) { 1266 ret = HDF_FAILURE; 1267 goto err_alloc_write_buf; 1268 } 1269 ret = UsbAllocWriteRequests(acm); 1270 if (ret < 0) { 1271 ret = HDF_FAILURE; 1272 goto err_alloc_write_reqs; 1273 } 1274 ret = UsbAllocNotifyRequest(acm); 1275 if (ret) { 1276 goto err_alloc_notify_req; 1277 } 1278 ret = UsbAllocReadRequests(acm); 1279 if (ret) { 1280 goto err_alloc_read_reqs; 1281 } 1282 ret = UsbStartIo(acm); 1283 if (ret) { 1284 goto err_start_io; 1285 } 1286 1287 acm->lineCoding.dwDTERate = CpuToLe32(DATARATE); 1288 acm->lineCoding.bCharFormat = CHARFORMAT; 1289 acm->lineCoding.bParityType = USB_CDC_NO_PARITY; 1290 acm->lineCoding.bDataBits = USB_CDC_1_STOP_BITS; 1291 1292 ret = UsbRawSubmitRequest(acm->notifyReq); 1293 if (ret) { 1294 goto err_submit_req; 1295 } 1296 1297 acm->initFlag = true; 1298 return HDF_SUCCESS; 1299 1300err_submit_req: 1301 UsbStopIo(acm); // 停止IO线程并释放所有资源 1302err_start_io: 1303 UsbFreeReadRequests(acm); 1304err_alloc_read_reqs: 1305 UsbFreeNotifyRequest(acm); 1306 err_alloc_notify_req: 1307 UsbFreeWriteRequests(acm); 1308err_alloc_write_reqs: 1309 AcmWriteBufFree(acm); 1310err_alloc_write_buf: 1311 UsbReleaseInterfaces(acm); 1312err_parse_desc: 1313 UsbRawFreeConfigDescriptor(acm->config); 1314 acm->config = NULL; 1315err_get_desc: 1316 (void)UsbRawCloseDevice(devHandle); // 关闭USB设备对象 1317err_open_device: 1318 UsbRawExit(acm->session); // 退出USB DDK的专家模式 1319 1320 return ret; 1321} 1322 1323static void UsbSerialRelease(struct AcmDevice *acm) 1324{ 1325 if (acm->initFlag == false) { 1326 return; 1327 } 1328 1329 /* stop io thread and release all resources */ 1330 UsbStopIo(acm); 1331 if (g_syncRequest != NULL) { 1332 UsbRawFreeRequest(g_syncRequest); 1333 g_syncRequest = NULL; 1334 } 1335 UsbFreeReadRequests(acm); 1336 UsbFreeNotifyRequest(acm); 1337 UsbFreeWriteRequests(acm); 1338 AcmWriteBufFree(acm); 1339 (void)UsbRawCloseDevice(acm->devHandle); 1340 UsbReleaseInterfaces(acm); 1341 UsbRawFreeConfigDescriptor(acm->config); 1342 acm->config = NULL; 1343 // 退出USB DDK的专家模式 1344 UsbRawExit(acm->session); 1345 1346 acm->initFlag = false; 1347} 1348 1349static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) 1350{ 1351 struct AcmDevice *acm = NULL; 1352 int32_t ret; 1353 1354 if (device == NULL) { 1355 return HDF_ERR_INVALID_OBJECT; 1356 } 1357 acm = (struct AcmDevice *)device->service; 1358 OsalMutexInit(&acm->readLock); 1359 OsalMutexInit(&acm->writeLock); 1360 1361 ret = UsbSerialDeviceAlloc(acm); 1362 if (ret != HDF_SUCCESS) { 1363 HDF_LOGE("%s:%d UsbSerialDeviceAlloc failed", __func__, __LINE__); 1364 } 1365 1366 acm->initFlag = false; 1367 g_rawAcmReleaseFlag = false; 1368 return ret; 1369} 1370 1371static void UsbSerialDriverRelease(struct HdfDeviceObject *device) 1372{ 1373 struct AcmDevice *acm = NULL; 1374 if (device == NULL) { 1375 return; 1376 } 1377 1378 acm = (struct AcmDevice *)device->service; 1379 if (acm == NULL) { 1380 return; 1381 } 1382 1383 g_rawAcmReleaseFlag = true; 1384 1385 if (acm->initFlag == true) { 1386 UsbSerialRelease(acm); 1387 } 1388 UsbSeriaDevicelFree(acm); 1389 OsalMutexDestroy(&acm->writeLock); 1390 OsalMutexDestroy(&acm->readLock); 1391 OsalMutexDestroy(&acm->lock); 1392 OsalMemFree(acm); 1393 acm = NULL; 1394} 1395 1396struct HdfDriverEntry g_usbSerialRawDriverEntry = { 1397 .moduleVersion = 1, 1398 .moduleName = "usbhost_acm_rawapi", // 驱动模块名称,必须与hcs文件中配置的名称一致 1399 .Bind = UsbSerialDriverBind, 1400 .Init = UsbSerialDriverInit, 1401 .Release = UsbSerialDriverRelease, 1402}; 1403HDF_INIT(g_usbSerialRawDriverEntry); 1404``` 1405 1406#### Device DDK API驱动开发 1407 1408USB ACM设备核心代码路径为drivers\peripheral\usb\gadget\function\acm\cdcacm.c。其使用示例如下所示,首先根据描述符创建设备,然后获取接口,打开接口,获取Pipe信息,接收Event事件,接着进行USB通信(读写等),设备卸载时候,关闭接口,停止Event接收,删除设备。 1409 14101. 创建设备。 1411 1412 ```cpp 1413 static int32_t AcmCreateFuncDevice(struct UsbAcmDevice *acm, struct DeviceResourceIface *iface) 1414 { 1415 struct UsbFnDevice *fnDev = NULL; 1416 struct UsbFnDescriptorData descData; 1417 uint8_t useHcs; 1418 ... 1419 if (useHcs == 0) { // 描述符来自于代码中编码 1420 descData.type = USBFN_DESC_DATA_TYPE_DESC; 1421 descData.descriptor = &g_masterFuncDevice; 1422 } else { // 描述符来自于解析hcs文件 1423 descData.type = USBFN_DESC_DATA_TYPE_PROP; 1424 descData.property = device->property; 1425 } 1426 /* 创建设备 */ 1427 fnDev = (struct UsbFnDevice *)UsbFnDeviceCreate(acm->udcName, &descData); 1428 if (fnDev == NULL) { 1429 return HDF_FAILURE; 1430 } 1431 ... 1432 } 1433 ``` 1434 14352. 获取接口,打开接口,获取Pipe信息 1436 1437 ```cpp 1438 static int32_t AcmParseEachPipe(struct UsbAcmDevice *acm, struct UsbAcmInterface *iface) 1439 { 1440 ... 1441 for (i = 0; i < fnIface->info.numPipes; i++) { 1442 struct UsbFnPipeInfo pipeInfo; 1443 /* 获取pipe信息 */ 1444 ret = UsbFnInterfaceGetPipeInfo(fnIface, i, &pipeInfo); 1445 ... 1446 } 1447 return HDF_SUCCESS; 1448 } 1449 /* 获取接口,打开接口获取handle */ 1450 static int32_t AcmParseEachIface(struct UsbAcmDevice *acm, struct UsbFnDevice *fnDev) 1451 { 1452 ... 1453 for (i = 0; i < fnDev->numInterfaces; i++) { 1454 /* 获取接口 */ 1455 fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i); 1456 ... 1457 /* 打开接口 */ 1458 handle = UsbFnInterfaceOpen(fnIface); 1459 ... 1460 } 1461 return HDF_SUCCESS; 1462 } 1463 ``` 1464 14653. 接收Event事件(EP0控制传输) 1466 1467 ```cpp 1468 static int32_t AcmAllocCtrlRequests(struct UsbAcmDevice *acm, int32_t num) 1469 { 1470 ... 1471 req = UsbFnCtrlRequestAlloc(acm->ctrlIface.handle, 1472 sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); 1473 ... 1474 } 1475 static int32_t AcmDriverInit(struct HdfDeviceObject *device) 1476 { 1477 ... 1478 /* 开始接收Event */ 1479 ret = UsbFnInterfaceStartRecvEvent(acm->ctrlIface.fn, 0xff, UsbAcmEventCallback, acm); 1480 ... 1481 } 1482 ``` 1483 14844. 进行USB通信(读写等) 1485 1486 ```cpp 1487 static int32_t AcmSendNotifyRequest(struct UsbAcmDevice *acm, uint8_t type, 1488 uint16_t value, void *data, uint32_t length) 1489 { 1490 ... 1491 /* 异步发送 */ 1492 ret = UsbFnRequestSubmitAsync(req); 1493 ... 1494 } 1495 ``` 1496 14975. 关闭接口,停止Event接收,删除设备 1498 1499 ```cpp 1500 static int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm) 1501 { 1502 int32_t ret; 1503 /* 关闭接口 */ 1504 (void)UsbFnInterfaceClose(acm->ctrlIface.handle); 1505 (void)UsbFnInterfaceClose(acm->dataIface.handle); 1506 /* 停止接收Event EP0控制传输 */ 1507 (void)UsbFnInterfaceStopRecvEvent(acm->ctrlIface.fn); 1508 /* 删除设备 */ 1509 ret = UsbFnDeviceRemove(acm->fnDev); 1510 if (ret != HDF_SUCCESS) { 1511 HDF_LOGE("%s: remove usb function device failed", __func__); 1512 } 1513 return ret; 1514 } 1515 ``` 1516 1517## 参考 1518 1519- 代码仓库如下: 1520 1521 **[drivers\_hdf\_core](https://gitee.com/openharmony/drivers_hdf_core)** 1522 1523 [drivers\_peripheral](https://gitee.com/openharmony/drivers_peripheral) 1524 1525 [drivers\_interface](https://gitee.com/openharmony/drivers_interface) 1526 1527- 代码路径如下: 1528 1529 USB驱动模型liteos适配://drivers/hdf_core/adapter/khdf/liteos/model/usb 1530 1531 USB DDK驱动加载实现://drivers/hdf_core/framework/model/usb 1532 1533 USB HDI服务端实现://drivers/peripheral/usb/hdi_service 1534 1535 USB HDI对外接口://out/{product_name}/gen/drivers/interface/usb/v1_0 1536 1537