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| struct UsbInterface *UsbClaimInterface(const struct<br/> UsbSession *session, uint8_t busNum, uint8_t usbAddr, <br/>uint8_t interfaceIndex) | 获取USB接口对象 |
91| UsbInterfaceHandle&nbsp;\*UsbOpenInterface(const&nbsp;struct<br/>UsbInterface&nbsp;\*interfaceObj); | 打开USB对象接口 |
92| int32_t&nbsp;UsbGetPipeInfo(const&nbsp;UsbInterfaceHandle<br/>\*interfaceHandle,&nbsp;uint8_t&nbsp;settingIndex,&nbsp;uint8_t&nbsp;pipeId,<br/>struct&nbsp;UsbPipeInfo&nbsp;\*pipeInfo); | 获取指定可选设置的管道信息 |
93| struct&nbsp;UsbRequest&nbsp;\*UsbAllocRequest(const<br/>UsbInterfaceHandle&nbsp;\*interfaceHandle,&nbsp;int32_t&nbsp;isoPackets<br/>,&nbsp;int32_t&nbsp;length); | 分配请求对象 |
94| int32_t&nbsp;UsbFillRequest(const&nbsp;struct&nbsp;UsbRequest<br/>\*request,&nbsp;const&nbsp;UsbInterfaceHandle&nbsp;\*interfaceHandle,<br/>const&nbsp;struct&nbsp;UsbRequestParams&nbsp;\*params); | 填充请求 |
95| int32_t&nbsp;UsbSubmitRequestSync(const&nbsp;struct&nbsp;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&nbsp;UsbRawInit(struct&nbsp;UsbSession&nbsp;\*\*session); | USB驱动开发工具包专家模式初始化 |
104| UsbRawHandle&nbsp;\*UsbRawOpenDevice(const&nbsp;struct<br/>UsbSession&nbsp;\*session,&nbsp;uint8_t&nbsp;busNum,&nbsp;uint8_t<br/>usbAddr); | 打开USB设备对象 |
105| int32_t&nbsp;UsbRawSendControlRequest(const&nbsp;struct<br/>UsbRawRequest&nbsp;\*request,&nbsp;const&nbsp;UsbRawHandle<br/>\*devHandle,&nbsp;const&nbsp;struct&nbsp;UsbControlRequestData<br/>\*requestData); | 执行同步控制传输 |
106| int32_t&nbsp;UsbRawSendBulkRequest(const&nbsp;struct<br/>UsbRawRequest&nbsp;\*request,&nbsp;const&nbsp;UsbRawHandle<br/>\*devHandle,&nbsp;const&nbsp;struct&nbsp;UsbRequestData<br/>\*requestData); | 执行同步批量传输 |
107| int32_t&nbsp;UsbRawSendInterruptRequest(const&nbsp;struct<br/>UsbRawRequest&nbsp;\*request,&nbsp;const&nbsp;UsbRawHandle<br/>\*devHandle,&nbsp;const&nbsp;struct&nbsp;UsbRequestData<br/>\*requestData); | 执行同步中断传输 |
108| int32_t&nbsp;UsbRawGetConfigDescriptor(const&nbsp;UsbRawDevice<br/>\*rawDev,&nbsp;uint8_t&nbsp;configIndex,&nbsp;struct<br/>UsbRawConfigDescriptor&nbsp;\*\*config); | 获取给定设备指定ID的设备配置描述符 |
109| int32_t&nbsp;UsbRawFillInterruptRequest(const&nbsp;struct&nbsp;UsbRawRequest<br/>\*request,&nbsp;const&nbsp;UsbRawHandle&nbsp;\*devHandle,&nbsp;const&nbsp;struct<br/>UsbRawFillRequestData&nbsp;\*fillData); | 填充中断传输请求所需信息 |
110| int32_t&nbsp;UsbRawFillIsoRequest(const&nbsp;struct&nbsp;UsbRawRequest<br/>\*request,&nbsp;const&nbsp;UsbRawHandle&nbsp;\*devHandle,&nbsp;const&nbsp;struct<br/>UsbRawFillRequestData&nbsp;\*fillData); | 填充同步传输(Isochronous&nbsp;Transfers)请求所需信息 |
111| int32_t&nbsp;UsbRawSubmitRequest(const&nbsp;struct&nbsp;UsbRawRequest<br/>\*request); | 提交一个传输请求 |
112| int32_t&nbsp;UsbRawCancelRequest(const&nbsp;struct&nbsp;UsbRawRequest<br/>\*request); | 取消一个传输请求 |
113| int32_t&nbsp;UsbRawHandleRequests(const&nbsp;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&nbsp;struct&nbsp;UsbFnDevice&nbsp;\*UsbFnCreateDevice(const<br/>char&nbsp;\*udcName,&nbsp;const&nbsp;struct&nbsp;UsbFnDescriptorData<br/>\*descriptor); | 创建USB设备 |
122| int32_t&nbsp;UsbFnRemoveDevice(struct&nbsp;UsbFnDevice<br/>\*fnDevice); | 删除USB设备 |
123| const&nbsp;struct&nbsp;UsbFnDevice&nbsp;\*UsbFnGetDevice(const&nbsp;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&nbsp;UsbFnStartRecvInterfaceEvent(struct<br/>UsbFnInterface&nbsp;\*interface,&nbsp;uint32_t&nbsp;eventMask,<br/>UsbFnEventCallback&nbsp;callback,&nbsp;void&nbsp;\*context); | 开始接受Event事件 |
132| int32_t&nbsp;UsbFnStopRecvInterfaceEvent(struct<br/>UsbFnInterface&nbsp;\*interface); | 停止接受Event事件 |
133| UsbFnInterfaceHandle&nbsp;UsbFnOpenInterface(struct&nbsp;UsbFnInterface&nbsp;\*interface); | 打开一个接口 |
134| int32_t&nbsp;UsbFnCloseInterface(UsbFnInterfaceHandle&nbsp;handle); | 关闭一个接口 |
135| int32_t&nbsp;UsbFnGetInterfacePipeInfo(struct&nbsp;UsbFnInterface<br/>\*interface,&nbsp;uint8_t&nbsp;pipeId,&nbsp;struct&nbsp;UsbFnPipeInfo&nbsp;\*info); | 获取管道信息 |
136| int32_t&nbsp;UsbFnSetInterfaceProp(const&nbsp;struct&nbsp;UsbFnInterface<br/>\*interface,&nbsp;const&nbsp;char&nbsp;\*name,&nbsp;const&nbsp;char&nbsp;\*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&nbsp;UsbFnRequest<br/>\*UsbFnAllocCtrlRequest(UsbFnInterfaceHandle&nbsp;handle,<br/>uint32_t&nbsp;len); | 申请一个控制请求 |
145| struct&nbsp;UsbFnRequest&nbsp;\*UsbFnAllocRequest(UsbFnInterfaceHandle&nbsp;handle,<br/>uint8_t&nbsp;pipe,&nbsp;uint32_t&nbsp;len); | 申请一个数据请求 |
146| int32_t&nbsp;UsbFnFreeRequest(struct&nbsp;UsbFnRequest&nbsp;\*req); | 释放一个请求 |
147| int32_t&nbsp;UsbFnSubmitRequestAsync(struct&nbsp;UsbFnRequest<br/>\*req); | 发送异步请求 |
148| int32_t&nbsp;UsbFnSubmitRequestSync(struct&nbsp;UsbFnRequest<br/>\*req,&nbsp;uint32_t&nbsp;timeout); | 发送同步请求 |
149| int32_t&nbsp;UsbFnCancelRequest(struct&nbsp;UsbFnRequest&nbsp;\*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