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 14 15**Figure 2** USB device driver model<a name="fig8847615103013"></a> 16 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, ¶ms); 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