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  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  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| struct UsbInterface *UsbClaimInterface(const struct<br/> UsbSession *session, uint8_t busNum, uint8_t usbAddr, <br/>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 .funcName = "f_generic.a", //功能名称 300 .strings = g_acmStrings, //字符串 301 .fsDescriptors = g_acmFsFunction, //初始化fs描述符 302 .hsDescriptors = g_acmHsFunction, //初始化hs描述符 303 .ssDescriptors = g_acmSsFunction, //初始化ss描述符 304 .sspDescriptors = nullptr, //ss描述符置空 305 }; 306 struct UsbFnFunction *g_functions[] = { 307 #ifdef CDC_ECM 308 &g_ecmFunction, 309 #endif 310 #ifdef CDC_ACM 311 &g_acmFunction, 312 #endif 313 nullptr}; 314 static struct UsbFnConfiguration g_masterConfig = { // 配置描述符 315 .configurationValue = 1, 316 .iConfiguration = USB_FUNC_CONFIG_IDX, 317 .attributes = USB_CFG_BUS_POWERED, 318 .maxPower = POWER, 319 .functions = g_functions, 320 }; 321 static struct UsbFnConfiguration *g_configs[] = { 322 &g_masterConfig, 323 nullptr, 324 }; 325 static struct UsbDeviceDescriptor g_cdcUsbFnDeviceDesc = { // 设备描述符 326 .bLength = sizeof(g_cdcUsbFnDeviceDesc), 327 .bDescriptorType = USB_DDK_DT_DEVICE, 328 .bcdUSB = CpuToLe16(BCD_USB), 329 .bDeviceClass = 0, 330 .bDeviceSubClass = 0, 331 .bDeviceProtocol = 0, 332 .bMaxPacketSize0 = USB_MAX_PACKET_SIZE, 333 .idVendor = CpuToLe16(DEVICE_VENDOR_ID), 334 .idProduct = CpuToLe16(DEVICE_PRODUCT_ID), 335 .bcdDevice = CpuToLe16(DEVICE_VERSION), 336 .iManufacturer = USB_FUNC_MANUFACTURER_IDX, 337 .iProduct = USB_FUNC_PRODUCT_IDX, 338 .iSerialNumber = USB_FUNC_SERIAL_IDX, 339 .bNumConfigurations = 1, 340 }; 341 struct UsbFnDeviceDesc g_acmFnDevice = { //描述符入口 342 .deviceDesc = &g_cdcUsbFnDeviceDesc, 343 .deviceStrings = g_devStrings, 344 .configs = g_configs, 345 }; 346 ``` 347 3482. 创建设备。描述符构造完成后,使用UsbFnDeviceCreate函数创建一个USB设备,并传入UDC控制器和UsbFnDescriptorData结构体。 349 350 ```cpp 351 if (useHcs == 0) { // 使用代码编写的描述符 352 descData.type = USBFN_DESC_DATA_TYPE_DESC; 353 descData.descriptor = &g_acmFnDevice; 354 } else { // 使用hcs编写的描述符 355 devMgr->descData.type = USBFN_DESC_DATA_TYPE_PROP; 356 devMgr->descData.property = device->property; 357 } 358 // 创建设备 359 fnDev = (struct UsbFnDevice *)UsbFnCreateDevice(devMgr->udcName, &devMgr->descData); 360 ``` 361 3623. 设备创建后,使用UsbFnGetInterface函数获取UsbInterface接口对象,并通过UsbFnGetInterfacePipeInfo函数获取USB管道信息。 363 364 ```cpp 365 // 获取接口 366 fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i); 367 // 获取Pipe信息 368 UsbFnGetInterfacePipeInfo(fnIface, i, &pipeInfo); 369 // 获取Handle 370 handle = UsbFnOpenInterface(fnIface); 371 // 获取控制(EP0)Request 372 req = UsbFnAllocCtrlRequest(acmDevice->ctrlIface.handle, sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); 373 // 获取Request 374 req = UsbFnAllocCtrlRequest(acmDevice->ctrlIface.handle, sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); 375 ``` 376 3774. 通过UsbFnStartRecvInterfaceEvent函数接收Event事件,并通过UsbFnEventCallback回调函数对Event事件做出响应。 378 379 ```cpp 380 // 开始接收Event事件 381 ret = UsbFnStartRecvInterfaceEvent(acmDevice->ctrlIface.fn, 0xff, AcmEventCallback, acmDevice); 382 // Event处理回调函数 383 static void UsbAcmEventCallback(struct UsbFnEvent *event) 384 { 385 struct UsbAcmDevice *acm = NULL; 386 if (event == NULL || event->context == NULL) { 387 HDF_LOGE("%{public}s: event is null", __func__); 388 return; 389 } 390 acm = (struct UsbAcmDevice *)event->context; 391 switch (event->type) { 392 case USBFN_STATE_BIND: 393 HDF_LOGI("%{public}s: receive bind event", __func__); 394 break; 395 case USBFN_STATE_UNBIND: 396 HDF_LOGI("%{public}s: receive unbind event", __func__); 397 break; 398 case USBFN_STATE_ENABLE: 399 HDF_LOGI("%{public}s: receive enable event", __func__); 400 AcmEnable(acm); 401 break; 402 case USBFN_STATE_DISABLE: 403 HDF_LOGI("%{public}s: receive disable event", __func__); 404 AcmDisable(acm); 405 acm->enableEvtCnt = 0; 406 break; 407 case USBFN_STATE_SETUP: 408 HDF_LOGI("%{public}s: receive setup event", __func__); 409 if (event->setup != NULL) { 410 AcmSetup(acm, event->setup); 411 } 412 break; 413 case USBFN_STATE_SUSPEND: 414 HDF_LOGI("%{public}s: receive suspend event", __func__); 415 AcmSuspend(acm); 416 break; 417 case USBFN_STATE_RESUME: 418 HDF_LOGI("%{public}s: receive resume event", __func__); 419 AcmResume(acm); 420 break; 421 default: 422 break; 423 } 424 } 425 ``` 426 4275. 收发数据,可以选择同步异步发送模式。 428 429 ```cpp 430 notify = (struct UsbCdcNotification *)req->buf; 431 ... 432 ret = memcpy_s((void *)(notify + 1), length, data, length); 433 if (ret != EOK) { 434 HDF_LOGE("%s: memcpy_s failed", __func__); 435 return HDF_FAILURE; 436 } 437 ret = UsbFnSubmitRequestAsync(req); // 异步发送 438 if (ret != HDF_SUCCESS) { 439 HDF_LOGE("%s: send notify request failed", __func__); 440 acm->notifyReq = req; 441 } 442 ``` 443 444### 开发实例 445 446本实例提供USB串口驱动开发示例,并简要对具体关键点进行开发说明。 447 448#### Host DDK API驱动开发 449 450```cpp 451#include "usb_serial.h" 452#include "hdf_base.h" 453#include "hdf_log.h" 454#include "hdf_usb_pnp_manage.h" 455#include "osal_mem.h" 456#include "osal_time.h" 457#include "securec.h" 458#include "usb_ddk_interface.h" 459 460#define HDF_LOG_TAG USB_HOST_ACM 461#define STR_LEN 512 462 463static struct UsbRequest *g_syncRequest = NULL; // 定义一个USB请求 464static struct UsbRequest *g_ctrlCmdRequest = NULL; 465static bool g_acmReleaseFlag = false; 466static uint8_t *g_acmReadBuffer = NULL; 467... 468static int32_t SerialCtrlMsg(struct AcmDevice *acm, uint8_t request, uint16_t value, void *buf, uint16_t len) 469{ 470 int32_t ret; 471 if (acm == NULL || buf == NULL || acm->intPipe == NULL) { 472 HDF_LOGE("%s:invalid param", __func__); 473 return HDF_ERR_IO; 474 } 475 uint16_t index = acm->intPipe->interfaceId; 476 struct UsbControlParams controlParams = {}; 477 struct UsbRequestParams parmas = {}; // 定义一个USB请求参数对象 478 if (acm->ctrlReq == NULL) { 479 // 为获取到的UsbInterfaceHandle预先分配待发送的IO Request对象 480 acm->ctrlReq = UsbAllocRequest(acm->ctrDevHandle, 0, len); 481 if (acm->ctrlReq == NULL) { 482 HDF_LOGE("%s: UsbAllocRequest failed", __func__); 483 return HDF_ERR_IO; 484 } 485 } 486 487 controlParams.request = request; 488 controlParams.target = USB_REQUEST_TARGET_INTERFACE; // 接口对象 489 controlParams.reqType = USB_REQUEST_TYPE_CLASS; // 请求类型 490 controlParams.directon = USB_REQUEST_DIR_TO_DEVICE; // 从主机到设备的数据传输 491 controlParams.value = value; 492 controlParams.index = index; 493 controlParams.data = buf; 494 controlParams.size = len; 495 496 parmas.interfaceId = USB_CTRL_INTERFACE_ID; // 定义USB控制接口的默认ID 497 if (acm->ctrPipe != NULL) { 498 parmas.pipeAddress = acm->ctrPipe->pipeAddress; 499 parmas.pipeId = acm->ctrPipe->pipeId; 500 } 501 parmas.requestType = USB_REQUEST_PARAMS_CTRL_TYPE; // 控制类型 502 parmas.timeout = USB_CTRL_SET_TIMEOUT; // 设置超时时间 503 parmas.ctrlReq = UsbControlSetUp(&controlParams); 504 parmas.callback = NULL; 505 // 根据params填充预先分配的IO Request 506 ret = UsbFillRequest(acm->ctrlReq, acm->ctrDevHandle, &parmas); 507 if (ret != HDF_SUCCESS) { 508 HDF_LOGE("%s: UsbFillRequest failed, ret = %d ", __func__, ret); 509 return ret; 510 } 511 // 发送同步IO Request 512 ret = UsbSubmitRequestSync(acm->ctrlReq); 513 if (ret != HDF_SUCCESS) { 514 HDF_LOGE("UsbSubmitRequestSync failed, ret = %d ", ret); 515 return ret; 516 } 517 if (!acm->ctrlReq->compInfo.status) { 518 HDF_LOGE("%s status=%d ", __func__, acm->ctrlReq->compInfo.status); 519 } 520 return HDF_SUCCESS; 521} 522... 523static struct UsbInterface *GetUsbInterfaceById(const struct AcmDevice *acm, uint8_t interfaceIndex) 524{ 525 // 获取UsbInterface接口对象 526 return UsbClaimInterface(acm->session, acm->busNum, acm->devAddr, interfaceIndex); 527} 528... 529static struct UsbPipeInfo *EnumePipe( 530 const struct AcmDevice *acm, uint8_t interfaceIndex, UsbPipeType pipeType, UsbPipeDirection pipeDirection) 531{ 532 struct UsbInterfaceInfo *info = NULL; // 定义一个USB接口信息对象 533 UsbInterfaceHandle *interfaceHandle = NULL; // 定义一个USB接口操作句柄,就是void *类型 534 if (pipeType == USB_PIPE_TYPE_CONTROL) { 535 info = &acm->ctrIface->info; 536 interfaceHandle = acm->ctrDevHandle; 537 } else { 538 // 根据interfaceIndex获取设备句柄 539 info = &acm->iface[interfaceIndex]->info; 540 interfaceHandle = InterfaceIdToHandle(acm, info->interfaceIndex); 541 } 542 543 for (uint8_t i = 0; i <= info->pipeNum; i++) { 544 struct UsbPipeInfo p; 545 // 获取指定索引为i的pipeInfo信息 546 int32_t ret = UsbGetPipeInfo(interfaceHandle, info->curAltSetting, i, &p); 547 if (ret < 0) { 548 continue; 549 } 550 if ((p.pipeDirection == pipeDirection) && (p.pipeType == pipeType)) { 551 struct UsbPipeInfo *pi = OsalMemCalloc(sizeof(*pi)); // 开辟内存并初始化 552 if (pi == NULL) { 553 HDF_LOGE("%s: Alloc pipe failed", __func__); 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, UsbPipeType pipeType, UsbPipeDirection pipeDirection) 565{ 566 uint8_t i; 567 if (acm == NULL) { 568 HDF_LOGE("%s: invalid param", __func__); 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 HDF_LOGE("%s: device is null", __func__); 594 return HDF_ERR_INVALID_OBJECT; 595 } 596 //开辟内存空间 597 acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm)); 598 if (acm == NULL) { 599 HDF_LOGE("%s: Alloc usb serial device failed", __func__); 600 return HDF_FAILURE; 601 } 602 // 初始化互斥锁,&acm->lock表示指向互斥量的指针 603 if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) { 604 HDF_LOGE("%s:%d OsalMutexInit failed", __func__, __LINE__); 605 goto ERROR; 606 } 607 info = (struct UsbPnpNotifyServiceInfo *)device->priv; 608 if (info != NULL) { 609 HDF_LOGD("%s:%d busNum=%d,devAddr=%d,interfaceLength=%d", __func__, __LINE__, info->busNum, info->devNum, 610 info->interfaceLength); 611 acm->busNum = (uint8_t)info->busNum; 612 acm->devAddr = (uint8_t)info->devNum; 613 acm->interfaceCnt = info->interfaceLength; 614 err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, (const void *)info->interfaceNumber, 615 info->interfaceLength); 616 if (err != EOK) { 617 HDF_LOGE("%s:%d memcpy_s failed err = %d", __func__, __LINE__, err); 618 goto LOCK_ERROR; 619 } 620 } else { 621 HDF_LOGE("%s:%d info is null!", __func__, __LINE__); 622 goto LOCK_ERROR; 623 } 624 acm->device = device; 625 device->service = &(acm->service); 626 acm->device->service->Dispatch = UsbSerialDeviceDispatch; 627 HDF_LOGD("UsbSerialDriverBind=========================OK"); 628 return HDF_SUCCESS; 629 630LOCK_ERROR: 631 if (OsalMutexDestroy(&acm->lock)) { 632 HDF_LOGE("%s:%d OsalMutexDestroy failed", __func__, __LINE__); 633 } 634ERROR: 635 OsalMemFree(acm); 636 acm = NULL; 637 return HDF_FAILURE; 638} 639... 640static int32_t AcmAllocReadRequests(struct AcmDevice *acm) 641{ 642 int32_t ret; 643 struct UsbRequestParams readParmas = {}; 644 for (int32_t i = 0; i < ACM_NR; i++) { 645 // 分配待发送的readReq IO Request对象 646 acm->readReq[i] = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), 0, acm->readSize); 647 if (!acm->readReq[i]) { 648 HDF_LOGE("readReq request failed\n"); 649 goto ERROR; 650 } 651 readParmas.userData = (void *)acm; 652 readParmas.pipeAddress = acm->dataInPipe->pipeAddress; 653 readParmas.pipeId = acm->dataInPipe->pipeId; 654 readParmas.interfaceId = acm->dataInPipe->interfaceId; 655 readParmas.callback = AcmReadBulk; 656 readParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE; /* Data type */ 657 readParmas.timeout = USB_CTRL_SET_TIMEOUT; 658 readParmas.dataReq.numIsoPackets = 0; 659 readParmas.dataReq.directon = (((uint8_t)acm->dataInPipe->pipeDirection) >> USB_PIPE_DIR_OFFSET) & 0x1; 660 readParmas.dataReq.length = (int)acm->readSize; 661 // 根据readParams填充预先分配待发送的readReq IO Request对象 662 ret = UsbFillRequest(acm->readReq[i], InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), &readParmas); 663 if (ret != HDF_SUCCESS) { 664 HDF_LOGE("%s: UsbFillRequest failed, ret=%d \n", __func__, ret); 665 goto ERROR; 666 } 667 } 668 return HDF_SUCCESS; 669 670ERROR: 671 AcmFreeReadRequests(acm); 672 return HDF_ERR_MALLOC_FAIL; 673} 674 675static int32_t AcmAllocNotifyRequest(struct AcmDevice *acm) 676{ 677 int32_t ret; 678 struct UsbRequestParams intParmas = {}; 679 // 分配待发送的中断IO Request对象 680 acm->notifyReq = UsbAllocRequest(InterfaceIdToHandle(acm, acm->intPipe->interfaceId), 0, acm->intSize); 681 if (!acm->notifyReq) { 682 HDF_LOGE("notifyReq request failed.\n"); 683 return HDF_ERR_MALLOC_FAIL; 684 } 685 intParmas.userData = (void *)acm; 686 intParmas.pipeAddress = acm->intPipe->pipeAddress; 687 intParmas.pipeId = acm->intPipe->pipeId; 688 intParmas.interfaceId = acm->intPipe->interfaceId; 689 intParmas.callback = AcmCtrlIrq; 690 intParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE; 691 intParmas.timeout = USB_CTRL_SET_TIMEOUT; 692 intParmas.dataReq.numIsoPackets = 0; 693 intParmas.dataReq.directon = (((uint8_t)acm->intPipe->pipeDirection) >> USB_PIPE_DIR_OFFSET) & DIRECTION_MASK; 694 intParmas.dataReq.length = (int)acm->intSize; 695 // 填充预先分配的中断IO Request 696 ret = UsbFillRequest(acm->notifyReq, InterfaceIdToHandle(acm, acm->intPipe->interfaceId), &intParmas); 697 if (ret != HDF_SUCCESS) { 698 HDF_LOGE("%s: UsbFillRequest failed, ret = %d", __func__, ret); 699 goto ERROR; 700 } 701 return HDF_SUCCESS; 702 703ERROR: 704 AcmFreeNotifyReqeust(acm); 705 return ret; 706} 707 708static void AcmReleaseInterfaces(struct AcmDevice *acm) 709{ 710 for (uint8_t i = 0; i < acm->interfaceCnt; i++) { 711 if (acm->iface[i]) { 712 // 释放一个USB接口对象 713 UsbReleaseInterface(acm->iface[i]); 714 acm->iface[i] = NULL; 715 } 716 } 717 if (acm->ctrIface) { 718 UsbReleaseInterface(acm->ctrIface); 719 acm->ctrIface = NULL; 720 } 721} 722 723static int32_t AcmClaimInterfaces(struct AcmDevice *acm) 724{ 725 for (uint8_t i = 0; i < acm->interfaceCnt; i++) { 726 // 获取UsbInterface接口对象 727 acm->iface[i] = GetUsbInterfaceById((const struct AcmDevice *)acm, acm->interfaceIndex[i]); 728 if (acm->iface[i] == NULL) { 729 HDF_LOGE("%s: interface%d is null", __func__, acm->interfaceIndex[i]); 730 goto ERROR; 731 } 732 } 733 // 获取控制接口对应的UsbInterface接口对象 734 acm->ctrIface = GetUsbInterfaceById((const struct AcmDevice *)acm, USB_CTRL_INTERFACE_ID); 735 if (acm->ctrIface == NULL) { 736 HDF_LOGE("%s: GetUsbInterfaceById null", __func__); 737 goto ERROR; 738 } 739 740 return HDF_SUCCESS; 741 742ERROR: 743 // 根据acm->interfaceCnt循环释放接口对象 744 AcmReleaseInterfaces(acm); 745 return HDF_FAILURE; 746} 747 748static void AcmCloseInterfaces(struct AcmDevice *acm) 749{ 750 for (uint8_t i = 0; i < acm->interfaceCnt; i++) { 751 if (acm->devHandle[i]) { 752 // 关闭一个USB设备对象 753 UsbCloseInterface(acm->devHandle[i]); 754 acm->devHandle[i] = NULL; 755 } 756 } 757 if (acm->ctrDevHandle) { 758 UsbCloseInterface(acm->ctrDevHandle); 759 acm->ctrDevHandle = NULL; 760 } 761} 762 763static int32_t AcmOpenInterfaces(struct AcmDevice *acm) 764{ 765 for (uint8_t i = 0; i < acm->interfaceCnt; i++) { 766 if (acm->iface[i]) { 767 // 打开获取到的UsbInterface接口对象 768 acm->devHandle[i] = UsbOpenInterface(acm->iface[i]); 769 if (acm->devHandle[i] == NULL) { 770 HDF_LOGE("%s: UsbOpenInterface null", __func__); 771 goto ERROR; 772 } 773 } 774 } 775 acm->ctrDevHandle = UsbOpenInterface(acm->ctrIface); 776 if (acm->ctrDevHandle == NULL) { 777 HDF_LOGE("%s: ctrDevHandle UsbOpenInterface null", __func__); 778 goto ERROR; 779 } 780 781 return HDF_SUCCESS; 782 783ERROR: 784 // 关闭所有UsbInterface接口对象 785 AcmCloseInterfaces(acm); 786 return HDF_FAILURE; 787} 788 789static int32_t AcmGetPipes(struct AcmDevice *acm) 790{ 791 // 获取dataInPipe的pipeInfo信息 792 acm->dataInPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_IN); 793 if (acm->dataInPipe == NULL) { 794 HDF_LOGE("dataInPipe is null"); 795 goto ERROR; 796 } 797 // 获取dataOutPipe的pipeInfo信息 798 acm->dataOutPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_OUT); 799 if (acm->dataOutPipe == NULL) { 800 HDF_LOGE("dataOutPipe is null"); 801 goto ERROR; 802 } 803 // 获取控制pipe的pipeInfo信息 804 acm->ctrPipe = EnumePipe(acm, acm->ctrIface->info.interfaceIndex, USB_PIPE_TYPE_CONTROL, USB_PIPE_DIRECTION_OUT); 805 if (acm->ctrPipe == NULL) { 806 HDF_LOGE("ctrPipe is null"); 807 goto ERROR; 808 } 809 // 获取中断pipe的pipeInfo信息 810 acm->intPipe = GetPipe(acm, USB_PIPE_TYPE_INTERRUPT, USB_PIPE_DIRECTION_IN); 811 if (acm->intPipe == NULL) { 812 HDF_LOGE("intPipe is null"); 813 goto ERROR; 814 } 815 816 acm->readSize = acm->dataInPipe->maxPacketSize; 817 acm->writeSize = acm->dataOutPipe->maxPacketSize; 818 acm->ctrlSize = acm->ctrPipe->maxPacketSize; 819 acm->intSize = acm->intPipe->maxPacketSize; 820 821 return HDF_SUCCESS; 822 823ERROR: 824 // 释放设备中所有的管道信息 825 AcmFreePipes(acm); 826 return HDF_FAILURE; 827} 828 829static void AcmFreeRequests(struct AcmDevice *acm) 830{ 831 if (g_syncRequest != NULL) { 832 UsbFreeRequest(g_syncRequest); 833 g_syncRequest = NULL; 834 } 835 AcmFreeReadRequests(acm); 836 AcmFreeNotifyReqeust(acm); 837 AcmFreeWriteRequests(acm); 838 AcmWriteBufFree(acm); 839} 840 841static int32_t AcmAllocRequests(const struct AcmDevice *acm) 842{ 843 int32_t ret; 844 845 if (AcmWriteBufAlloc(acm) < 0) { 846 HDF_LOGE("%s: AcmWriteBufAlloc failed", __func__); 847 return HDF_ERR_MALLOC_FAIL; 848 } 849 850 for (int32_t i = 0; i < ACM_NW; i++) { 851 struct AcmWb *snd = (struct AcmWb *)&(acm->wb[i]); 852 // 分配待发送的IO Request对象 853 snd->request = UsbAllocRequest( 854 InterfaceIdToHandle((struct AcmDevice *)acm, acm->dataOutPipe->interfaceId), 0, acm->writeSize); 855 snd->instance = (struct AcmDevice *)acm; 856 if (snd->request == NULL) { 857 HDF_LOGE("%s:%d snd request fail", __func__, __LINE__); 858 goto ERROR_ALLOC_WRITE_REQ; 859 } 860 } 861 862 ret = AcmAllocNotifyRequest((struct AcmDevice *)acm); // 分配并填充中断IO Request对象 863 if (ret != HDF_SUCCESS) { 864 HDF_LOGE("%s:%d AcmAllocNotifyRequest fail", __func__, __LINE__); 865 goto ERROR_ALLOC_INT_REQ; 866 } 867 868 ret = AcmAllocReadRequests((struct AcmDevice *)acm); // 分配并填充readReq IO Request对象 869 if (ret) { 870 HDF_LOGE("%s:%d AcmAllocReadRequests fail", __func__, __LINE__); 871 goto ERROR_ALLOC_READ_REQ; 872 } 873 874 return HDF_SUCCESS; 875 876ERROR_ALLOC_READ_REQ: 877 AcmFreeNotifyReqeust((struct AcmDevice *)acm); 878ERROR_ALLOC_INT_REQ: 879 AcmFreeWriteRequests((struct AcmDevice *)acm); 880ERROR_ALLOC_WRITE_REQ: 881 AcmWriteBufFree((struct AcmDevice *)acm); 882 return HDF_FAILURE; 883} 884 885static int32_t AcmInit(struct AcmDevice *acm) 886{ 887 int32_t ret; 888 889 if (acm->initFlag) { 890 HDF_LOGE("%{public}s: initFlag is true", __func__); 891 return HDF_SUCCESS; 892 } 893 // 初始化Host DDK 894 ret = UsbInitHostSdk(NULL); 895 if (ret != HDF_SUCCESS) { 896 HDF_LOGE("%{public}s: UsbInitHostSdk failed", __func__); 897 return HDF_ERR_IO; 898 } 899 acm->session = NULL; 900 // 根据acm->interfaceIndex[i]分别获取UsbInterface接口对象 901 ret = AcmClaimInterfaces(acm); 902 if (ret != HDF_SUCCESS) { 903 HDF_LOGE("%{public}s: AcmClaimInterfaces failed", __func__); 904 goto ERROR_CLAIM_INTERFACES; 905 } 906 // 根据acm->iface[i]分别打开UsbInterface接口对象 907 ret = AcmOpenInterfaces(acm); 908 if (ret != HDF_SUCCESS) { 909 HDF_LOGE("%{public}s: AcmOpenInterfaces failed", __func__); 910 goto ERROR_OPEN_INTERFACES; 911 } 912 // 获取管道信息的指针 913 ret = AcmGetPipes(acm); 914 if (ret != HDF_SUCCESS) { 915 HDF_LOGE("%{public}s: AcmGetPipes failed", __func__); 916 goto ERROR_GET_PIPES; 917 } 918 919 ret = AcmAllocRequests(acm); 920 if (ret != HDF_SUCCESS) { 921 HDF_LOGE("%{public}s: AcmAllocRequests failed", __func__); 922 goto ERROR_ALLOC_REQS; 923 } 924 925 acm->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE); 926 acm->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS; 927 acm->lineCoding.bParityType = USB_CDC_NO_PARITY; 928 acm->lineCoding.bDataBits = DATA_BITS_LENGTH; 929 acm->initFlag = true; 930 931 return HDF_SUCCESS; 932 933ERROR_ALLOC_REQS: 934 AcmFreePipes(acm); 935ERROR_GET_PIPES: 936 // 关闭所有UsbInterface接口对象 937 AcmCloseInterfaces(acm); 938ERROR_OPEN_INTERFACES: 939 // 释放所有UsbInterface接口对象 940 AcmReleaseInterfaces(acm); 941ERROR_CLAIM_INTERFACES: 942 // 在主机端退出USB DDK,acm->session代表指向会话上下文的指针 943 UsbExitHostSdk(acm->session); 944 acm->session = NULL; 945 return ret; 946} 947 948static void AcmRelease(struct AcmDevice *acm) 949{ 950 if (!(acm->initFlag)) { 951 HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__); 952 return; 953 } 954 955 AcmCloseInterfaces(acm); 956 AcmReleaseInterfaces(acm); 957 AcmFreeRequests(acm); 958 AcmFreePipes(acm); 959 // 在主机端退出USB DDK 960 UsbExitHostSdk(acm->session); 961 acm->session = NULL; 962 963 acm->initFlag = false; 964} 965 966static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) 967{ 968 int32_t ret; 969 struct AcmDevice *acm = NULL; 970 971 if (device == NULL) { 972 HDF_LOGE("%s: device is null", __func__); 973 return HDF_ERR_INVALID_OBJECT; 974 } 975 acm = (struct AcmDevice *)device->service; 976 // 初始化互斥锁,&acm->readLock表示指向互斥量的指针 977 if (acm == NULL) { 978 return HDF_ERR_INVALID_OBJECT; 979 } 980 OsalMutexInit(&acm->readLock); 981 OsalMutexInit(&acm->writeLock); 982 HDF_LOGD("%s:%d busNum = %d,devAddr = %d", __func__, __LINE__, acm->busNum, acm->devAddr); 983 // 给USB串口设备信息开辟空间并赋值 984 ret = UsbSerialDeviceAlloc(acm); 985 if (ret != HDF_SUCCESS) { 986 HDF_LOGE("%s: Serial Device alloc failed", __func__); 987 } 988 989 acm->initFlag = false; 990 g_acmReleaseFlag = false; 991 992 HDF_LOGD("%s:%d init ok!", __func__, __LINE__); 993 994 return ret; 995} 996 997static void UsbSerialDriverRelease(struct HdfDeviceObject *device) 998{ 999 struct AcmDevice *acm = NULL; 1000 1001 if (device == NULL) { 1002 HDF_LOGE("%s: device is null", __func__); 1003 return; 1004 } 1005 acm = (struct AcmDevice *)device->service; 1006 if (acm == NULL) { 1007 HDF_LOGE("%s: acm is null", __func__); 1008 return; 1009 } 1010 1011 g_acmReleaseFlag = true; 1012 1013 if (acm->initFlag) { 1014 HDF_LOGE("%s:%d AcmRelease", __func__, __LINE__); 1015 AcmRelease(acm); 1016 } 1017 // 释放usb串口设备信息 1018 UsbSeriaDevicelFree(acm); 1019 // 释放互斥锁 1020 OsalMutexDestroy(&acm->writeLock); 1021 OsalMutexDestroy(&acm->readLock); 1022 OsalMutexDestroy(&acm->lock); 1023 OsalMemFree(acm); 1024 acm = NULL; 1025 HDF_LOGD("%s:%d exit", __func__, __LINE__); 1026} 1027// 驱动的Bind、Init、及Release操作 1028struct HdfDriverEntry g_usbSerialDriverEntry = { 1029 .moduleVersion = 1, 1030 .moduleName = "usbhost_acm", // 驱动模块名称,必须与hcs文件中配置的名称一致 1031 .Bind = UsbSerialDriverBind, 1032 .Init = UsbSerialDriverInit, 1033 .Release = UsbSerialDriverRelease, 1034}; 1035HDF_INIT(g_usbSerialDriverEntry); // 驱动入口 1036``` 1037 1038#### Host RAW API驱动开发 1039 1040```cpp 1041root { 1042 module = "usb_pnp_device"; 1043 usb_pnp_config { 1044 match_attr = "usb_pnp_match"; 1045 usb_pnp_device_id = "UsbPnpDeviceId"; 1046 UsbPnpDeviceId { 1047 idTableList = [ 1048 "host_acm_rawapi_table" 1049 ]; 1050 host_acm_rawapi_table { // 驱动配置匹配表信息 1051 // 驱动模块名,该字段的值必须和驱动入口结构的moduleName一致 1052 moduleName = "usbhost_acm_rawapi"; 1053 // 驱动对外发布服务的名称,必须唯一 1054 serviceName = "usbhost_acm_rawapi_service"; 1055 // 驱动私有数据匹配关键字 1056 deviceMatchAttr = "usbhost_acm_rawapi_matchAttr"; 1057 // 从该字段开始(包含该字段)之后数据长度,以byte为单位 1058 length = 21; 1059 // USB驱动匹配规则vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber 1060 matchFlag = 0x0303; 1061 // 厂商编号 1062 vendorId = 0x12D1; 1063 // 产品编号 1064 productId = 0x5000; 1065 // 设备出厂编号,低16位 1066 bcdDeviceLow = 0x0000; 1067 // 设备出厂编号,高16位 1068 bcdDeviceHigh = 0x0000; 1069 // USB分配的设备类代码 1070 deviceClass = 0; 1071 // USB分配的子类代码 1072 deviceSubClass = 0; 1073 // USB分配的设备协议代码 1074 deviceProtocol = 0; 1075 // 接口类型,根据实际需要可填写多个 1076 interfaceClass = [0]; 1077 // 接口子类型,根据实际需要可填写多个 1078 interfaceSubClass = [2, 0]; 1079 // 接口所遵循的协议,根据实际需要可填写多个 1080 interfaceProtocol = [1, 2]; 1081 // 接口的编号,根据实际需要可填写多个 1082 interfaceNumber = [2, 3]; 1083 } 1084 } 1085 } 1086} 1087``` 1088 1089```cpp 1090#include <unistd.h> 1091 1092#include "hdf_base.h" 1093#include "hdf_log.h" 1094#include "hdf_usb_pnp_manage.h" 1095#include "osal_mem.h" 1096#include "osal_time.h" 1097#include "securec.h" 1098#include "usb_serial_rawapi.h" 1099 1100#define HDF_LOG_TAG USB_HOST_ACM_RAW_API 1101#define USB_CTRL_REQ_SIZE 64 1102#define USB_IO_THREAD_STACK_SIZE 8192 1103#define USB_RAW_IO_SLEEP_MS_TIME 100 1104#define USB_RAW_IO_STOP_WAIT_MAX_TIME 3 1105 1106static struct UsbRawRequest *g_syncRequest = NULL; 1107static UsbRawIoProcessStatusType g_stopIoStatus = USB_RAW_IO_PROCESS_RUNNING; 1108struct OsalMutex g_stopIoLock; 1109static bool g_rawAcmReleaseFlag = false; 1110... 1111static int32_t UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConfigDescriptor **config) 1112{ 1113 UsbRawDevice *dev = NULL; 1114 int32_t activeConfig; 1115 int32_t ret; 1116 1117 if (devHandle == NULL) { 1118 HDF_LOGE("%s:%d devHandle is null", __func__, __LINE__); 1119 return HDF_ERR_INVALID_PARAM; 1120 } 1121 // 获取主用设备配置 1122 ret = UsbRawGetConfiguration(devHandle, &activeConfig); 1123 if (ret) { 1124 HDF_LOGE("%s:%d UsbRawGetConfiguration failed, ret = %d", __func__, __LINE__, ret); 1125 return HDF_FAILURE; 1126 } 1127 HDF_LOGE("%s:%d activeConfig = %d", __func__, __LINE__, activeConfig); 1128 // 根据指定的设备句柄获取设备指针 1129 dev = UsbRawGetDevice(devHandle); 1130 if (dev == NULL) { 1131 HDF_LOGE("%s:%d UsbRawGetDevice failed", __func__, __LINE__); 1132 return HDF_FAILURE; 1133 } 1134 // 根据指定的设备ID获取设备配置描述符 1135 ret = UsbRawGetConfigDescriptor(dev, activeConfig, config); 1136 if (ret) { 1137 HDF_LOGE("UsbRawGetConfigDescriptor failed, ret = %d\n", ret); 1138 return HDF_FAILURE; 1139 } 1140 1141 return HDF_SUCCESS; 1142} 1143... 1144 static int32_t UsbAllocWriteRequests(struct AcmDevice *acm) 1145{ 1146 int32_t i; 1147 1148 for (i = 0; i < ACM_NW; i++) { 1149 struct AcmWb *snd = &acm->wb[i]; 1150 // 分配一个具有指定数目的同步传输分组描述符的传输请求 1151 snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataOutEp->maxPacketSize); 1152 snd->instance = acm; 1153 if (snd->request == NULL) { 1154 HDF_LOGE("%s: UsbRawAllocRequest failed", __func__); 1155 return HDF_ERR_MALLOC_FAIL; 1156 } 1157 } 1158 1159 return HDF_SUCCESS; 1160} 1161... 1162/* HdfDriverEntry implementations */ 1163static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device) 1164{ 1165 struct AcmDevice *acm = NULL; 1166 struct UsbPnpNotifyServiceInfo *info = NULL; 1167 errno_t err; 1168 1169 if (device == NULL) { 1170 HDF_LOGE("%s: device is null", __func__); 1171 return HDF_ERR_INVALID_OBJECT; 1172 } 1173 1174 acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm)); 1175 if (acm == NULL) { 1176 HDF_LOGE("%s: Alloc usb serial device failed", __func__); 1177 return HDF_FAILURE; 1178 } 1179 if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) { 1180 HDF_LOGE("%s:%d OsalMutexInit fail", __func__, __LINE__); 1181 goto ERROR; 1182 } 1183 1184 info = (struct UsbPnpNotifyServiceInfo *)device->priv; 1185 if (info != NULL) { 1186 acm->busNum = (uint8_t)info->busNum; 1187 acm->devAddr = (uint8_t)info->devNum; 1188 acm->interfaceCnt = info->interfaceLength; 1189 err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, (const void *)info->interfaceNumber, 1190 info->interfaceLength); 1191 if (err != EOK) { 1192 HDF_LOGE("%s:%d memcpy_s failed err=%d", __func__, __LINE__, err); 1193 goto LOCK_ERROR; 1194 } 1195 } else { 1196 HDF_LOGE("%s:%d info is NULL!", __func__, __LINE__); 1197 goto LOCK_ERROR; 1198 } 1199 1200 device->service = &(acm->service); 1201 device->service->Dispatch = UsbSerialDeviceDispatch; 1202 acm->device = device; 1203 HDF_LOGD("UsbSerialDriverBind=========================OK"); 1204 return HDF_SUCCESS; 1205 1206LOCK_ERROR: 1207 if (OsalMutexDestroy(&acm->lock)) { 1208 HDF_LOGE("%s:%d OsalMutexDestroy fail", __func__, __LINE__); 1209 } 1210ERROR: 1211 OsalMemFree(acm); 1212 acm = NULL; 1213 return HDF_FAILURE; 1214} 1215... 1216static int32_t UsbAllocReadRequests(struct AcmDevice *acm) 1217{ 1218 struct UsbRawFillRequestData reqData; 1219 uint32_t size = acm->dataInEp->maxPacketSize; 1220 1221 for (int32_t i = 0; i < ACM_NR; i++) { 1222 // 分配一个具有指定数目的同步传输分组描述符的传输请求 1223 acm->readReq[i] = UsbRawAllocRequest(acm->devHandle, 0, size); 1224 if (!acm->readReq[i]) { 1225 HDF_LOGE("readReq request failed\n"); 1226 return HDF_ERR_MALLOC_FAIL; 1227 } 1228 1229 reqData.endPoint = acm->dataInEp->addr; 1230 reqData.numIsoPackets = 0; 1231 reqData.callback = AcmReadBulkCallback; 1232 reqData.userData = (void *)acm; 1233 reqData.timeout = USB_CTRL_SET_TIMEOUT; 1234 reqData.length = size; 1235 // 在批量传输请求中填写所需信息 1236 int32_t ret = UsbRawFillBulkRequest(acm->readReq[i], acm->devHandle, &reqData); 1237 if (ret != HDF_SUCCESS) { 1238 HDF_LOGE("%s: FillBulkRequest failed, ret=%d\n", __func__, ret); 1239 return HDF_FAILURE; 1240 } 1241 } 1242 1243 return HDF_SUCCESS; 1244} 1245... 1246static int32_t UsbAllocNotifyRequest(struct AcmDevice *acm) 1247{ 1248 struct UsbRawFillRequestData fillRequestData; 1249 uint32_t size = acm->notifyEp->maxPacketSize; 1250 int32_t ret; 1251 // 分配一个具有指定数目的同步传输分组描述符的传输请求 1252 acm->notifyReq = UsbRawAllocRequest(acm->devHandle, 0, size); 1253 if (!acm->notifyReq) { 1254 HDF_LOGE("notifyReq request fail\n"); 1255 return HDF_ERR_MALLOC_FAIL; 1256 } 1257 1258 fillRequestData.endPoint = acm->notifyEp->addr; 1259 fillRequestData.length = size; 1260 fillRequestData.numIsoPackets = 0; 1261 fillRequestData.callback = AcmNotifyReqCallback; 1262 fillRequestData.userData = (void *)acm; 1263 fillRequestData.timeout = USB_CTRL_SET_TIMEOUT; 1264 // 在中断传输请求中填充所需的信息 1265 ret = UsbRawFillInterruptRequest(acm->notifyReq, acm->devHandle, &fillRequestData); 1266 if (ret) { 1267 HDF_LOGE("%s: FillInterruptRequest failed, ret=%d", __func__, ret); 1268 return HDF_FAILURE; 1269 } 1270 1271 return HDF_SUCCESS; 1272} 1273... 1274static int32_t UsbSerialInit(struct AcmDevice *acm) 1275{ 1276 struct UsbSession *session = NULL; 1277 UsbRawHandle *devHandle = NULL; 1278 int32_t ret; 1279 1280 if (acm->initFlag) { 1281 HDF_LOGE("%s:%d: initFlag is true", __func__, __LINE__); 1282 return HDF_SUCCESS; 1283 } 1284 // 以专家模式初始化USB DDK 1285 ret = UsbRawInit(NULL); 1286 if (ret) { 1287 HDF_LOGE("%s:%d UsbRawInit failed", __func__, __LINE__); 1288 return HDF_ERR_IO; 1289 } 1290 acm->session = session; 1291 // 打开一个USB设备对象 1292 devHandle = UsbRawOpenDevice(session, acm->busNum, acm->devAddr); 1293 if (devHandle == NULL) { 1294 HDF_LOGE("%s:%d UsbRawOpenDevice failed", __func__, __LINE__); 1295 ret = HDF_FAILURE; 1296 goto ERR_OPEN_DEVICE; 1297 } 1298 acm->devHandle = devHandle; 1299 // 获取主用设备配置、设备指针及配置描述符 1300 ret = UsbGetConfigDescriptor(devHandle, &acm->config); 1301 if (ret) { 1302 HDF_LOGE("%s:%d UsbGetConfigDescriptor failed", __func__, __LINE__); 1303 ret = HDF_FAILURE; 1304 goto ERR_GET_DESC; 1305 } 1306 ret = UsbParseConfigDescriptor(acm, acm->config); 1307 if (ret != HDF_SUCCESS) { 1308 HDF_LOGE("%s:%d UsbParseConfigDescriptor failed", __func__, __LINE__); 1309 ret = HDF_FAILURE; 1310 goto ERR_PARSE_DESC; 1311 } 1312 1313 ret = AcmWriteBufAlloc(acm); 1314 if (ret < 0) { 1315 HDF_LOGE("%s:%d AcmWriteBufAlloc failed", __func__, __LINE__); 1316 ret = HDF_FAILURE; 1317 goto ERR_ALLOC_WRITE_BUF; 1318 } 1319 ret = UsbAllocWriteRequests(acm); 1320 if (ret < 0) { 1321 HDF_LOGE("%s:%d UsbAllocWriteRequests failed", __func__, __LINE__); 1322 ret = HDF_FAILURE; 1323 goto ERR_ALLOC_WRITE_REQS; 1324 } 1325 ret = UsbAllocNotifyRequest(acm); 1326 if (ret) { 1327 HDF_LOGE("%s:%d UsbAllocNotifyRequests failed", __func__, __LINE__); 1328 goto ERR_ALLOC_NOTIFY_REQ; 1329 } 1330 ret = UsbAllocReadRequests(acm); 1331 if (ret) { 1332 HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__); 1333 goto ERR_ALLOC_READ_REQS; 1334 } 1335 ret = UsbStartIo(acm); 1336 if (ret) { 1337 HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__); 1338 goto ERR_START_IO; 1339 } 1340 1341 acm->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE); 1342 acm->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS; 1343 acm->lineCoding.bParityType = USB_CDC_NO_PARITY; 1344 acm->lineCoding.bDataBits = DATA_BITS_LENGTH; 1345 1346 ret = UsbRawSubmitRequest(acm->notifyReq); 1347 if (ret) { 1348 HDF_LOGE("%s:%d UsbRawSubmitRequest failed", __func__, __LINE__); 1349 goto ERR_SUBMIT_REQ; 1350 } 1351 1352 acm->initFlag = true; 1353 1354 HDF_LOGD("%s:%d=========================OK", __func__, __LINE__); 1355 1356 return HDF_SUCCESS; 1357 1358ERR_SUBMIT_REQ: 1359 UsbStopIo(acm); // 停止IO线程并释放所有资源 1360ERR_START_IO: 1361 UsbFreeReadRequests(acm); 1362ERR_ALLOC_READ_REQS: 1363 UsbFreeNotifyReqeust(acm); 1364ERR_ALLOC_NOTIFY_REQ: 1365 UsbFreeWriteRequests(acm); 1366ERR_ALLOC_WRITE_REQS: 1367 AcmWriteBufFree(acm); 1368ERR_ALLOC_WRITE_BUF: 1369 UsbReleaseInterfaces(acm); 1370ERR_PARSE_DESC: 1371 UsbRawFreeConfigDescriptor(acm->config); 1372 acm->config = NULL; 1373ERR_GET_DESC: 1374 (void)UsbRawCloseDevice(devHandle); // 关闭USB设备对象 1375ERR_OPEN_DEVICE: 1376 UsbRawExit(acm->session); // 退出USB DDK的专家模式 1377 1378 return ret; 1379} 1380... 1381static void UsbSerialRelease(struct AcmDevice *acm) 1382{ 1383 if (!(acm->initFlag)) { 1384 HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__); 1385 return; 1386 } 1387 1388 /* stop io thread and release all resources */ 1389 UsbStopIo(acm); 1390 if (g_syncRequest != NULL) { 1391 UsbRawFreeRequest(g_syncRequest); 1392 g_syncRequest = NULL; 1393 } 1394 UsbFreeReadRequests(acm); 1395 UsbFreeNotifyReqeust(acm); 1396 UsbFreeWriteRequests(acm); 1397 AcmWriteBufFree(acm); 1398 UsbReleaseInterfaces(acm); 1399 (void)UsbRawCloseDevice(acm->devHandle); 1400 UsbRawFreeConfigDescriptor(acm->config); 1401 acm->config = NULL; 1402 // 退出USB DDK的专家模式 1403 UsbRawExit(acm->session); 1404 1405 acm->initFlag = false; 1406} 1407 1408static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) 1409{ 1410 struct AcmDevice *acm = NULL; 1411 int32_t ret; 1412 1413 if (device == NULL) { 1414 HDF_LOGE("%s:%d device is null", __func__, __LINE__); 1415 return HDF_ERR_INVALID_OBJECT; 1416 } 1417 acm = (struct AcmDevice *)device->service; 1418 if (acm == NULL) { 1419 return HDF_ERR_INVALID_OBJECT; 1420 } 1421 OsalMutexInit(&acm->readLock); 1422 OsalMutexInit(&acm->writeLock); 1423 // 设备申请连续的内存 1424 ret = UsbSerialDeviceAlloc(acm); 1425 if (ret != HDF_SUCCESS) { 1426 HDF_LOGE("%s:%d UsbSerialDeviceAlloc failed", __func__, __LINE__); 1427 } 1428 1429 acm->initFlag = false; 1430 g_rawAcmReleaseFlag = false; 1431 HDF_LOGD("%s:%d init ok!", __func__, __LINE__); 1432 return ret; 1433} 1434 1435static void UsbSerialDriverRelease(struct HdfDeviceObject *device) 1436{ 1437 struct AcmDevice *acm = NULL; 1438 if (device == NULL) { 1439 HDF_LOGE("%s: device is null", __func__); 1440 return; 1441 } 1442 1443 acm = (struct AcmDevice *)device->service; 1444 if (acm == NULL) { 1445 HDF_LOGE("%s: acm is null", __func__); 1446 return; 1447 } 1448 1449 g_rawAcmReleaseFlag = true; 1450 1451 if (acm->initFlag) { 1452 HDF_LOGE("%s:%d UsbSerialRelease", __func__, __LINE__); 1453 UsbSerialRelease(acm); 1454 } 1455 UsbSeriaDevicelFree(acm); 1456 OsalMutexDestroy(&acm->writeLock); 1457 OsalMutexDestroy(&acm->readLock); 1458 OsalMutexDestroy(&acm->lock); 1459 OsalMemFree(acm); 1460 acm = NULL; 1461 HDF_LOGD("%s:%d exit", __func__, __LINE__); 1462} 1463 1464struct HdfDriverEntry g_usbSerialRawDriverEntry = { 1465 .moduleVersion = 1, 1466 .moduleName = "usbhost_acm_rawapi", // 驱动模块名称,必须与hcs文件中配置的名称一致 1467 .Bind = UsbSerialDriverBind, 1468 .Init = UsbSerialDriverInit, 1469 .Release = UsbSerialDriverRelease, 1470}; 1471HDF_INIT(g_usbSerialRawDriverEntry); 1472``` 1473 1474#### Device DDK API驱动开发 1475 1476USB ACM设备核心代码路径为drivers\peripheral\usb\gadget\function\acm\cdcacm.c。其使用示例如下所示,首先根据描述符创建设备,然后获取接口,打开接口,获取Pipe信息,接收Event事件,接着进行USB通信(读写等),设备卸载时候,关闭接口,停止Event接收,删除设备。 1477 14781. 创建设备。 1479 1480 ```cpp 1481 static int32_t AcmCreateFuncDevice(struct UsbAcmDevice *acm, struct DeviceResourceIface *iface) 1482 { 1483 int32_t ret; 1484 struct UsbFnDevice *fnDev = NULL; 1485 // 读取hcs文件中的udc_name节点的字符串值 1486 if (iface->GetString(acm->device->property, "udc_name", (const char **)&acm->udcName, UDC_NAME) != HDF_SUCCESS) { 1487 HDF_LOGE("%s: read udc_name failed, use default", __func__); 1488 return HDF_FAILURE; 1489 } 1490 1491 fnDev = (struct UsbFnDevice *)UsbFnGetDevice(acm->udcName); 1492 if (fnDev == NULL) { 1493 HDF_LOGE("%s: create usb function device failed", __func__); 1494 return HDF_FAILURE; 1495 } 1496 // 解析acm每一个Iface 1497 ret = AcmParseEachIface(acm, fnDev); 1498 if (ret != HDF_SUCCESS) { 1499 HDF_LOGE("%s: get pipes failed", __func__); 1500 return HDF_FAILURE; 1501 } 1502 1503 acm->fnDev = fnDev; 1504 return HDF_SUCCESS; 1505 } 1506 1507 ``` 1508 15092. 获取接口,打开接口,获取Pipe信息 1510 1511 ```cpp 1512 static int32_t AcmParseEachPipe(struct UsbAcmDevice *acm, struct UsbAcmInterface *iface) 1513 { 1514 struct UsbFnInterface *fnIface = iface->fn; 1515 for (uint32_t i = 0; i < fnIface->info.numPipes; i++) { 1516 struct UsbFnPipeInfo pipeInfo; 1517 // pipeInfo清除缓存区内容 1518 (void)memset_s(&pipeInfo, sizeof(pipeInfo), 0, sizeof(pipeInfo)); 1519 /* 获取pipe信息 */ 1520 int32_t ret = UsbFnGetInterfacePipeInfo(fnIface, i, &pipeInfo); 1521 if (ret != HDF_SUCCESS) { 1522 HDF_LOGE("%s: get pipe info error", __func__); 1523 return ret; 1524 } 1525 // PIPE的中断和管脚 1526 switch (pipeInfo.type) { 1527 case USB_PIPE_TYPE_INTERRUPT: 1528 acm->notifyPipe.id = pipeInfo.id; 1529 acm->notifyPipe.maxPacketSize = pipeInfo.maxPacketSize; 1530 acm->ctrlIface = *iface; 1531 break; 1532 case USB_PIPE_TYPE_BULK: 1533 if (pipeInfo.dir == USB_PIPE_DIRECTION_IN) { 1534 acm->dataInPipe.id = pipeInfo.id; 1535 acm->dataInPipe.maxPacketSize = pipeInfo.maxPacketSize; 1536 acm->dataIface = *iface; 1537 } else { 1538 acm->dataOutPipe.id = pipeInfo.id; 1539 acm->dataOutPipe.maxPacketSize = pipeInfo.maxPacketSize; 1540 } 1541 break; 1542 default: 1543 HDF_LOGE("%s: pipe type %d don't support", __func__, pipeInfo.type); 1544 break; 1545 } 1546 } 1547 1548 return HDF_SUCCESS; 1549 } 1550 /* 获取接口,打开接口获取handle */ 1551 static int32_t AcmParseEachIface(struct UsbAcmDevice *acm, struct UsbFnDevice *fnDev) 1552 { 1553 struct UsbFnInterface *fnIface = NULL; 1554 uint32_t i; 1555 if (fnDev == NULL) { 1556 return HDF_FAILURE; 1557 } 1558 for (i = 0; i < fnDev->numInterfaces; i++) { 1559 fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i); 1560 if (fnIface == NULL) { 1561 HDF_LOGE("%s: get interface failed", __func__); 1562 return HDF_FAILURE; 1563 } 1564 1565 if (fnIface->info.subclass == USB_DDK_CDC_SUBCLASS_ACM) { 1566 (void)AcmParseAcmIface(acm, fnIface); 1567 fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i + 1); 1568 if (fnIface == NULL) { 1569 HDF_LOGE("%s: get interface failed", __func__); 1570 return HDF_FAILURE; 1571 } 1572 (void)AcmParseAcmIface(acm, fnIface); 1573 return HDF_SUCCESS; 1574 } 1575 } 1576 return HDF_FAILURE; 1577 } 1578 ``` 1579 15803. 接收Event事件(EP0控制传输) 1581 1582 ```cpp 1583 static int32_t AcmAllocCtrlRequests(struct UsbAcmDevice *acm, int32_t num) 1584 { 1585 struct DListHead *head = &acm->ctrlPool; 1586 struct UsbFnRequest *req = NULL; 1587 struct CtrlInfo *ctrlInfo = NULL; 1588 int32_t i; 1589 1590 DListHeadInit(&acm->ctrlPool); 1591 acm->ctrlReqNum = 0; 1592 1593 for (i = 0; i < num; i++) { 1594 // 申请内存 1595 ctrlInfo = (struct CtrlInfo *)OsalMemCalloc(sizeof(*ctrlInfo)); 1596 if (ctrlInfo == NULL) { 1597 HDF_LOGE("%s: Allocate ctrlInfo failed", __func__); 1598 goto OUT; 1599 } 1600 ctrlInfo->acm = acm; 1601 req = UsbFnAllocCtrlRequest( 1602 acm->ctrlIface.handle, sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); 1603 if (req == NULL) { 1604 goto OUT; 1605 } 1606 req->complete = AcmCtrlComplete; 1607 req->context = ctrlInfo; 1608 DListInsertTail(&req->list, head); 1609 acm->ctrlReqNum++; 1610 } 1611 return HDF_SUCCESS; 1612 1613 OUT: 1614 return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS; 1615 } 1616 ``` 1617 16184. 进行USB通信(读写等) 1619 1620 ```cpp 1621 static int32_t AcmSendNotifyRequest( 1622 struct UsbAcmDevice *acm, uint8_t type, uint16_t value, const void *data, uint32_t length) 1623 { 1624 struct UsbFnRequest *req = acm->notifyReq; 1625 struct UsbCdcNotification *notify = NULL; 1626 int32_t ret; 1627 1628 if (req == NULL || req->buf == NULL) { 1629 HDF_LOGE("%s: req is null", __func__); 1630 return HDF_FAILURE; 1631 } 1632 1633 acm->notifyReq = NULL; 1634 acm->pending = false; 1635 req->length = sizeof(*notify) + length; 1636 1637 notify = (struct UsbCdcNotification *)req->buf; 1638 notify->bmRequestType = USB_DDK_DIR_IN | USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE; 1639 notify->bNotificationType = type; 1640 notify->wValue = CPU_TO_LE16(value); 1641 notify->wIndex = CPU_TO_LE16(acm->ctrlIface.fn->info.index); 1642 notify->wLength = CPU_TO_LE16(length); 1643 ret = memcpy_s((void *)(notify + 1), length, data, length); 1644 if (ret != EOK) { 1645 HDF_LOGE("%s: memcpy_s failed", __func__); 1646 return HDF_FAILURE; 1647 } 1648 1649 ret = UsbFnSubmitRequestAsync(req); 1650 if (ret != HDF_SUCCESS) { 1651 HDF_LOGE("%s: send notify request failed", __func__); 1652 acm->notifyReq = req; 1653 } 1654 1655 return ret; 1656 } 1657 ``` 1658 16595. 关闭接口,停止Event接收,删除设备 1660 1661 ```cpp 1662 static int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm) 1663 { 1664 int32_t ret; 1665 /* 关闭接口 */ 1666 (void)UsbFnInterfaceClose(acm->ctrlIface.handle); 1667 (void)UsbFnInterfaceClose(acm->dataIface.handle); 1668 /* 停止接收Event EP0控制传输 */ 1669 (void)UsbFnInterfaceStopRecvEvent(acm->ctrlIface.fn); 1670 /* 删除设备 */ 1671 ret = UsbFnDeviceRemove(acm->fnDev); 1672 if (ret != HDF_SUCCESS) { 1673 HDF_LOGE("%s: remove usb function device failed", __func__); 1674 } 1675 return ret; 1676 } 1677 static int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm) 1678 { 1679 int32_t ret = HDF_SUCCESS; 1680 if (acm->fnDev == NULL) { 1681 HDF_LOGE("%s: fnDev is null", __func__); 1682 return HDF_FAILURE; 1683 } 1684 //释放通知请求 1685 AcmFreeCtrlRequests(acm); 1686 AcmFreeNotifyRequest(acm); 1687 /* 停止接收Event EP0控制传输 */ 1688 (void)UsbFnCloseInterface(acm->ctrlIface.handle); 1689 (void)UsbFnCloseInterface(acm->dataIface.handle); 1690 (void)UsbFnStopRecvInterfaceEvent(acm->ctrlIface.fn); 1691 return ret; 1692 } 1693 ``` 1694 1695## 参考 1696 1697- 代码仓库如下: 1698 1699 **[drivers\_hdf\_core](https://gitee.com/openharmony/drivers_hdf_core)** 1700 1701 [drivers\_peripheral](https://gitee.com/openharmony/drivers_peripheral) 1702 1703 [drivers\_interface](https://gitee.com/openharmony/drivers_interface) 1704 1705- 代码路径如下: 1706 1707 USB驱动模型liteos适配://drivers/hdf_core/adapter/khdf/liteos/model/usb 1708 1709 USB DDK驱动加载实现://drivers/hdf_core/framework/model/usb 1710 1711 USB HDI服务端实现://drivers/peripheral/usb/hdi_service 1712 1713 USB HDI对外接口://out/{product_name}/gen/drivers/interface/usb/v1_0 1714 1715