• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# USB<a name="EN-US_TOPIC_0000001228574475"></a>
2
3
4## Overview<a name="section127mcpsimp"></a>
5
6USB host development aims to provide host-related functions, including protocol encapsulation, device management, and driver installation and uninstall.
7
8USB device development aims to provide device-related functions, including device management, configuration management, and I/O management. These functions implement creation, configuration, and data communication of USB devices.
9
10The following figures show the UBS host and device driver models.
11
12**Figure 1** USB host driver model<a name="fig1649563542917"></a>
13![](figures/USB_host_driver_model.png "USB host driver model")
14
15**Figure 2** USB device driver model<a name="fig8847615103013"></a>
16![](figures/USB_device_driver_model.png "USB device driver model")
17
18The USB driver model offers the following APIs:
19
20-   The USB host Driver Development Kit (DDK) provides driver capability APIs that can be directly called in user mode. The APIs can be classified into the DDK initialization class, interface operation class, and request operation class by function. These APIs can be used to perform DDK initialization, bind/release and open/close an interface, allocate/release a request, and implement synchronous or asynchronous transfer.
21-   The USB device DDK provides device management, I/O management, and configuration management APIs, which can be used to create and delete a device, obtain/open an interface, and perform synchronous or asynchronous transfer.
22
23### Available APIs(<a name="section141mcpsimp"></a>)
24
25[Figure 1](#fig1649563542917) describes the APIs provided by the USB host driver model.
26
27**Table 1** APIs provided by the USB host driver model
28
29<a name="table11474102882612"></a>
30<table><thead align="left"><tr id="row1147413289268"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p1966391682713"><a name="p1966391682713"></a><a name="p1966391682713"></a>Header File</p>
31</th>
32<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p166313167274"><a name="p166313167274"></a><a name="p166313167274"></a>API</p>
33</th>
34<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p1066341602710"><a name="p1066341602710"></a><a name="p1066341602710"></a> Description</p>
35</th>
36</tr>
37</thead>
38<tbody><tr id="row1275799122710"><td class="cellrowborder" rowspan="16" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p4725109162716"><a name="p4725109162716"></a><a name="p4725109162716"></a>usb_ddk_interface.h</p>
39</td>
40<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p17725698274"><a name="p17725698274"></a><a name="p17725698274"></a>int32_t UsbInitHostSdk(struct UsbSession **session);</p>
41</td>
42<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p27252992712"><a name="p27252992712"></a><a name="p27252992712"></a>Initializes the USB host driver DDK.</p>
43</td>
44</tr>
45<tr id="row775779172719"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p14725149172712"><a name="p14725149172712"></a><a name="p14725149172712"></a>int32_t UsbExitHostSdk(const struct UsbSession *session);</p>
46</td>
47<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p172549192711"><a name="p172549192711"></a><a name="p172549192711"></a>Exits the USB host driver DDK.</p>
48</td>
49</tr>
50<tr id="row975769172712"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p167251791278"><a name="p167251791278"></a><a name="p167251791278"></a>const struct UsbInterface *UsbClaimInterface(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr, uint8_t interfaceIndex);</p>
51</td>
52<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p187255962716"><a name="p187255962716"></a><a name="p187255962716"></a>Obtains a USB interface.</p>
53</td>
54</tr>
55<tr id="row97577920273"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p16725497276"><a name="p16725497276"></a><a name="p16725497276"></a>int UsbReleaseInterface(const struct UsbInterface *interfaceObj);</p>
56</td>
57<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p117251894270"><a name="p117251894270"></a><a name="p117251894270"></a>Releases a USB interface.</p>
58</td>
59</tr>
60<tr id="row67574982718"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p872514915277"><a name="p872514915277"></a><a name="p872514915277"></a>int UsbAddOrRemoveInterface(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr, uint8_t interfaceIndex, UsbInterfaceStatus status);</p>
61</td>
62<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p157251914278"><a name="p157251914278"></a><a name="p157251914278"></a>Adds or removes a USB interface.</p>
63</td>
64</tr>
65<tr id="row47576942720"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p572517916275"><a name="p572517916275"></a><a name="p572517916275"></a>UsbInterfaceHandle *UsbOpenInterface(const struct UsbInterface *interfaceObj);</p>
66</td>
67<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p67254915272"><a name="p67254915272"></a><a name="p67254915272"></a>Opens a USB interface.</p>
68</td>
69</tr>
70<tr id="row197579952713"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p472514912712"><a name="p472514912712"></a><a name="p472514912712"></a>int32_t UsbCloseInterface(const UsbInterfaceHandle *interfaceHandle);</p>
71</td>
72<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p67251095276"><a name="p67251095276"></a><a name="p67251095276"></a>Closes a USB interface.</p>
73</td>
74</tr>
75<tr id="row15757894278"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p5725169192717"><a name="p5725169192717"></a><a name="p5725169192717"></a>int32_t UsbSelectInterfaceSetting(const UsbInterfaceHandle *interfaceHandle, uint8_t settingIndex, struct UsbInterface **interfaceObj);</p>
76</td>
77<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p6725109112720"><a name="p6725109112720"></a><a name="p6725109112720"></a>Sets a USB interface.</p>
78</td>
79</tr>
80<tr id="row107579932715"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p11725199182715"><a name="p11725199182715"></a><a name="p11725199182715"></a>int32_t UsbGetPipeInfo(const UsbInterfaceHandle *interfaceHandle, uint8_t settingIndex, uint8_t pipeId, struct UsbPipeInfo *pipeInfo);</p>
81</td>
82<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p107261298272"><a name="p107261298272"></a><a name="p107261298272"></a>Obtains USB pipe information.</p>
83</td>
84</tr>
85<tr id="row27577992716"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p8726890275"><a name="p8726890275"></a><a name="p8726890275"></a>int32_t UsbClearInterfaceHalt(const UsbInterfaceHandle *interfaceHandle, uint8_t pipeAddress);</p>
86</td>
87<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p177261797274"><a name="p177261797274"></a><a name="p177261797274"></a>Clears the state of the pipe with the specified index.</p>
88</td>
89</tr>
90<tr id="row1757189172714"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1726998273"><a name="p1726998273"></a><a name="p1726998273"></a>struct UsbRequest *UsbAllocRequest(const UsbInterfaceHandle *interfaceHandle, int isoPackets, int length);</p>
91</td>
92<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1272617982713"><a name="p1272617982713"></a><a name="p1272617982713"></a>Allocates a request object.</p>
93</td>
94</tr>
95<tr id="row07579911279"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p187261911279"><a name="p187261911279"></a><a name="p187261911279"></a>int UsbFreeRequest(const struct UsbRequest *request);</p>
96</td>
97<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p177271592271"><a name="p177271592271"></a><a name="p177271592271"></a>Releases a request object.</p>
98</td>
99</tr>
100<tr id="row075759142715"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3727896271"><a name="p3727896271"></a><a name="p3727896271"></a>int UsbSubmitRequestAsync(const struct UsbRequest *request);</p>
101</td>
102<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p372714942718"><a name="p372714942718"></a><a name="p372714942718"></a>Sends an asynchronous request.</p>
103</td>
104</tr>
105<tr id="row1475718919272"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1727698272"><a name="p1727698272"></a><a name="p1727698272"></a>int32_t UsbFillRequest(const struct UsbRequest *request, const UsbInterfaceHandle *interfaceHandle, const struct UsbRequestParams *params);</p>
106</td>
107<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p872713910270"><a name="p872713910270"></a><a name="p872713910270"></a>Fills in a request.</p>
108</td>
109</tr>
110<tr id="row117576932710"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p9727291278"><a name="p9727291278"></a><a name="p9727291278"></a>sint UsbCancelRequest(const struct UsbRequest *request);</p>
111</td>
112<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p37271897276"><a name="p37271897276"></a><a name="p37271897276"></a>Cancels an asynchronous request.</p>
113</td>
114</tr>
115<tr id="row1475714912715"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p2727698275"><a name="p2727698275"></a><a name="p2727698275"></a>int UsbSubmitRequestSync(const struct UsbRequest *request);</p>
116</td>
117<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p87279914277"><a name="p87279914277"></a><a name="p87279914277"></a>Sends a synchronous request.</p>
118</td>
119</tr>
120<tr id="row11756097274"><td class="cellrowborder" rowspan="27" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p12727179132710"><a name="p12727179132710"></a><a name="p12727179132710"></a>usb_raw_api.h</p>
121</td>
122<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p11727391272"><a name="p11727391272"></a><a name="p11727391272"></a>int UsbRawInit(struct UsbSession **session);</p>
123</td>
124<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1572711919272"><a name="p1572711919272"></a><a name="p1572711919272"></a>Initializes the USB raw APIs.</p>
125</td>
126</tr>
127<tr id="row1575629182713"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p372711918279"><a name="p372711918279"></a><a name="p372711918279"></a>int UsbRawExit(const struct UsbSession *session);</p>
128</td>
129<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p372710942717"><a name="p372710942717"></a><a name="p372710942717"></a>Exits the USB raw APIs.</p>
130</td>
131</tr>
132<tr id="row5756999270"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p8727291277"><a name="p8727291277"></a><a name="p8727291277"></a>UsbRawHandle *UsbRawOpenDevice(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr);</p>
133</td>
134<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1772719972717"><a name="p1772719972717"></a><a name="p1772719972717"></a>Opens a USB device.</p>
135</td>
136</tr>
137<tr id="row117561292270"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p772709122715"><a name="p772709122715"></a><a name="p772709122715"></a>int UsbRawCloseDevice(const UsbRawHandle *devHandle);</p>
138</td>
139<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1372715902711"><a name="p1372715902711"></a><a name="p1372715902711"></a>Closes a USB device.</p>
140</td>
141</tr>
142<tr id="row775689182714"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p197272918272"><a name="p197272918272"></a><a name="p197272918272"></a>int UsbRawSendControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbControlRequestData *requestData);</p>
143</td>
144<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p272715932717"><a name="p272715932717"></a><a name="p272715932717"></a>Performs a control transfer synchronously.</p>
145</td>
146</tr>
147<tr id="row3756179132714"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1727296276"><a name="p1727296276"></a><a name="p1727296276"></a>int UsbRawSendBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData);</p>
148</td>
149<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p872789162713"><a name="p872789162713"></a><a name="p872789162713"></a>Performs a bulk transfer synchronously.</p>
150</td>
151</tr>
152<tr id="row27568916276"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1072719992711"><a name="p1072719992711"></a><a name="p1072719992711"></a>int UsbRawSendInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData);</p>
153</td>
154<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p117271895271"><a name="p117271895271"></a><a name="p117271895271"></a>Performs an interrupt transfer synchronously.</p>
155</td>
156</tr>
157<tr id="row14756149112710"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p772711917274"><a name="p772711917274"></a><a name="p772711917274"></a>int UsbRawGetConfigDescriptor(const UsbRawDevice *rawDev, uint8_t configIndex, struct UsbRawConfigDescriptor **config);</p>
158</td>
159<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p472714912710"><a name="p472714912710"></a><a name="p472714912710"></a>Obtains the configuration descriptor of a device.</p>
160</td>
161</tr>
162<tr id="row1775614902711"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p37277942718"><a name="p37277942718"></a><a name="p37277942718"></a>void UsbRawFreeConfigDescriptor(const struct UsbRawConfigDescriptor *config);</p>
163</td>
164<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p772759162711"><a name="p772759162711"></a><a name="p772759162711"></a>Releases the memory space of a configuration descriptor.</p>
165</td>
166</tr>
167<tr id="row9756119182711"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3727699274"><a name="p3727699274"></a><a name="p3727699274"></a>int UsbRawGetConfiguration(const UsbRawHandle *devHandle, int *config);</p>
168</td>
169<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p13728109192717"><a name="p13728109192717"></a><a name="p13728109192717"></a>Obtains the configuration in use.</p>
170</td>
171</tr>
172<tr id="row37567922714"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1872849162718"><a name="p1872849162718"></a><a name="p1872849162718"></a>int UsbRawSetConfiguration(const UsbRawHandle *devHandle, int config);</p>
173</td>
174<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p87280914277"><a name="p87280914277"></a><a name="p87280914277"></a>Sets the configuration in use.</p>
175</td>
176</tr>
177<tr id="row1775612982711"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p127283902712"><a name="p127283902712"></a><a name="p127283902712"></a>int UsbRawGetDescriptor(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawDescriptorParam *param, const unsigned char *data);</p>
178</td>
179<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p17728209122710"><a name="p17728209122710"></a><a name="p17728209122710"></a>Obtains descriptor information.</p>
180</td>
181</tr>
182<tr id="row97564992719"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1672849122712"><a name="p1672849122712"></a><a name="p1672849122712"></a>UsbRawDevice *UsbRawGetDevice(const UsbRawHandle *devHandle);</p>
183</td>
184<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p472879202719"><a name="p472879202719"></a><a name="p472879202719"></a>Obtains the device pointer based on the device handle.</p>
185</td>
186</tr>
187<tr id="row1075612922718"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p172814982715"><a name="p172814982715"></a><a name="p172814982715"></a>int UsbRawGetDeviceDescriptor(const UsbRawDevice *rawDev, struct UsbDeviceDescriptor *desc);</p>
188</td>
189<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p8728139172715"><a name="p8728139172715"></a><a name="p8728139172715"></a>Obtains the device descriptor of the specified USB device.</p>
190</td>
191</tr>
192<tr id="row117561919273"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p072820912714"><a name="p072820912714"></a><a name="p072820912714"></a>int UsbRawClaimInterface(const UsbRawHandle *devHandle, int interfaceNumber);</p>
193</td>
194<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p972817914279"><a name="p972817914279"></a><a name="p972817914279"></a>Declares the interface on the specified device handle.</p>
195</td>
196</tr>
197<tr id="row87561920275"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p2728191276"><a name="p2728191276"></a><a name="p2728191276"></a>int UsbRawReleaseInterface(const UsbRawHandle *devHandle, int interfaceNumber);</p>
198</td>
199<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p8728159102710"><a name="p8728159102710"></a><a name="p8728159102710"></a>Releases the previously declared interface.</p>
200</td>
201</tr>
202<tr id="row375679152710"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p137281192274"><a name="p137281192274"></a><a name="p137281192274"></a>int UsbRawResetDevice(const UsbRawHandle *devHandle);</p>
203</td>
204<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p107281992272"><a name="p107281992272"></a><a name="p107281992272"></a>Resets a device.</p>
205</td>
206</tr>
207<tr id="row14756109152719"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p137288914273"><a name="p137288914273"></a><a name="p137288914273"></a>struct UsbRawRequest *UsbRawAllocRequest(const UsbRawHandle *devHandle, int isoPackets, int length);</p>
208</td>
209<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p27281797274"><a name="p27281797274"></a><a name="p27281797274"></a>Allocates a transfer request with the specified number of sync packet descriptors.</p>
210</td>
211</tr>
212<tr id="row07560932714"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p2072810912713"><a name="p2072810912713"></a><a name="p2072810912713"></a>int UsbRawFreeRequest(const struct UsbRawRequest *request);</p>
213</td>
214<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p17281917278"><a name="p17281917278"></a><a name="p17281917278"></a>Releases the previously allocated transfer request.</p>
215</td>
216</tr>
217<tr id="row1775615952717"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1872810915274"><a name="p1872810915274"></a><a name="p1872810915274"></a>int UsbRawFillBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);</p>
218</td>
219<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p117281090271"><a name="p117281090271"></a><a name="p117281090271"></a>Fills in a bulk transfer request.</p>
220</td>
221</tr>
222<tr id="row675659172716"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1272820962719"><a name="p1272820962719"></a><a name="p1272820962719"></a>int UsbRawFillControlSetup(const unsigned char *setup, const struct UsbControlRequestData *requestData);</p>
223</td>
224<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p177281299278"><a name="p177281299278"></a><a name="p177281299278"></a>Fills in a control setup packet.</p>
225</td>
226</tr>
227<tr id="row97563912271"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1372817914277"><a name="p1372817914277"></a><a name="p1372817914277"></a>int UsbRawFillControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);</p>
228</td>
229<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1372815952715"><a name="p1372815952715"></a><a name="p1372815952715"></a>Fills in a control transfer request.</p>
230</td>
231</tr>
232<tr id="row117561932712"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p172899112714"><a name="p172899112714"></a><a name="p172899112714"></a>int UsbRawFillInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);</p>
233</td>
234<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p19728092271"><a name="p19728092271"></a><a name="p19728092271"></a>Fills in an interrupt transfer request.</p>
235</td>
236</tr>
237<tr id="row075617917271"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p072829132714"><a name="p072829132714"></a><a name="p072829132714"></a>int UsbRawFillIsoRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);</p>
238</td>
239<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p107281913275"><a name="p107281913275"></a><a name="p107281913275"></a>Fills in an isochronous transfer request.</p>
240</td>
241</tr>
242<tr id="row87564917271"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p16728129152712"><a name="p16728129152712"></a><a name="p16728129152712"></a>int UsbRawSubmitRequest(const struct UsbRawRequest *request);</p>
243</td>
244<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p187299922718"><a name="p187299922718"></a><a name="p187299922718"></a>Submits a transfer request.</p>
245</td>
246</tr>
247<tr id="row975659192711"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p15729099278"><a name="p15729099278"></a><a name="p15729099278"></a>int UsbRawCancelRequest(const struct UsbRawRequest *request);</p>
248</td>
249<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p872912911274"><a name="p872912911274"></a><a name="p872912911274"></a>Cancels a transfer request.</p>
250</td>
251</tr>
252<tr id="row1675519932712"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1472929182710"><a name="p1472929182710"></a><a name="p1472929182710"></a>int UsbRawHandleRequests(const UsbRawHandle *devHandle);</p>
253</td>
254<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p572929102710"><a name="p572929102710"></a><a name="p572929102710"></a>Handles a transfer request event.</p>
255</td>
256</tr>
257</tbody>
258</table>
259
260[Figure 2](#fig8847615103013) describes the APIs provided by the USB device driver model.
261
262**Table 2** APIs provided by the USB device driver model
263
264<a name="table1172315391272"></a>
265<table><thead align="left"><tr id="row207231239162719"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p1472363915270"><a name="p1472363915270"></a><a name="p1472363915270"></a>Header File</p>
266</th>
267<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p672313910271"><a name="p672313910271"></a><a name="p672313910271"></a>API</p>
268</th>
269<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p524922814284"><a name="p524922814284"></a><a name="p524922814284"></a>Description</p>
270</th>
271</tr>
272</thead>
273<tbody><tr id="row1526165392716"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p143125320275"><a name="p143125320275"></a><a name="p143125320275"></a>usbfn_device.h</p>
274</td>
275<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p1644533274"><a name="p1644533274"></a><a name="p1644533274"></a>const struct UsbFnDevice *UsbFnCreateDevice(const char *udcName, const struct UsbFnDescriptorData *descriptor);</p>
276</td>
277<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p241853152716"><a name="p241853152716"></a><a name="p241853152716"></a>Creates a USB device.</p>
278</td>
279</tr>
280<tr id="row11261453112717"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p741553102715"><a name="p741553102715"></a><a name="p741553102715"></a>int UsbFnRemoveDevice(struct UsbFnDevice *fnDevice);</p>
281</td>
282<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p5435318271"><a name="p5435318271"></a><a name="p5435318271"></a>Deletes a USB device.</p>
283</td>
284</tr>
285<tr id="row126205320278"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p9425362716"><a name="p9425362716"></a><a name="p9425362716"></a>const struct UsbFnDevice *UsbFnGetDevice(const char *udcName);</p>
286</td>
287<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p54135392719"><a name="p54135392719"></a><a name="p54135392719"></a>Obtains a USB device.</p>
288</td>
289</tr>
290<tr id="row326125314279"><td class="cellrowborder" rowspan="6" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p144653142719"><a name="p144653142719"></a><a name="p144653142719"></a>usbfn_interface.h</p>
291</td>
292<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p941453112713"><a name="p941453112713"></a><a name="p941453112713"></a>int UsbFnStartRecvInterfaceEvent(struct UsbFnInterface *interface, uint32_t eventMask, UsbFnEventCallback callback, void *context);</p>
293</td>
294<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1341530277"><a name="p1341530277"></a><a name="p1341530277"></a>Starts receiving events.</p>
295</td>
296</tr>
297<tr id="row172613534273"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p124153152713"><a name="p124153152713"></a><a name="p124153152713"></a>int UsbFnStopRecvInterfaceEvent(struct UsbFnInterface *interface);</p>
298</td>
299<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1441532271"><a name="p1441532271"></a><a name="p1441532271"></a>Stops receiving events.</p>
300</td>
301</tr>
302<tr id="row1026653142717"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p24185317276"><a name="p24185317276"></a><a name="p24185317276"></a>UsbFnInterfaceHandle UsbFnOpenInterface(struct UsbFnInterface *interface);</p>
303</td>
304<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p142537274"><a name="p142537274"></a><a name="p142537274"></a>Opens an interface.</p>
305</td>
306</tr>
307<tr id="row226195362720"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p114175382715"><a name="p114175382715"></a><a name="p114175382715"></a>int UsbFnCloseInterface(UsbFnInterfaceHandle handle);</p>
308</td>
309<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p124453132715"><a name="p124453132715"></a><a name="p124453132715"></a>Closes an interface.</p>
310</td>
311</tr>
312<tr id="row12605311277"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3565313278"><a name="p3565313278"></a><a name="p3565313278"></a>int UsbFnGetInterfacePipeInfo(struct UsbFnInterface *interface, uint8_t pipeId, struct UsbFnPipeInfo *info);</p>
313</td>
314<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p054536274"><a name="p054536274"></a><a name="p054536274"></a>Obtains pipe information.</p>
315</td>
316</tr>
317<tr id="row19261153132716"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1958532275"><a name="p1958532275"></a><a name="p1958532275"></a>int UsbFnSetInterfaceProp(const struct UsbFnInterface *interface, const char *name, const char *value);</p>
318</td>
319<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p9516538277"><a name="p9516538277"></a><a name="p9516538277"></a>Sets custom properties.</p>
320</td>
321</tr>
322<tr id="row3261853202716"><td class="cellrowborder" rowspan="8" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p65453192711"><a name="p65453192711"></a><a name="p65453192711"></a>usbfn_request.h</p>
323</td>
324<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p3520539276"><a name="p3520539276"></a><a name="p3520539276"></a>struct UsbFnRequest *UsbFnAllocCtrlRequest(UsbFnInterfaceHandle handle, uint32_t len);</p>
325</td>
326<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p5514538278"><a name="p5514538278"></a><a name="p5514538278"></a>Applies for a control transfer request.</p>
327</td>
328</tr>
329<tr id="row18261253112716"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p85115312277"><a name="p85115312277"></a><a name="p85115312277"></a>struct UsbFnRequest *UsbFnAllocRequest(UsbFnInterfaceHandle handle, uint8_t pipe, uint32_t len);</p>
330</td>
331<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p105105342716"><a name="p105105342716"></a><a name="p105105342716"></a>Applies for a data request.</p>
332</td>
333</tr>
334<tr id="row82665320272"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1461538279"><a name="p1461538279"></a><a name="p1461538279"></a>int UsbFnFreeRequest(struct UsbFnRequest *req);</p>
335</td>
336<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p26165372718"><a name="p26165372718"></a><a name="p26165372718"></a>Releases a request.</p>
337</td>
338</tr>
339<tr id="row162610537275"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p261653192714"><a name="p261653192714"></a><a name="p261653192714"></a>int UsbFnSubmitRequestAsync(struct UsbFnRequest *req);</p>
340</td>
341<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p361253112718"><a name="p361253112718"></a><a name="p361253112718"></a>Sends an asynchronous request.</p>
342</td>
343</tr>
344<tr id="row1326253122711"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p4611536275"><a name="p4611536275"></a><a name="p4611536275"></a>int UsbFnSubmitRequestSync(struct UsbFnRequest *req, uint32_t timeout);</p>
345</td>
346<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p06853112710"><a name="p06853112710"></a><a name="p06853112710"></a>Sends a synchronous request.</p>
347</td>
348</tr>
349<tr id="row15265539272"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p177453102712"><a name="p177453102712"></a><a name="p177453102712"></a>int UsbFnCancelRequest(struct UsbFnRequest *req);</p>
350</td>
351<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p13725312275"><a name="p13725312275"></a><a name="p13725312275"></a>Cancels a request.</p>
352</td>
353</tr>
354</tbody>
355</table>
356
357## Development Guidelines<a name="section581mcpsimp"></a>
358
359The USB driver is developed based on the Hardware Driver Foundation (HDF), platform, and Operating System Abstraction Layer (OSAL) APIs. A unified driver model is provided for USB devices, irrespective of the operating system and chip architecture. This document uses a serial port as an example to describe how to develop drivers for the USB host and USB device.
360
361### How to Develop<a name="section583mcpsimp"></a>
362
363### Developing Driver Using Host DDK APIs<a name="section584mcpsimp"></a>
364
3651.  Configure the driver mapping table.
3662.  Initialize the USB host DDK.
3673.  Obtain a **UsbInterface** object.
3684.  Open the **UsbInterface** object to obtain the **UsbInterfaceHandle** object.
3695.  Obtain pipe information of the specified **pipeIndex** based on the **UsbInterfaceHandle** object.
3706.  Allocate an I/O request for the **UsbInterfaceHandle** object.
3717.  Fill in the I/O request based on the input parameters.
3728.  Submit the I/O request in synchronous or asynchronous mode.
373
374### Developing Driver Using Host Raw APIs<a name="section594mcpsimp"></a>
375
3761.  Configure the driver mapping table.
3772.  Initialize the host raw data, open the USB device, obtain the descriptor, and then obtain interface and endpoint information based on the descriptor.
3783.  Allocate a request and fill in the request based on the transfer type.
3794.  Submit the I/O request in synchronous or asynchronous mode.
380
381### Developing Driver Using Device DDK APIs<a name="section600mcpsimp"></a>
382
3831.  Construct a descriptor.
3842.  Instantiate a USB device using the descriptor constructed.
3853.  Call **UsbFnDeviceGetInterface** to obtain an interface, call **UsbFnInterfaceGetPipeInfo** to obtain pipe information based on the interface, call **UsbFnInterfaceOpen** to open the interface to obtain the handle, and call **UsbFnRequestAlloc** to obtain the request based on the handle and pipe ID.
3864.  Call **UsbFnInterfaceStartRecvEvent** to receive events such as Enable and Setup, and respond to the events in **UsbFnEventCallback**.
3875.  Send and receive data in synchronous or asynchronous mode.
388
389## Development Examples<a name="section607mcpsimp"></a>
390
391The following examples help you better understand the development of the USB serial port driver.
392
393### Developing Driver Using Host DDK APIs<a name="section609mcpsimp"></a>
394
395```
396root {
397    module = "usb_pnp_device";
398    usb_pnp_config {
399        match_attr = "usb_pnp_match";
400        usb_pnp_device_id = "UsbPnpDeviceId";
401        UsbPnpDeviceId {
402            idTableList = [
403                "host_acm_table"
404            ];
405            host_acm_table {
406                // Driver module name, which must be the same as the value of moduleName in the driver entry structure.
407                moduleName = "usbhost_acm";
408                // Service name of the driver, which must be unique.
409                serviceName = "usbhost_acm_pnp_service";
410                // Keyword for matching private driver data.
411                deviceMatchAttr = "usbhost_acm_pnp_matchAttr";
412                // Data length starting from this field, in bytes.
413                length = 21;
414                // USB driver matching rule: vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber.
415                matchFlag = 0x0303;
416                // Vendor ID.
417                vendorId = 0x12D1;
418                // Product ID.
419                productId = 0x5000;
420                // The least significant 16 bits of the device sequence number.
421                bcdDeviceLow = 0x0000;
422                // The most significant 16 bits of the device sequence number.
423                 bcdDeviceHigh = 0x0000;
424                // Device class code allocated by the USB.
425                deviceClass = 0;
426                // Child class code allocated by the USB.
427                deviceSubClass = 0;
428                // Device protocol code allocated by the USB.
429                deviceProtocol = 0;
430                // Interface type. You can enter multiple types as needed.
431                interfaceClass = [0];
432                // Interface subtype. You can enter multiple subtypes as needed.
433                interfaceSubClass = [2, 0];
434                // Protocol that the interface complies with. You can enter multiple protocols as needed.
435                interfaceProtocol = [1, 2];
436                // Interface number. You can enter multiple interface numbers as needed.
437                interfaceNumber = [2, 3];
438            }
439        }
440    }
441}
442
443#include "usb_serial.h"
444#include "hdf_base.h"
445#include "hdf_log.h"
446#include "osal_mem.h"
447#include "osal_time.h"
448#include "securec.h"
449#include "usb_ddk_interface.h"
450#include "hdf_usb_pnp_manage.h"
451
452#define HDF_LOG_TAG USB_HOST_ACM
453#define STR_LEN     512
454
455static struct UsbRequest *g_syncRequest = NULL;
456static struct UsbRequest *g_ctrlCmdRequest = NULL;
457static bool g_acmReleaseFlag = false;
458static uint8_t *g_acmReadBuffer = NULL;
459...
460static int SerialCtrlMsg(struct AcmDevice *acm, uint8_t request,
461    uint16_t value, void *buf, uint16_t len)
462{
463    int ret;
464    uint16_t index = acm->intPipe->interfaceId;
465    struct UsbControlParams controlParams;
466    struct UsbRequestParams params;
467    if (acm == NULL || buf == NULL) {
468        HDF_LOGE("%s:invalid param", __func__);
469        return HDF_ERR_IO;
470    }
471    if (acm->ctrlReq == NULL) {
472        acm->ctrlReq = UsbAllocRequest(acm->ctrDevHandle, 0, len);
473        if (acm->ctrlReq == NULL) {
474            HDF_LOGE("%s: UsbAllocRequest failed", __func__);
475            return HDF_ERR_IO;
476        }
477    }
478
479    controlParams.request = request;
480    controlParams.target = USB_REQUEST_TARGET_INTERFACE;
481    controlParams.reqType = USB_REQUEST_TYPE_CLASS;
482    controlParams.directon = USB_REQUEST_DIR_TO_DEVICE;
483    controlParams.value = value;
484    controlParams.index = index;
485    controlParams.data = buf;
486    controlParams.size = len;
487
488    params.interfaceId = USB_CTRL_INTERFACE_ID;
489    params.pipeAddress = acm->ctrPipe->pipeAddress;
490    params.pipeId = acm->ctrPipe->pipeId;
491    params.requestType = USB_REQUEST_PARAMS_CTRL_TYPE;
492    params.timeout = USB_CTRL_SET_TIMEOUT;
493    params.ctrlReq = UsbControlSetUp(&controlParams);
494    ret = UsbFillRequest(acm->ctrlReq, acm->ctrDevHandle, &params);
495    if (HDF_SUCCESS != ret) {
496        HDF_LOGE("%s: failed, ret=%d ", __func__, ret);
497        return ret;
498    }
499    ret = UsbSubmitRequestSync(acm->ctrlReq);    // Send an I/O request synchronously.
500    if (HDF_SUCCESS != ret) {
501        HDF_LOGE("UsbSubmitRequestSync failed, ret=%d ", ret);
502        return ret;
503    }
504    if (!acm->ctrlReq->compInfo.status) {
505        HDF_LOGE("%s status=%d ", __func__, acm->ctrlReq->compInfo.status);
506    }
507    return HDF_SUCCESS;
508}
509...
510static struct UsbInterface *GetUsbInterfaceById(const struct AcmDevice *acm,
511    uint8_t interfaceIndex)
512{
513    struct UsbInterface *tmpIf = NULL;
514    tmpIf = (struct UsbInterface *)UsbClaimInterface(acm->session, acm->busNum,
515            acm->devAddr, interfaceIndex); // Obtain the UsbInterface object.
516    return tmpIf;
517}
518...
519static struct UsbPipeInfo *EnumePipe(const struct AcmDevice *acm,
520    uint8_t interfaceIndex, UsbPipeType pipeType, UsbPipeDirection pipeDirection)
521{
522    uint8_t i;
523    int ret;
524    struct UsbInterfaceInfo *info = NULL;
525    UsbInterfaceHandle *interfaceHandle = NULL;
526    if (pipeType == USB_PIPE_TYPE_CONTROL)
527    {
528        info = &acm->ctrIface->info;
529        interfaceHandle = acm->ctrDevHandle;
530    }
531    else
532    {
533        info = &acm->iface[interfaceIndex]->info;
534        interfaceHandle = InterfaceIdToHandle(acm, info->interfaceIndex);
535    }
536
537    for (i = 0;  i <= info->pipeNum; i++) {
538        struct UsbPipeInfo p;
539        ret = UsbGetPipeInfo(interfaceHandle, info->curAltSetting, i, &p);// Obtain information about the pipe with index i.
540        if (ret < 0) {
541            continue;
542        }
543        if ((p.pipeDirection == pipeDirection) && (p.pipeType == pipeType)) {
544            struct UsbPipeInfo *pi = OsalMemCalloc(sizeof(*pi));
545            if (pi == NULL) {
546                HDF_LOGE("%s: Alloc pipe failed", __func__);
547                return NULL;
548            }
549            p.interfaceId = info->interfaceIndex;
550            *pi = p;
551            return pi;
552        }
553    }
554    return NULL;
555}
556
557static struct UsbPipeInfo *GetPipe(const struct AcmDevice *acm,
558    UsbPipeType pipeType, UsbPipeDirection pipeDirection)
559{
560    uint8_t i;
561    if (acm == NULL) {
562        HDF_LOGE("%s: invalid params", __func__);
563        return NULL;
564    }
565    for (i = 0; i < acm->interfaceCnt; i++) {
566        struct UsbPipeInfo *p = NULL;
567        if (!acm->iface[i]) {
568            continue;
569        }
570        p = EnumePipe(acm, i, pipeType, pipeDirection);
571        if (p == NULL) {
572            continue;
573        }
574        return p;
575    }
576    return NULL;
577}
578
579/* HdfDriverEntry implementations */
580static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device)
581{
582    struct UsbPnpNotifyServiceInfo *info = NULL;
583    errno_t err;
584    struct AcmDevice *acm = NULL;
585    if (device == NULL) {
586        HDF_LOGE("%s: device is null", __func__);
587        return HDF_ERR_INVALID_OBJECT;
588    }
589    acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm));
590    if (acm == NULL) {
591        HDF_LOGE("%s: Alloc usb serial device failed", __func__);
592        return HDF_FAILURE;
593    }
594    if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
595        HDF_LOGE("%s:%d OsalMutexInit failed", __func__, __LINE__);
596        goto error;
597    }
598    info = (struct UsbPnpNotifyServiceInfo *)device->priv;
599    if (info != NULL) {
600        HDF_LOGD("%s:%d busNum=%d,devAddr=%d,interfaceLength=%d",
601            __func__, __LINE__, info->busNum, info->devNum, info->interfaceLength);
602        acm->busNum = info->busNum;
603        acm->devAddr = info->devNum;
604        acm->interfaceCnt = info->interfaceLength;
605        err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES,
606              (const void*)info->interfaceNumber, info->interfaceLength);
607        if (err != EOK) {
608            HDF_LOGE("%s:%d memcpy_s failed err=%d",
609                __func__, __LINE__, err);
610            goto lock_error;
611        }
612    } else {
613        HDF_LOGE("%s:%d info is NULL!", __func__, __LINE__);
614        goto lock_error;
615    }
616    acm->device  = device;
617    device->service = &(acm->service);
618    acm->device->service->Dispatch = UsbSerialDeviceDispatch;
619    HDF_LOGD("UsbSerialDriverBind=========================OK");
620    return HDF_SUCCESS;
621
622lock_error:
623    if (OsalMutexDestroy(&acm->lock)) {
624        HDF_LOGE("%s:%d OsalMutexDestroy failed", __func__, __LINE__);
625    }
626error:
627    OsalMemFree(acm);
628    acm = NULL;
629    return HDF_FAILURE;
630}
631...
632static int AcmAllocReadRequests(struct AcmDevice *acm)
633{
634    int ret;
635    struct UsbRequestParams readParams;
636    for (int i = 0; i < ACM_NR; i++) {
637        acm->readReq[i] = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), 0, acm->readSize);    // Allocate the readReq I/O request to be sent.
638        if (!acm->readReq[i]) {
639            HDF_LOGE("readReq request failed");
640            goto error;
641        }
642        readParams.userData = (void *)acm;
643        readParams.pipeAddress = acm->dataInPipe->pipeAddress;
644        readParams.pipeId = acm->dataInPipe->pipeId;
645        readParams.interfaceId = acm->dataInPipe->interfaceId;
646        readParams.callback = AcmReadBulk;
647        readParams.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
648        readParams.timeout = USB_CTRL_SET_TIMEOUT;
649        readParams.dataReq.numIsoPackets = 0;
650        readParams.dataReq.directon = (acm->dataInPipe->pipeDirection >> USB_PIPE_DIR_OFFSET) & 0x1;
651        readParams.dataReq.length = acm->readSize;
652        ret = UsbFillRequest(acm->readReq[i], InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), &readParams);    // Fills in the readReq object to be sent.
653        if (HDF_SUCCESS != ret) {
654            HDF_LOGE("%s: UsbFillRequest failed, ret=%d n", __func__, ret);
655            goto error;
656        }
657    }
658    return HDF_SUCCESS;
659
660error:
661    AcmFreeReadRequests(acm);
662    return HDF_ERR_MALLOC_FAIL;
663}
664
665static int AcmAllocNotifyRequest(struct AcmDevice *acm)
666{
667    int ret;
668    struct UsbRequestParams intParams = {};
669    acm->notifyReq = UsbAllocRequest(InterfaceIdToHandle(acm, acm->intPipe->interfaceId), 0, acm->intSize);    // Allocate the interrupt I/O request object to be sent.
670    if (!acm->notifyReq) {
671        HDF_LOGE("notifyReq request failed");
672        return HDF_ERR_MALLOC_FAIL;
673    }
674    intParams.userData = (void *)acm;
675    intParams.pipeAddress = acm->intPipe->pipeAddress;
676    intParams.pipeId = acm->intPipe->pipeId;
677    intParams.interfaceId = acm->intPipe->interfaceId;
678    intParams.callback = AcmCtrlIrq;
679    intParams.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
680    intParams.timeout = USB_CTRL_SET_TIMEOUT;
681    intParams.dataReq.numIsoPackets = 0;
682    intParams.dataReq.directon = (acm->intPipe->pipeDirection >> USB_PIPE_DIR_OFFSET) & DIRECTION_MASK;
683    intParams.dataReq.length = acm->intSize;
684    ret = UsbFillRequest(acm->notifyReq, InterfaceIdToHandle(acm, acm->intPipe->interfaceId), &intParams);    // Fill in the interrupt I/O request.
685    if (HDF_SUCCESS != ret) {
686        HDF_LOGE("%s: UsbFillRequest failed, ret=%d n", __func__, ret);
687        goto error;
688    }
689    return HDF_SUCCESS;
690
691error:
692    AcmFreeNotifyReqeust(acm);
693    return ret;
694}
695
696static void AcmReleaseInterfaces(struct AcmDevice *acm)
697{
698    for (int i = 0; i < acm->interfaceCnt; i++) {
699        if (acm->iface[i]) {
700            UsbReleaseInterface(acm->iface[i]);
701            acm->iface[i] = NULL;
702        }
703    }
704    if (acm->ctrIface) {
705        UsbReleaseInterface(acm->ctrIface);
706        acm->ctrIface = NULL;
707    }
708}
709
710static int32_t AcmClaimInterfaces(struct AcmDevice *acm)
711{
712    for (int i = 0; i < acm->interfaceCnt; i++) {
713        acm->iface[i] = GetUsbInterfaceById((const struct AcmDevice *)acm, acm->interfaceIndex[i]);    // Obtain the UsbInterface object.
714        if (acm->iface[i] == NULL) {
715            HDF_LOGE("%s: interface%d is null", __func__, acm->interfaceIndex[i]);
716            goto error;
717        }
718    }
719
720    acm->ctrIface = GetUsbInterfaceById((const struct AcmDevice *)acm, USB_CTRL_INTERFACE_ID);     // Obtain the UsbInterface object corresponding to the control interface.
721    if (acm->ctrIface == NULL) {
722        HDF_LOGE("%s: GetUsbInterfaceById null", __func__);
723        goto error;
724    }
725
726    return HDF_SUCCESS;
727
728 error:
729    AcmReleaseInterfaces(acm);
730    return HDF_FAILURE;
731}
732
733static void AcmCloseInterfaces(struct AcmDevice *acm)
734{
735    for (int i = 0; i < acm->interfaceCnt; i++) {
736        if (acm->devHandle[i]) {
737            UsbCloseInterface(acm->devHandle[i]);
738            acm->devHandle[i] = NULL;
739        }
740    }
741    if (acm->ctrDevHandle) {
742        UsbCloseInterface(acm->ctrDevHandle);
743        acm->ctrDevHandle = NULL;
744    }
745}
746
747static int32_t AcmOpenInterfaces(struct AcmDevice *acm)
748{
749    for (int i = 0; i < acm->interfaceCnt; i++) {
750        if (acm->iface[i]) {
751            acm->devHandle[i] = UsbOpenInterface(acm->iface[i]);    // Open the UsbInterface object obtained.
752            if (acm->devHandle[i] == NULL) {
753                HDF_LOGE("%s: UsbOpenInterface null", __func__);
754                goto error;
755            }
756        }
757    }
758    acm->ctrDevHandle = UsbOpenInterface(acm->ctrIface);
759    if (acm->ctrDevHandle == NULL) {
760        HDF_LOGE("%s: ctrDevHandle UsbOpenInterface null", __func__);
761        goto error;
762    }
763
764    return HDF_SUCCESS;
765
766error:
767    AcmCloseInterfaces(acm);
768    return HDF_FAILURE;
769}
770
771static int32_t AcmGetPipes(struct AcmDevice *acm)
772{
773    acm->dataInPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_IN);// Obtain pipe information of dataInPipe.
774    if (acm->dataInPipe == NULL) {
775        HDF_LOGE("dataInPipe is NULL");
776        goto error;
777    }
778
779    acm->dataOutPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_OUT); // Obtain pipe information of dataOutPipe.
780    if (acm->dataOutPipe == NULL) {
781        HDF_LOGE("dataOutPipe is NULL");
782        goto error;
783    }
784
785    acm->ctrPipe = EnumePipe(acm, acm->ctrIface->info.interfaceIndex, USB_PIPE_TYPE_CONTROL, USB_PIPE_DIRECTION_OUT);    // Obtain pipe information of the control pipe.
786    if (acm->ctrPipe == NULL) {
787        HDF_LOGE("ctrPipe is NULL");
788        goto error;
789    }
790
791    acm->intPipe = GetPipe(acm, USB_PIPE_TYPE_INTERRUPT, USB_PIPE_DIRECTION_IN); // Obtain pipe information of the interrupt pipe.
792    if (acm->intPipe == NULL) {
793        HDF_LOGE("intPipe is NULL");
794        goto error;
795    }
796
797    acm->readSize  = acm->dataInPipe->maxPacketSize;
798    acm->writeSize = acm->dataOutPipe->maxPacketSize;
799    acm->ctrlSize  = acm->ctrPipe->maxPacketSize;
800    acm->intSize   = acm->intPipe->maxPacketSize;
801
802    return HDF_SUCCESS;
803
804error:
805    AcmFreePipes(acm);
806    return HDF_FAILURE;
807}
808
809static void AcmFreeRequests(struct AcmDevice *acm)
810{
811    if (g_syncRequest != NULL) {
812        UsbFreeRequest(g_syncRequest);
813        g_syncRequest = NULL;
814    }
815    AcmFreeReadRequests(acm);
816    AcmFreeNotifyReqeust(acm);
817    AcmFreeWriteRequests(acm);
818    AcmWriteBufFree(acm);
819}
820
821static int32_t AcmAllocRequests(struct AcmDevice *acm)
822{
823    int32_t ret;
824
825    if (AcmWriteBufAlloc(acm) < 0) {
826        HDF_LOGE("%s: AcmWriteBufAlloc failed", __func__);
827        return HDF_ERR_MALLOC_FAIL;
828    }
829
830    for (int i = 0; i < ACM_NW; i++) {
831        struct AcmWb *snd = &(acm->wb[i]);
832        snd->request = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataOutPipe->interfaceId), 0, acm->writeSize);    // Allocate the I/O request object to be sent.
833        snd->instance = acm;
834        if (snd->request == NULL) {
835            HDF_LOGE("%s:%d snd request failed", __func__, __LINE__);
836            goto error_alloc_write_req;
837        }
838    }
839
840    ret = AcmAllocNotifyRequest(acm); // Allocate and fill in the interrupt I/O request object.
841    if (ret != HDF_SUCCESS) {
842        HDF_LOGE("%s:%d AcmAllocNotifyRequest failed", __func__, __LINE__);
843        goto error_alloc_int_req;
844    }
845
846    ret = AcmAllocReadRequests(acm);    // Allocate and fill in the readReq I/O request object.
847    if (ret) {
848        HDF_LOGE("%s:%d AcmAllocReadRequests failed", __func__, __LINE__);
849        goto error_alloc_read_req;
850    }
851
852    return HDF_SUCCESS;
853
854error_alloc_read_req:
855    AcmFreeNotifyReqeust(acm);
856error_alloc_int_req:
857    AcmFreeWriteRequests(acm);
858error_alloc_write_req:
859    AcmWriteBufFree(acm);
860    return HDF_FAILURE;
861}
862
863static int32_t AcmInit(struct AcmDevice *acm)
864{
865    int32_t ret;
866    struct UsbSession *session = NULL;
867
868    if (acm->initFlag == true) {
869        HDF_LOGE("%s:%d: initFlag is true", __func__, __LINE__);
870        return HDF_SUCCESS;
871    }
872
873    ret = UsbInitHostSdk(NULL); // Initialize the Host DDK.
874    if (ret != HDF_SUCCESS) {
875        HDF_LOGE("%s: UsbInitHostSdk failed", __func__);
876        return HDF_ERR_IO;
877    }
878    acm->session = session;
879
880    ret = AcmClaimInterfaces(acm);
881    if (ret != HDF_SUCCESS) {
882        HDF_LOGE("%s: AcmClaimInterfaces failed", __func__);
883        goto error_claim_interfaces;
884    }
885
886    ret = AcmOpenInterfaces(acm);
887    if (ret != HDF_SUCCESS) {
888        HDF_LOGE("%s: AcmOpenInterfaces failed", __func__);
889        goto error_open_interfaces;
890    }
891
892    ret = AcmGetPipes(acm);
893    if (ret != HDF_SUCCESS) {
894        HDF_LOGE("%s: AcmGetPipes failed", __func__);
895        goto error_get_pipes;
896    }
897
898    ret = AcmAllocRequests(acm);
899    if (ret != HDF_SUCCESS) {
900        HDF_LOGE("%s: AcmAllocRequests failed", __func__);
901        goto error_alloc_reqs;
902    }
903
904    acm->lineCoding.dwDTERate = CpuToLe32(DATARATE);
905    acm->lineCoding.bCharFormat = CHARFORMAT;
906    acm->lineCoding.bParityType = USB_CDC_NO_PARITY;
907    acm->lineCoding.bDataBits = USB_CDC_1_STOP_BITS;
908    acm->initFlag = true;
909
910    HDF_LOGD("%s:%d========OK", __func__, __LINE__);
911    return HDF_SUCCESS;
912
913error_alloc_reqs:
914    AcmFreePipes(acm);
915error_get_pipes:
916    AcmCloseInterfaces(acm);
917error_open_interfaces:
918    AcmReleaseInterfaces(acm);
919error_claim_interfaces:
920    UsbExitHostSdk(acm->session);
921    acm->session = NULL;
922    return ret;
923}
924
925static void AcmRelease(struct AcmDevice *acm)
926{
927    if (acm->initFlag == false) {
928        HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__);
929        return;
930    }
931
932    AcmFreeRequests(acm);
933    AcmFreePipes(acm);
934    AcmCloseInterfaces(acm);
935    AcmReleaseInterfaces(acm);
936    UsbExitHostSdk(acm->session);
937    acm->session = NULL;
938
939    acm->initFlag = false;
940}
941
942static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device)
943{
944    int32_t ret;
945    struct AcmDevice *acm = NULL;
946
947    if (device == NULL) {
948        HDF_LOGE("%s: device is null", __func__);
949        return HDF_ERR_INVALID_OBJECT;
950    }
951    acm = (struct AcmDevice *)device->service;
952    OsalMutexInit(&acm->readLock);
953    OsalMutexInit(&acm->writeLock);
954    HDF_LOGD("%s:%d busNum=%d,devAddr=%d",
955        __func__, __LINE__, acm->busNum, acm->devAddr);
956
957    ret = UsbSerialDeviceAlloc(acm);
958    if (ret != HDF_SUCCESS) {
959        HDF_LOGE("%s: Serial Device alloc failed", __func__);
960    }
961
962    acm->initFlag = false;
963    g_acmReleaseFlag = false;
964
965    HDF_LOGD("%s:%d init ok!", __func__, __LINE__);
966
967    return ret;
968}
969
970static void UsbSerialDriverRelease(struct HdfDeviceObject *device)
971{
972    struct AcmDevice *acm = NULL;
973
974    if (device == NULL) {
975        HDF_LOGE("%s: device is NULL", __func__);
976        return;
977    }
978    acm = (struct AcmDevice *)device->service;
979    if (acm == NULL) {
980        HDF_LOGE("%s: acm is null", __func__);
981        return;
982    }
983
984    g_acmReleaseFlag = true;
985
986    if (acm->initFlag == true) {
987        HDF_LOGE("%s:%d AcmRelease", __func__, __LINE__);
988        AcmRelease(acm);
989    }
990    UsbSeriaDevicelFree(acm);
991    OsalMutexDestroy(&acm->writeLock);
992    OsalMutexDestroy(&acm->readLock);
993    OsalMutexDestroy(&acm->lock);
994    OsalMemFree(acm);
995    acm = NULL;
996    HDF_LOGD("%s:%d exit", __func__, __LINE__);
997}
998
999struct HdfDriverEntry g_usbSerialDriverEntry = {
1000    .moduleVersion = 1,
1001    .moduleName    = "usbhost_acm",    // Driver module name, which must be the same as that configured in the .hcs file.
1002    .Bind          = UsbSerialDriverBind,
1003    .Init          = UsbSerialDriverInit,
1004    .Release       = UsbSerialDriverRelease,
1005};
1006HDF_INIT(g_usbSerialDriverEntry);
1007```
1008
1009### Developing Driver Using Host Raw APIs<a name="section612mcpsimp"></a>
1010
1011```
1012root {
1013    module = "usb_pnp_device";
1014    usb_pnp_config {
1015        match_attr = "usb_pnp_match";
1016        usb_pnp_device_id = "UsbPnpDeviceId";
1017        UsbPnpDeviceId {
1018            idTableList = [
1019                "host_acm_rawapi_table"
1020            ];
1021            host_acm_rawapi_table {    // Driver mapping table information.
1022                // Driver module name, which must be the same as the value of moduleName in the driver entry structure.
1023                moduleName = "usbhost_acm_rawapi";
1024                // Service name of the driver, which must be unique.
1025                serviceName = "usbhost_acm_rawapi_service";
1026                // Keyword for matching private driver data.
1027                deviceMatchAttr = "usbhost_acm_rawapi_matchAttr";
1028                // Data length starting from this field, in bytes.
1029                length = 21;
1030                // USB driver matching rule: vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber.
1031                matchFlag = 0x0303;
1032                // Vendor ID.
1033                vendorId = 0x12D1;
1034                // Product ID.
1035                productId = 0x5000;
1036                // The least significant 16 bits of the device sequence number.
1037                bcdDeviceLow = 0x0000;
1038                // The most significant 16 bits of the device sequence number.
1039                bcdDeviceHigh = 0x0000;
1040                // Device class code allocated by the USB.
1041                deviceClass = 0;
1042                // Child class code allocated by the USB.
1043                deviceSubClass = 0;
1044                // Device protocol code allocated by the USB.
1045                deviceProtocol = 0;
1046                // Interface type. You can enter multiple types as needed.
1047                interfaceClass = [0];
1048                // Interface subtype. You can enter multiple subtypes as needed.
1049                interfaceSubClass = [2, 0];
1050                // Protocol that the interface complies with. You can enter multiple protocols as needed.
1051                interfaceProtocol = [1, 2];
1052                // Interface number. You can enter multiple interface numbers as needed.
1053                interfaceNumber = [2, 3];
1054            }
1055        }
1056    }
1057}
1058
1059#include "usb_serial_rawapi.h"
1060#include <unistd.h>
1061#include "osal_mem.h"
1062#include "osal_time.h"
1063#include "securec.h"
1064#include "hdf_base.h"
1065#include "hdf_log.h"
1066#include "hdf_usb_pnp_manage.h"
1067
1068#define HDF_LOG_TAG                     USB_HOST_ACM_RAW_API
1069#define USB_CTRL_REQ_SIZE               64
1070#define USB_IO_THREAD_STACK_SIZE        8192
1071#define USB_RAW_IO_SLEEP_MS_TIME        100
1072#define USB_RAW_IO_STOP_WAIT_MAX_TIME   3
1073
1074static struct UsbRawRequest *g_syncRequest = NULL;
1075static UsbRawIoProcessStatusType g_stopIoStatus = USB_RAW_IO_PROCESS_RUNNING;
1076struct OsalMutex g_stopIoLock;
1077static bool g_rawAcmReleaseFlag = false;
1078......
1079
1080static int UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConfigDescriptor **config)
1081{
1082    UsbRawDevice *dev = NULL;
1083    int activeConfig;
1084    int ret;
1085
1086    if (devHandle == NULL) {
1087        HDF_LOGE("%s:%d devHandle is NULL",
1088                 __func__, __LINE__);
1089        return HDF_ERR_INVALID_PARAM;
1090    }
1091
1092    ret = UsbRawGetConfiguration(devHandle, &activeConfig);
1093    if (ret) {
1094        HDF_LOGE("%s:%d UsbRawGetConfiguration failed, ret=%d",
1095                 __func__, __LINE__, ret);
1096        return HDF_FAILURE;
1097    }
1098    HDF_LOGE("%s:%d activeConfig=%d", __func__, __LINE__, activeConfig);
1099    dev = UsbRawGetDevice(devHandle);
1100    if (dev == NULL) {
1101        HDF_LOGE("%s:%d UsbRawGetDevice failed",
1102                 __func__, __LINE__);
1103        return HDF_FAILURE;
1104    }
1105
1106    ret = UsbRawGetConfigDescriptor(dev, activeConfig, config);
1107    if (ret) {
1108        HDF_LOGE("UsbRawGetConfigDescriptor failed, ret=%dn", ret);
1109        return HDF_FAILURE;
1110    }
1111
1112    return HDF_SUCCESS;
1113}
1114...
1115static int UsbAllocWriteRequests(struct AcmDevice *acm)
1116{
1117    int i;
1118
1119    for (i = 0; i < ACM_NW; i++) {
1120        struct AcmWb *snd = &acm->wb[i];
1121        snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataOutEp->maxPacketSize);
1122        snd->instance = acm;
1123        if (snd->request == NULL) {
1124            HDF_LOGE("%s: UsbRawAllocRequest failed", __func__);
1125            return HDF_ERR_MALLOC_FAIL;
1126        }
1127    }
1128
1129    return HDF_SUCCESS;
1130}
1131...
1132/* HdfDriverEntry implementations */
1133static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device)
1134{
1135    struct AcmDevice *acm = NULL;
1136    struct UsbPnpNotifyServiceInfo *info = NULL;
1137    errno_t err;
1138
1139    if (device == NULL) {
1140        HDF_LOGE("%s: device is null", __func__);
1141        return HDF_ERR_INVALID_OBJECT;
1142    }
1143
1144    acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm));
1145    if (acm == NULL) {
1146        HDF_LOGE("%s: Alloc usb serial device failed", __func__);
1147        return HDF_FAILURE;
1148    }
1149    if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
1150        HDF_LOGE("%s:%d OsalMutexInit failed", __func__, __LINE__);
1151        goto error;
1152    }
1153
1154    info = (struct UsbPnpNotifyServiceInfo *)device->priv;
1155    if (info != NULL) {
1156        acm->busNum       = info->busNum;
1157        acm->devAddr      = info->devNum;
1158        acm->interfaceCnt = info->interfaceLength;
1159        err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES,
1160                       (const void*)info->interfaceNumber, info->interfaceLength);
1161        if (err != EOK) {
1162            HDF_LOGE("%s:%d memcpy_s failed err=%d",
1163                __func__, __LINE__, err);
1164            goto lock_error;
1165        }
1166    } else {
1167        HDF_LOGE("%s:%d info is NULL!", __func__, __LINE__);
1168        goto lock_error;
1169    }
1170
1171    device->service = &(acm->service);
1172    device->service->Dispatch = UsbSerialDeviceDispatch;
1173    acm->device = device;
1174    HDF_LOGD("UsbSerialDriverBind=========================OK");
1175    return HDF_SUCCESS;
1176
1177lock_error:
1178    if (OsalMutexDestroy(&acm->lock)) {
1179        HDF_LOGE("%s:%d OsalMutexDestroy failed", __func__, __LINE__);
1180    }
1181error:
1182    OsalMemFree(acm);
1183    acm = NULL;
1184    return HDF_FAILURE;
1185}
1186...
1187static int UsbAllocReadRequests(struct AcmDevice *acm)
1188{
1189    struct UsbRawFillRequestData reqData;
1190    int size = acm->dataInEp->maxPacketSize;
1191    int ret;
1192
1193    for (int i = 0; i < ACM_NR; i++) {
1194        acm->readReq[i] = UsbRawAllocRequest(acm->devHandle, 0, size);
1195        if (!acm->readReq[i]) {
1196            HDF_LOGE("readReq request failed");
1197            return HDF_ERR_MALLOC_FAIL;
1198        }
1199
1200        reqData.endPoint      = acm->dataInEp->addr;
1201        reqData.numIsoPackets = 0;
1202        reqData.callback      = AcmReadBulkCallback;
1203        reqData.userData      = (void *)acm;
1204        reqData.timeout       = USB_CTRL_SET_TIMEOUT;
1205        reqData.length        = size;
1206
1207        ret = UsbRawFillBulkRequest(acm->readReq[i], acm->devHandle, &reqData);
1208        if (ret) {
1209            HDF_LOGE("%s: FillBulkRequest failed, ret=%d n",
1210                     __func__, ret);
1211            return HDF_FAILURE;
1212        }
1213    }
1214
1215    return HDF_SUCCESS;
1216}
1217...
1218static int UsbAllocNotifyRequest(struct AcmDevice *acm)
1219{
1220    struct UsbRawFillRequestData fillRequestData;
1221    int size = acm->notifyEp->maxPacketSize;
1222    int ret;
1223
1224    acm->notifyReq = UsbRawAllocRequest(acm->devHandle, 0, size);
1225    if (!acm->notifyReq) {
1226        HDF_LOGE("notifyReq request failed");
1227        return HDF_ERR_MALLOC_FAIL;
1228    }
1229
1230    fillRequestData.endPoint = acm->notifyEp->addr;
1231    fillRequestData.length = size;
1232    fillRequestData.numIsoPackets = 0;
1233    fillRequestData.callback = AcmNotifyReqCallback;
1234    fillRequestData.userData = (void *)acm;
1235    fillRequestData.timeout = USB_CTRL_SET_TIMEOUT;
1236
1237    ret = UsbRawFillInterruptRequest(acm->notifyReq, acm->devHandle, &fillRequestData);
1238    if (ret) {
1239        HDF_LOGE("%s: FillInterruptRequest failed, ret=%d", __func__, ret);
1240        return HDF_FAILURE;
1241    }
1242
1243    return HDF_SUCCESS;
1244}
1245...
1246static int32_t UsbSerialInit(struct AcmDevice *acm)
1247{
1248    struct UsbSession *session = NULL;
1249    UsbRawHandle *devHandle = NULL;
1250    int32_t ret;
1251
1252    if (acm->initFlag == true) {
1253        HDF_LOGE("%s:%d: initFlag is true", __func__, __LINE__);
1254        return HDF_SUCCESS;
1255    }
1256
1257    ret = UsbRawInit(NULL);
1258    if (ret) {
1259        HDF_LOGE("%s:%d UsbRawInit failed", __func__, __LINE__);
1260        return HDF_ERR_IO;
1261    }
1262    acm->session = session;
1263
1264    devHandle = UsbRawOpenDevice(session, acm->busNum, acm->devAddr);
1265    if (devHandle == NULL) {
1266        HDF_LOGE("%s:%d UsbRawOpenDevice failed", __func__, __LINE__);
1267        ret =  HDF_FAILURE;
1268        goto err_open_device;
1269    }
1270    acm->devHandle = devHandle;
1271    ret = UsbGetConfigDescriptor(devHandle, &acm->config);
1272    if (ret) {
1273        HDF_LOGE("%s:%d UsbGetConfigDescriptor failed", __func__, __LINE__);
1274        ret =  HDF_FAILURE;
1275        goto err_get_desc;
1276    }
1277    ret = UsbParseConfigDescriptor(acm, acm->config);
1278    if (ret != HDF_SUCCESS) {
1279        HDF_LOGE("%s:%d UsbParseConfigDescriptor failed", __func__, __LINE__);
1280        ret = HDF_FAILURE;
1281        goto err_parse_desc;
1282    }
1283
1284    ret = AcmWriteBufAlloc(acm);
1285    if (ret < 0) {
1286        HDF_LOGE("%s:%d AcmWriteBufAlloc failed", __func__, __LINE__);
1287        ret = HDF_FAILURE;
1288        goto err_alloc_write_buf;
1289    }
1290    ret = UsbAllocWriteRequests(acm);
1291    if (ret < 0) {
1292        HDF_LOGE("%s:%d UsbAllocWriteRequests failed", __func__, __LINE__);
1293        ret = HDF_FAILURE;
1294        goto err_alloc_write_reqs;
1295    }
1296    ret = UsbAllocNotifyRequest(acm);
1297    if (ret) {
1298        HDF_LOGE("%s:%d UsbAllocNotifyRequests failed", __func__, __LINE__);
1299        goto err_alloc_notify_req;
1300    }
1301    ret = UsbAllocReadRequests(acm);
1302    if (ret) {
1303        HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__);
1304        goto err_alloc_read_reqs;
1305    }
1306    ret = UsbStartIo(acm);
1307    if (ret) {
1308        HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__);
1309        goto err_start_io;
1310    }
1311
1312    acm->lineCoding.dwDTERate   = CpuToLe32(DATARATE);
1313    acm->lineCoding.bCharFormat = CHARFORMAT;
1314    acm->lineCoding.bParityType = USB_CDC_NO_PARITY;
1315    acm->lineCoding.bDataBits   = USB_CDC_1_STOP_BITS;
1316
1317    ret = UsbRawSubmitRequest(acm->notifyReq);
1318    if (ret) {
1319        HDF_LOGE("%s:%d UsbRawSubmitRequest failed", __func__, __LINE__);
1320        goto err_submit_req;
1321    }
1322
1323    acm->initFlag = true;
1324
1325    HDF_LOGD("%s:%d=========================OK", __func__, __LINE__);
1326
1327    return HDF_SUCCESS;
1328
1329err_submit_req:
1330    UsbStopIo(acm);
1331err_start_io:
1332    UsbFreeReadRequests(acm);
1333err_alloc_read_reqs:
1334    UsbFreeNotifyReqeust(acm);
1335 err_alloc_notify_req:
1336    UsbFreeWriteRequests(acm);
1337err_alloc_write_reqs:
1338    AcmWriteBufFree(acm);
1339err_alloc_write_buf:
1340    UsbReleaseInterfaces(acm);
1341err_parse_desc:
1342    UsbRawFreeConfigDescriptor(acm->config);
1343    acm->config = NULL;
1344err_get_desc:
1345    (void)UsbRawCloseDevice(devHandle);
1346err_open_device:
1347    UsbRawExit(acm->session);
1348
1349    return ret;
1350}
1351
1352static void UsbSerialRelease(struct AcmDevice *acm)
1353{
1354    if (acm->initFlag == false) {
1355        HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__);
1356        return;
1357    }
1358
1359    /* stop io thread and release all resources */
1360    UsbStopIo(acm);
1361    if (g_syncRequest != NULL) {
1362        UsbRawFreeRequest(g_syncRequest);
1363        g_syncRequest = NULL;
1364    }
1365    UsbFreeReadRequests(acm);
1366    UsbFreeNotifyReqeust(acm);
1367    UsbFreeWriteRequests(acm);
1368    AcmWriteBufFree(acm);
1369    (void)UsbRawCloseDevice(acm->devHandle);
1370    UsbReleaseInterfaces(acm);
1371    UsbRawFreeConfigDescriptor(acm->config);
1372    acm->config = NULL;
1373    UsbRawExit(acm->session);
1374
1375    acm->initFlag = false;
1376}
1377
1378static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device)
1379{
1380    struct AcmDevice *acm = NULL;
1381    int32_t ret;
1382
1383    if (device == NULL) {
1384        HDF_LOGE("%s:%d device is null", __func__, __LINE__);
1385        return HDF_ERR_INVALID_OBJECT;
1386    }
1387    acm = (struct AcmDevice *)device->service;
1388    OsalMutexInit(&acm->readLock);
1389    OsalMutexInit(&acm->writeLock);
1390
1391    ret = UsbSerialDeviceAlloc(acm);
1392    if (ret != HDF_SUCCESS) {
1393        HDF_LOGE("%s:%d UsbSerialDeviceAlloc failed", __func__, __LINE__);
1394    }
1395
1396    acm->initFlag = false;
1397    g_rawAcmReleaseFlag = false;
1398
1399    HDF_LOGD("%s:%d init ok!", __func__, __LINE__);
1400
1401    return ret;
1402}
1403
1404static void UsbSerialDriverRelease(struct HdfDeviceObject *device)
1405{
1406    struct AcmDevice *acm = NULL;
1407    if (device == NULL) {
1408        HDF_LOGE("%s: device is NULL", __func__);
1409        return;
1410    }
1411
1412    acm = (struct AcmDevice *)device->service;
1413    if (acm == NULL) {
1414        HDF_LOGE("%s: acm is null", __func__);
1415        return;
1416    }
1417
1418    g_rawAcmReleaseFlag = true;
1419
1420    if (acm->initFlag == true) {
1421        HDF_LOGE("%s:%d UsbSerialRelease", __func__, __LINE__);
1422        UsbSerialRelease(acm);
1423    }
1424    UsbSeriaDevicelFree(acm);
1425    OsalMutexDestroy(&acm->writeLock);
1426    OsalMutexDestroy(&acm->readLock);
1427    OsalMutexDestroy(&acm->lock);
1428    OsalMemFree(acm);
1429    acm = NULL;
1430    HDF_LOGD("%s:%d exit", __func__, __LINE__);
1431}
1432
1433struct HdfDriverEntry g_usbSerialRawDriverEntry = {
1434    .moduleVersion = 1,
1435    ..moduleName    = "usbhost_acm_rawapi",    // Driver module name, which must be the same as that configured in the .hcs file.
1436    .Bind          = UsbSerialDriverBind,
1437    .Init          = UsbSerialDriverInit,
1438    .Release       = UsbSerialDriverRelease,
1439};
1440HDF_INIT(g_usbSerialRawDriverEntry);
1441```
1442
1443### Developing Driver Using Device DDK APIs<a name="section615mcpsimp"></a>
1444
1445The core code of the USB Abstract Control Model (ACM) device is available in **drivers/peripheral/usb/gadget/function/acm/cdcacm.c**. The following is an example:
1446
1447```
14481. Create a device.
1449static int32_t AcmCreateFuncDevice(struct UsbAcmDevice *acm,
1450    struct DeviceResourceIface *iface)
1451{
1452    struct UsbFnDevice *fnDev = NULL;
1453struct UsbFnDescriptorData descData;
1454uint8_t useHcs;
1455     ...
1456if (useHcs == 0) {
1457    descData.type = USBFN_DESC_DATA_TYPE_DESC;
1458    descData.descriptor = &g_masterFuncDevice;
1459} else {
1460    descData.type = USBFN_DESC_DATA_TYPE_PROP;
1461    descData.property = device->property;
1462}
1463/* Create a device. */
1464    fnDev = (struct UsbFnDevice *)UsbFnDeviceCreate(acm->udcName, &descData);
1465    if (fnDev == NULL) {
1466        HDF_LOGE("%s: create usb function device failed", __func__);
1467        return HDF_FAILURE;
1468    }
1469    ...
1470}
14712. Obtain an interface and open the interface for pipe information.
1472static int32_t AcmParseEachPipe(struct UsbAcmDevice *acm, struct UsbAcmInterface *iface)
1473{
1474    ...
1475    for (i = 0; i < fnIface->info.numPipes; i++) {
1476        struct UsbFnPipeInfo pipeInfo;
1477/* Obtain pipe information. */
1478        ret = UsbFnInterfaceGetPipeInfo(fnIface, i, &pipeInfo);
1479        ...
1480    }
1481    return HDF_SUCCESS;
1482}
1483/* Obtain the interface and open the interface to obtain the handle. */
1484static int32_t AcmParseEachIface(struct UsbAcmDevice *acm, struct UsbFnDevice *fnDev)
1485{
1486    ...
1487    for (i = 0; i < fnDev->numInterfaces; i++) {
1488        /* Obtain an interface.*/
1489        fnIface = (struct UsbFnInterface *)UsbFnDeviceGetInterface(fnDev, i);
1490        ...
1491        /* Open the interface. */
1492        handle = UsbFnInterfaceOpen(fnIface);
1493        ...
1494    }
1495    return HDF_SUCCESS;
1496}
14973. Receive events.
1498static int32_t AcmAllocCtrlRequests(struct UsbAcmDevice *acm, int num)
1499{
1500    ...
1501        req = UsbFnCtrlRequestAlloc(acm->ctrlIface.handle,
1502            sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding));
1503    ...
1504}
1505static int32_t AcmDriverInit(struct HdfDeviceObject *device)
1506{
1507...
1508/* Start to receive events.*/
1509    ret = UsbFnInterfaceStartRecvEvent(acm->ctrlIface.fn, 0xff, UsbAcmEventCallback, acm);
1510    ...
1511}
15124. Perform USB communication (read and write).
1513static int32_t AcmSendNotifyRequest(struct UsbAcmDevice *acm, uint8_t type,
1514    uint16_t value, void *data, uint32_t length)
1515{
1516...
1517/* Send an asynchronous request.*/
1518    ret = UsbFnRequestSubmitAsync(req);
1519    ...
1520}
15215. Close the interface, stop receiving events, and remove the device.
1522static int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm)
1523{
1524int32_t ret;
1525/* Close the interface. */
1526    (void)UsbFnInterfaceClose(acm->ctrlIface.handle);
1527(void)UsbFnInterfaceClose(acm->dataIface.handle);
1528/* Stop receiving events. */
1529(void)UsbFnInterfaceStopRecvEvent(acm->ctrlIface.fn);
1530/* Remove the device. */
1531    ret = UsbFnDeviceRemove(acm->fnDev);
1532    if (ret != HDF_SUCCESS) {
1533        HDF_LOGE("%s: remove usb function device failed", __func__);
1534    }
1535    return ret;
1536}
1537```
1538