HarmonyOS USB DDK助你轻松实现USB驱动开发
Python微信訂餐小程序課程視頻
https://edu.csdn.net/course/detail/36074
Python實(shí)戰(zhàn)量化交易理財(cái)系統(tǒng)
https://edu.csdn.net/course/detail/35475
HDF(Hardware Driver Foundation)驅(qū)動(dòng)框架是HarmonyOS硬件生態(tài)開放的基礎(chǔ),為開發(fā)者提供了驅(qū)動(dòng)加載、驅(qū)動(dòng)服務(wù)管理和驅(qū)動(dòng)消息機(jī)制等驅(qū)動(dòng)能力,讓開發(fā)者能精準(zhǔn)且高效地開發(fā)驅(qū)動(dòng)程序。
本期,我們將為大家?guī)?lái)HDF驅(qū)動(dòng)框架中USB DDK的解析與指導(dǎo)。
一、USB DDK介紹
USB(Universal Serial Bus)通用串行總線,用于規(guī)范電腦與外部設(shè)備的連接和通訊,包含了主機(jī)端(Host)和設(shè)備端(Device)。其中,主機(jī)端負(fù)責(zé)USB總線中的數(shù)據(jù)傳輸及端口管理,設(shè)備端則可以連接各種外設(shè),所以USB驅(qū)動(dòng)開發(fā)又分為主機(jī)端驅(qū)動(dòng)開發(fā)和設(shè)備端驅(qū)動(dòng)開發(fā)。
由于基于內(nèi)核態(tài)開發(fā)的USB驅(qū)動(dòng)功能擴(kuò)展性較差,目前開發(fā)者通常選擇Libusb庫(kù)進(jìn)行USB驅(qū)動(dòng)開發(fā)。該庫(kù)是一種跨平臺(tái)的用戶態(tài)開源USB通信庫(kù),可以滿足開發(fā)者基于用戶態(tài)開發(fā)功能驅(qū)動(dòng)的需求。但是,由于Libusb庫(kù)是完全按照USB協(xié)議來(lái)封裝接口的,所以需要開發(fā)者對(duì)USB協(xié)議要有較深的了解才能很好的使用,對(duì)開發(fā)者的要求相對(duì)較高,讓很多比較初級(jí)的開發(fā)者望而卻步。為了讓更多的開發(fā)者都能進(jìn)行基于用戶態(tài)的USB驅(qū)動(dòng)開發(fā),HDF引入了USB DDK開發(fā)套件。
USB DDK(USB DriverDevelop Kit)是HDF驅(qū)動(dòng)框架為開發(fā)者提供的USB驅(qū)動(dòng)程序開發(fā)套件,包括USB Host DDK及USB Device DDK兩部分,支持基于用戶態(tài)開發(fā)USB設(shè)備驅(qū)動(dòng)的同時(shí),還提供了豐富的USB驅(qū)動(dòng)開發(fā)能力,讓廣大開發(fā)者能精準(zhǔn)且高效的開發(fā)USB驅(qū)動(dòng)程序。
下面,我們將一一道來(lái)。
1)USB Host DDK
USB Host DDK給開發(fā)者提供了主機(jī)端USB驅(qū)動(dòng)開發(fā)能力,按照功能分類三大類,分別是DDK初始化類、interface對(duì)象操作類及request對(duì)象操作類。并為開發(fā)者提供了普通模式和專家模式兩種開發(fā)模式。普通模式下,開發(fā)者可通過USBDDK API直接完成相關(guān)USB數(shù)據(jù)讀寫操作,不需要過多關(guān)注底層傳輸細(xì)節(jié)。
專家模式下,開發(fā)者通過USB RAW API直接訪問OS平臺(tái)USB通道的接口,自定義實(shí)現(xiàn)更加復(fù)雜的功能。目的是給驅(qū)動(dòng)層留有更靈活,更強(qiáng)大的擴(kuò)展方案,同時(shí)也能夠兼容現(xiàn)有驅(qū)動(dòng),便于移植。USBHost DDK架構(gòu)如圖1所示:
圖1 USB Host DDK架構(gòu)
(1)USB Interface Pool負(fù)責(zé)USBInterface管理。提供USB Interface申請(qǐng)和回收,USB Interface記錄設(shè)備端口信息以及資源。USB Interface Pool按照USB Port對(duì)USB Interface進(jìn)行分類管理。同時(shí),此模塊還提供了USB DDK API,方便開發(fā)者USB數(shù)據(jù)讀寫操作。
(2)USB Protocol Layer提供USB協(xié)議封裝,根據(jù)USB協(xié)議對(duì)設(shè)備IO/控制命令的“翻譯/解析”,同時(shí)負(fù)責(zé)設(shè)備描述符的管理,根據(jù)USB Device上報(bào)的枚舉信息,匹配對(duì)應(yīng)的描述符,并構(gòu)建對(duì)應(yīng)的USB Interface,并加入到USB Interface Pool中管理。
(3)Device IO Manager負(fù)責(zé)USBIO請(qǐng)求管理,提供了同步IO和異步IO管理機(jī)制,對(duì)于異步IO,IO Manager負(fù)責(zé)將該請(qǐng)求記錄下來(lái),然后通過Raw API Library提供的接口依次處理待發(fā)送的IO請(qǐng)求;當(dāng)收到USB控制器應(yīng)答的處理結(jié)果后,IO接收線程負(fù)責(zé)解析并上報(bào)處理結(jié)果給上層調(diào)用者。
(4)Raw API Library抽象了底層OS能力,定義了統(tǒng)一的OS能力接口,對(duì)外提供了USB RAW API,讓開發(fā)者自定義實(shí)現(xiàn)更加復(fù)雜的驅(qū)動(dòng)功能。
(5)OS Adapter用于封裝與平臺(tái)(Linux和LiteOS)相關(guān)的操作,根據(jù)不同平臺(tái)配置編譯對(duì)應(yīng)平臺(tái)的封裝接口。在Linux平臺(tái)上,訪問USBFS的操作,全部都封裝在這個(gè)模塊中;而在LiteOS平臺(tái)上,基于FreeBSD USB框架的設(shè)備訪問操作,對(duì)應(yīng)的也都全部封裝在這個(gè)模塊中。
(6)PNP Notify用于動(dòng)態(tài)監(jiān)測(cè)USB狀態(tài)變化,當(dāng)有新設(shè)備添加/移除時(shí),變化設(shè)備信息。同時(shí)將所有USB設(shè)備信息都通過KHDF上報(bào)給UHDF側(cè)的PNPNotify Manager模塊來(lái)完成加載/卸載第三方功能驅(qū)動(dòng)。
2)USB Device DDK
USB Device DDK給開發(fā)者提供了設(shè)備端USB驅(qū)動(dòng)開發(fā)能力。例如,USB端口動(dòng)態(tài)注冊(cè)和去注冊(cè)能力,開發(fā)者可以基于能力實(shí)現(xiàn)USB端口的動(dòng)態(tài)添加和組合;動(dòng)態(tài)實(shí)例化能力,支持根據(jù)動(dòng)態(tài)下發(fā)設(shè)備、配置、接口及端點(diǎn)描述符創(chuàng)建設(shè)備實(shí)例及傳輸通道;用戶態(tài)的數(shù)據(jù)發(fā)送及接收能力,支持用戶態(tài)下發(fā)送及接收數(shù)據(jù);復(fù)合設(shè)備能力,支持一個(gè)物理設(shè)備上多個(gè)邏輯設(shè)備,實(shí)現(xiàn)多個(gè)邏輯設(shè)備間隔離,并支持不同邏輯設(shè)備同時(shí)被不同的應(yīng)用進(jìn)程訪問。
USB Device DDK架構(gòu)如圖2所示:
圖2 USB Device DDK架構(gòu)
(1)SDK IF負(fù)責(zé)將USB設(shè)備按照設(shè)備、接口、管道進(jìn)行邏輯劃分,對(duì)配置管理、設(shè)備管理、IO管理進(jìn)行封裝。此模塊還向開發(fā)者提供了設(shè)備創(chuàng)建、獲取接口、接收Event事件、收發(fā)數(shù)據(jù)等設(shè)備測(cè)驅(qū)動(dòng)開發(fā)的能力接口。
(2)Configuration Manager負(fù)責(zé)解析HCS文件描述的USB描述符信息,得到的USB描述符信息用于設(shè)備創(chuàng)建,同時(shí)模塊還提供了自定義屬性的讀取、創(chuàng)建、刪除、修改等操作。
(3)Device Manager負(fù)責(zé)根據(jù)配置模塊解析的USB描述符,并根據(jù)USB描述符創(chuàng)建設(shè)備。同時(shí)模塊還負(fù)責(zé)獲取設(shè)備、刪除設(shè)備、獲取設(shè)備狀態(tài),獲取設(shè)備上面接口信息。
(4)IO Manager負(fù)責(zé)數(shù)據(jù)的讀寫,包括Events事件、數(shù)據(jù)讀寫完成事件的接受,支持同步和異步模式數(shù)據(jù)讀寫。
(5)Adapter IF主要是對(duì)復(fù)合設(shè)備配置驅(qū)動(dòng)及通用功能驅(qū)動(dòng)設(shè)備節(jié)點(diǎn)操作進(jìn)行封裝,為上層提供統(tǒng)一的設(shè)備管理接口。
(6)Adapter該模塊由復(fù)合設(shè)備配置驅(qū)動(dòng)及通用功能驅(qū)動(dòng)提供。
二、USB DDK開發(fā)指導(dǎo)
相信大家已對(duì)USB DDK已經(jīng)有了一定的認(rèn)識(shí)。下面,我們來(lái)看看如何使用USB DDK來(lái)開發(fā)USB Host和USB Device驅(qū)動(dòng)程序吧。
1)USB Host的開發(fā)
USB Host(主機(jī)端驅(qū)動(dòng))主要完成協(xié)議封裝、設(shè)備管理、驅(qū)動(dòng)安裝與卸載等。通過上文的介紹,開發(fā)者可通過USB DDK API和USB RAW API來(lái)實(shí)現(xiàn)主機(jī)端驅(qū)動(dòng)。
1. USB DDK API的使用
USB DDK API主要實(shí)現(xiàn)主機(jī)端USB數(shù)據(jù)讀寫操作,如圖3所示,是USB DDK API提供的部分接口。
圖3 USB DDK API部分接口
使用步驟如下:
(1) 配置驅(qū)動(dòng)匹配表,完成主機(jī)端驅(qū)動(dòng)總體信息的配置,具體如下:
struct UsbPnpMatchIdTable { //驅(qū)動(dòng)模塊名,該字段的值必須和驅(qū)動(dòng)入口結(jié)構(gòu)的moduleName一致 const char *moduleName; //驅(qū)動(dòng)對(duì)外發(fā)布服務(wù)的名稱,必須唯一 const char *serviceName; //驅(qū)動(dòng)私有數(shù)據(jù)匹配關(guān)鍵字 const char *deviceMatchAttr; //從該字段開始(包含該字段)之后數(shù)據(jù)長(zhǎng)度,以byte為單位 uint8\_t length; //USB驅(qū)動(dòng)匹配規(guī)則 uint16\_t matchFlag; //廠商編號(hào) uint16\_t vendorId; //產(chǎn)品編號(hào) uint16\_t productId; //設(shè)備出廠編號(hào),低16位 uint16\_t bcdDeviceLow; //設(shè)備出廠編號(hào),高16位 uint16\_t bcdDeviceHigh; //USB分配的設(shè)備類代碼 uint8\_t deviceClass; //USB分配的子類代碼 uint8\_t deviceSubClass; //USB分配的設(shè)備協(xié)議代碼 uint8\_t deviceProtocol; //接口類型,根據(jù)實(shí)際需要可填寫多個(gè) uint8\_t interfaceClass[USB\_PNP\_INFO\_MAX\_INTERFACES]; //接口子類型,根據(jù)實(shí)際需要可填寫多個(gè) uint8\_t interfaceSubClass[USB\_PNP\_INFO\_MAX\_INTERFACES]; //接口所遵循的協(xié)議,根據(jù)實(shí)際需要可填寫多個(gè) uint8\_t interfaceProtocol[USB\_PNP\_INFO\_MAX\_INTERFACES]; //接口的編號(hào),根據(jù)實(shí)際需要可填寫多個(gè) uint8\_t interfaceNumber[USB\_PNP\_INFO\_MAX\_INTERFACES]; };其中matchFlag表示驅(qū)動(dòng)匹配規(guī)則,每個(gè)bit表示一種匹配方式,其取值如下:
enum {USB\_PNP\_NOTIFY\_MATCH\_VENDOR = 0x0001,USB\_PNP\_NOTIFY\_MATCH\_PRODUCT = 0x0002,USB\_PNP\_NOTIFY\_MATCH\_DEV\_LOW = 0x0004,USB\_PNP\_NOTIFY\_MATCH\_DEV\_HIGH = 0x0008,USB\_PNP\_NOTIFY\_MATCH\_DEV\_CLASS = 0x0010,USB\_PNP\_NOTIFY\_MATCH\_DEV\_SUBCLASS = 0x0020,USB\_PNP\_NOTIFY\_MATCH\_DEV\_PROTOCOL = 0x0040,USB\_PNP\_NOTIFY\_MATCH\_INT\_CLASS = 0x0080,USB\_PNP\_NOTIFY\_MATCH\_INT\_SUBCLASS = 0x0100,USB\_PNP\_NOTIFY\_MATCH\_INT\_PROTOCOL = 0x0200,USB\_PNP\_NOTIFY\_MATCH\_INT\_NUMBER = 0x0400, };(2) USB主機(jī)端驅(qū)動(dòng)開發(fā)工具包初始化,使用如下接口:
int32\_t UsbInitHostSdk(struct UsbSession **session)(3) 待步驟2初始化完后獲取UsbInterface對(duì)象,使用如下接口:
const struct UsbInterface *UsbClaimInterface(const struct UsbSession *session, uint8\_t busNum, uint8\_t usbAddr, uint8\_t interfaceIndex);(4) 打開步驟3獲取到的UsbInterface接口對(duì)象,獲取對(duì)應(yīng)接口的UsbInterfaceHandle對(duì)象,使用如下接口:
UsbInterfaceHandle *UsbOpenInterface(const struct UsbInterface *interfaceObj);(5) 根據(jù)步驟4獲取到的UsbInterfaceHandle對(duì)象,獲取指定索引為pinpeIndex的pipeInfo信息,使用如下接口:
int32\_t UsbGetPipeInfo(const UsbInterfaceHandle *interfaceHandle, uint8\_t settingIndex, uint8\_t pipeId, struct UsbPipeInfo *pipeInfo);(6) 為步驟4獲取到的UsbInterfaceHandle預(yù)先分配待發(fā)送的IO Request對(duì)象,使用如下接口:
struct UsbRequest *UsbAllocRequest(const UsbInterfaceHandle *interfaceHandle, int isoPackets, int length);(7) 根據(jù)輸入?yún)?shù)params填充步驟6預(yù)先分配的IO Request,使用如下接口:
int32\_t UsbFillRequest(const struct UsbRequest *request, const UsbInterfaceHandle *interfaceHandle, const struct UsbRequestParams *params);(8) 提交IO Request對(duì)象,可以選擇同步或異步兩種模式,使用如下接口:
int32\_t UsbSubmitRequestSync(const struct UsbRequest *request);//發(fā)送同步IO請(qǐng)求 int32\_t UsbSubmitRequestAsync(const struct UsbRequest *request);//發(fā)送異步IO請(qǐng)求2. USB RAW API 的使用
USB RAW API主要實(shí)現(xiàn)USB更加復(fù)雜的功能,如獲取描述符信息、獲取設(shè)備指針、復(fù)位設(shè)備、提交傳輸請(qǐng)求等,如圖4所示,是USB RAW API提供的部分接口。
圖4 USB RAW API
使用步驟如下:
(1) 同USB DDK API的步驟1一樣,需先進(jìn)行驅(qū)動(dòng)匹配表配置。
(2) 初始化Host RAW,使用如下接口:
int32\_t UsbRawInit(struct UsbSession **session);(3) 待步驟2完成后打開USB設(shè)備,使用如下接口:
UsbRawHandle *UsbRawOpenDevice(const struct UsbSession *session, uint8\_t busNum, uint8\_t usbAddr);(4) 待步驟3完成后獲取描述符,通過描述符獲取接口、端點(diǎn)信息,使用如下接口:
int32\_t UsbRawGetConfigDescriptor(const UsbRawDevice *rawDev, uint8\_t configIndex, struct UsbRawConfigDescriptor **config);(5) 分配Request,并根據(jù)不同的傳輸類型使用相應(yīng)的接口對(duì)Request進(jìn)行填充:
int32\_t UsbRawFillBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);// 填充用于批量傳輸?shù)恼?qǐng)求 int32\_t UsbRawFillControlSetup(const unsigned char *setup, const struct UsbControlRequestData *requestData); int32\_t UsbRawFillControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);// 填充用于控制傳輸?shù)恼?qǐng)求 int32\_t UsbRawFillInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);// 填充用于中斷傳輸?shù)恼?qǐng)求 int32\_t UsbRawFillIsoRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);// 填充用于同步傳輸?shù)恼?qǐng)求(6) 提交IO Request對(duì)象,可以選擇同步或異步兩種模式,分別使用如下接口:
int32\_t UsbRawSendControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbControlRequestData *requestData);//發(fā)送同步USB控制傳輸請(qǐng)求 int32\_t UsbRawSendBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData);//發(fā)送同步USB批量傳輸請(qǐng)求 int32\_t UsbRawSendInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData);//發(fā)送同步執(zhí)行USB中斷傳輸請(qǐng)求 int32\_t UsbRawSubmitRequest(const struct UsbRawRequest *request);//提交異步IO請(qǐng)求感興趣的小伙伴可點(diǎn)擊下方鏈接查看完整的USB Host開發(fā)代碼:
https://gitee.com/openharmony/drivers_peripheral/tree/master/usb/serial/src
2)USB Device的開發(fā)
USB Device(設(shè)備端驅(qū)動(dòng))主要實(shí)現(xiàn)設(shè)備管理、配置管理、IO管理、數(shù)據(jù)通信等。USB Deivce DDK給開發(fā)者提供了設(shè)備創(chuàng)建、獲取接口、接收Event事件、收發(fā)數(shù)據(jù)等驅(qū)動(dòng)能力接口,如圖5所示:
圖5 USB Device DDK開放的API
下面,我們將根據(jù)USB Deivce DDK提供的驅(qū)動(dòng)能力接口來(lái)開發(fā)設(shè)備端驅(qū)動(dòng)。
1. 構(gòu)造描述符
首先,需構(gòu)造描述符來(lái)說(shuō)明設(shè)備的總體信息。開發(fā)者可以通過設(shè)備功能代碼及設(shè)備私有數(shù)據(jù)HCS兩種途徑進(jìn)行配置,下面將分別介紹。
(1) 在設(shè)備功能代碼中配置描述符,配置代碼如下:
static struct UsbFnFunction g\_acmFunction = {//功能描述符.enable = true,.funcName = "f\_generic.a",.strings = g\_acmStrings,.fsDescriptors = g\_acmFsFunction,.hsDescriptors = g\_acmHsFunction,.ssDescriptors = g\_acmSsFunction, .sspDescriptors = NULL, }; struct UsbFnFunction *g\_functions[] = { #ifdef CDC\_ECM&g\_ecmFunction, #endif #ifdef CDC\_ACM&g\_acmFunction, #endif NULL }; static struct UsbFnConfiguration g\_masterConfig = {//配置描述符.configurationValue = 1,.iConfiguration = USB\_FUNC\_CONFIG\_IDX,.attributes = USB\_CFG\_BUS\_POWERED,.maxPower = POWER,.functions = g\_functions, }; static struct UsbFnConfiguration *g\_configs[] = {&g\_masterConfig,NULL, }; static struct UsbDeviceDescriptor g\_cdcMasterDeviceDesc = {//設(shè)備描述符.bLength = sizeof(g\_cdcMasterDeviceDesc),.bDescriptorType = USB\_DDK\_DT\_DEVICE,.bcdUSB = CpuToLe16(BCD\_USB),.bDeviceClass = 0,.bDeviceSubClass = 0,.bDeviceProtocol = 0,.bMaxPacketSize0 = USB\_MAX\_PACKET\_SIZE,.idVendor = CpuToLe16(DEVICE\_VENDOR\_ID),.idProduct = CpuToLe16(DEVICE\_PRODUCT\_ID),.bcdDevice = CpuToLe16(DEVICE\_VERSION),.iManufacturer = USB\_FUNC\_MANUFACTURER\_IDX,.iProduct = USB\_FUNC\_PRODUCT\_IDX,.iSerialNumber = USB\_FUNC\_SERIAL\_IDX,.bNumConfigurations = 1, }; static struct UsbFnDeviceDesc g\_masterFuncDevice = {//描述符入口.deviceDesc = &g\_cdcMasterDeviceDesc,.deviceStrings = g\_devStrings,.configs = g\_configs, };(2) 在設(shè)備私有數(shù)據(jù)HCS中配置,配置代碼如下:
root {module = "master"; master\_config {match\_attr = "usbfn\_master\_driver";//該字段與device中deviceMatchAttr保持一致,否則無(wú)法找到的這個(gè)節(jié)點(diǎn)的信息。use\_hcs = 1; //用戶可以用該值決定是否使用hcs配置信息udc\_name = "100e0000.hidwc3\_0"; //UDC的名字usb\_dev\_desc = "UsbDeviceDescriptor";//設(shè)備描述符的節(jié)點(diǎn)UsbDeviceDescriptorusb\_dev\_string = "UsbDeviceStrings"; //設(shè)備字符串的節(jié)點(diǎn)為UsbDeviceStringsusb\_configuration = "UsbConfigs"; //配置描述符的節(jié)點(diǎn)為UsbConfigs...} }設(shè)備描述符的節(jié)點(diǎn)為UsbDeviceDescriptor,配置如下:
UsbDeviceDescriptor {bLength = 18;bDescriptorType = 0x01;bcdUSB = 0x0200;bDeviceClass = 0;bDeviceSubClass = 0;bDeviceProtocol = 0;bMaxPacketSize0 = 0x40;idVendor = 0x0525;idProduct = 0xA4A7;bcdDevice = 0x0100;manufacturer = 0;product = 1;serialnumber = 2;numConfigurations = 1; }2. 創(chuàng)建設(shè)備
描述符構(gòu)造完成后,使用UsbFnDeviceCreate函數(shù)創(chuàng)建一個(gè)USB設(shè)備,并傳入U(xiǎn)DC控制器名和UsbFnDescriptorData結(jié)構(gòu)體。實(shí)現(xiàn)代碼如下:
if (useHcs == 0) {//使用代碼編寫的描述符descData.type = USBFN\_DESC\_DATA\_TYPE\_DESC;descData.descriptor = &g\_acmFuncDevice;} else { //使用hcs編寫的描述符descData.type = USBFN\_DESC\_DATA\_TYPE\_PROP;descData.property = acm->device->property; }//創(chuàng)建設(shè)備fnDev = (struct UsbFnDevice *) UsbFnCreateDevice(acm->udcName, &descData);3.獲取接口
設(shè)備創(chuàng)建后,使用UsbFnDeviceGetInterface函數(shù)獲取UsbInterface接口對(duì)象,并通過UsbFnGetInterfacePipeInfo函數(shù)獲取USB管道信息,實(shí)現(xiàn)代碼如下:
//獲取接口 fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i); //獲取Pipe信息 UsbFnGetInterfacePipeInfo(fnIface, i, &pipeInfo); //獲取Handle handle = UsbFnOpenInterface(fnIface); //獲取控制(EP0)Request req = UsbFnAllocCtrlRequest(acm->ctrlIface.handle,sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding)); //獲取Request req = UsbFnAllocCtrlRequest(acm->ctrlIface.handle,sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding));4. 接收Event事件
通過UsbFnStartRecvInterfaceEvent函數(shù)接收Event事件,并通過UsbFnEventCallback回調(diào)函數(shù)對(duì)Event事件做出響應(yīng),實(shí)現(xiàn)代碼如下:
//開始接收Event事件 ret = UsbFnStartRecvInterfaceEvent(acm->ctrlIface.fn, 0xff, UsbAcmEventCallback, acm); //Event處理回調(diào)函數(shù) static void UsbAcmEventCallback(struct UsbFnEvent *event) { struct UsbAcmDevice *acm = NULL;if (event == NULL || event->context == NULL) {HDF\_LOGE("%s: event is null", \_\_func\_\_);return;}acm = (struct UsbAcmDevice *)event->context;switch (event->type) {case USBFN\_STATE\_BIND:HDF\_LOGI("%s: receive bind event", \_\_func\_\_);break;case USBFN\_STATE\_UNBIND:HDF\_LOGI("%s: receive unbind event", \_\_func\_\_);break;case USBFN\_STATE\_ENABLE:HDF\_LOGI("%s: receive enable event", \_\_func\_\_);AcmEnable(acm);break;case USBFN\_STATE\_DISABLE:HDF\_LOGI("%s: receive disable event", \_\_func\_\_);AcmDisable(acm);acm->enableEvtCnt = 0;break;case USBFN\_STATE\_SETUP:HDF\_LOGI("%s: receive setup event", \_\_func\_\_);if (event->setup != NULL) {AcmSetup(acm, event->setup);}break;case USBFN\_STATE\_SUSPEND:HDF\_LOGI("%s: receive suspend event", \_\_func\_\_);AcmSuspend(acm);break;case USBFN\_STATE\_RESUME:HDF\_LOGI("%s: receive resume event", \_\_func\_\_);AcmResume(acm);break;default:break;} }5. 收發(fā)數(shù)據(jù)
可以選擇同步異步發(fā)送模式,實(shí)現(xiàn)代碼如下:
notify = (struct UsbCdcNotification *)req->buf;...if (memcpy\_s((void *)(notify + 1), length, data, length) != EOK) {return HDF\_FAILURE;} ret = UsbFnSubmitRequestAsync(req);//異步發(fā)送感興趣的小伙伴可點(diǎn)擊下方鏈接查看完整的設(shè)備測(cè)開發(fā)代碼。
完整設(shè)備測(cè)開發(fā)代碼:https://gitee.com/openharmony/drivers_peripheral/tree/master/usb/gadget/function/
以上就是本期全部?jī)?nèi)容,通過本文的介紹相信你已經(jīng)對(duì)USB DDK有了深刻的認(rèn)識(shí),期待廣大的開發(fā)者加入我們,一起豐富基于USB DDK的第三方驅(qū)動(dòng)。
掃碼添加開發(fā)者小助手微信
獲取更多HarmonyOS開發(fā)資源和開發(fā)者活動(dòng)資訊
總結(jié)
以上是生活随笔為你收集整理的HarmonyOS USB DDK助你轻松实现USB驱动开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 石油勘探开发知识图谱技术实现思路探讨
- 下一篇: 2023中国科学技术大学计算机考研信息汇