1 USB檢測(cè)與枚舉過程
1.1 USB插拔檢測(cè)
https://blog.csdn.net/u013836909/article/details/104886626 USB集線器的每個(gè)下游端口的D+和D-上,分別接了一個(gè)15K的下拉電阻到低。當(dāng)集線器的端口懸空(即沒有設(shè)備插入)時(shí),輸入端就被此兩個(gè)下拉電阻拉到低電平。在USB設(shè)備端,在D+或D-上接入1.5K的上拉電阻到3.3V的電源。1.5K的上拉電阻接在D+或D-上,由設(shè)備的速度決定。對(duì)于全速設(shè)備和高速設(shè)備,上拉電阻接在D+上,而低速設(shè)備的上拉電阻則是接在D-上??珊?jiǎn)單記為:速度快的,上拉電阻接正;速度慢的,上拉電阻接負(fù)的。
當(dāng)設(shè)備插入到集線器時(shí),接了上拉電阻的數(shù)據(jù)線的電壓由1.5K的上拉電阻和15K的下拉電阻分壓決定,結(jié)果大概為3V。在集線器的接收端來說,是一個(gè)高電平信號(hào)。集線器檢測(cè)到此狀態(tài)后,就報(bào)告給USB主控制器,此時(shí)就檢測(cè)到設(shè)備的插入。USB高速設(shè)備先是識(shí)別成全速設(shè)備,然后在通過集線器和設(shè)備兩者的確認(rèn),在切換到高速模式下。在高速模式下,是電流傳輸模式,此時(shí)需要將D+上的上拉電阻斷開。
1.2 USB枚舉過程
1) USB主機(jī)檢測(cè)到USB設(shè)備插入后,會(huì)先對(duì)設(shè)備進(jìn)行復(fù)位。 USB設(shè)備在總線復(fù)位后其地址為0,此時(shí)主機(jī)可通過地址0和該設(shè)備進(jìn)行通信。USB主機(jī)往地址0的設(shè)備的端點(diǎn)0發(fā)送獲取設(shè)備描述符的標(biāo)準(zhǔn)請(qǐng)求(這是控制傳輸?shù)慕⑦^程)。設(shè)備收到該請(qǐng)求后,會(huì)按主機(jī)請(qǐng)求的參數(shù),在數(shù)據(jù)過程將設(shè)備描述符返回給主機(jī)。主機(jī)在成功獲取到該數(shù)據(jù)包的設(shè)備描述符并且確認(rèn)沒有錯(cuò)誤后,就會(huì)返回一個(gè)0長(zhǎng)度的確認(rèn)數(shù)據(jù)包(狀態(tài)過程)給設(shè)備,從而進(jìn)入到接下來的設(shè)置地址階段。注意:第一次主機(jī)只會(huì)讀取一個(gè)數(shù)據(jù)包的設(shè)備描述符,標(biāo)準(zhǔn)的設(shè)備描述符有18byte,有些USB設(shè)備的端點(diǎn)0大小不足18byte(但至少具有8byte),這種情況下,USB主機(jī)也只發(fā)送一次數(shù)據(jù)輸入請(qǐng)求,多余的數(shù)據(jù)將不會(huì)再次請(qǐng)求。因此,如果當(dāng)設(shè)備斷電0大小不足18字節(jié)時(shí),就需要注意該問題,也就是說在第一次獲取設(shè)備描述符時(shí),只需要返回一次數(shù)據(jù)即可,不需要再等主句繼續(xù)獲取剩余數(shù)據(jù)(如果還有),因?yàn)橹鳈C(jī)不會(huì)這么干的。房主急成功獲取到設(shè)備描述符的前8byte之后,他就知道端點(diǎn)0的最大包長(zhǎng)度了,因?yàn)槎它c(diǎn)0最大包長(zhǎng)度剛好在設(shè)備描述符的第八字節(jié)處。
2) USB主機(jī)對(duì)設(shè)備又一次復(fù)位,開始設(shè)置地址階段。 USB主機(jī)往地址為0的設(shè)備的端點(diǎn)0發(fā)出一個(gè)設(shè)置地址的請(qǐng)求(控制傳輸?shù)慕⑦^程),新的設(shè)備地址包含在建立過程的數(shù)據(jù)包中。具體的地址有USB主機(jī)負(fù)責(zé)管理,主機(jī)會(huì)分配一個(gè)唯一的地址給剛接入的設(shè)備。USB設(shè)備在收到這個(gè)建立過程之后,就直接進(jìn)入到狀態(tài)過程,因?yàn)榇丝刂苽鬏敍]有數(shù)據(jù)過程。設(shè)備等待主機(jī)請(qǐng)求狀態(tài)返回(一個(gè)輸入令牌包),收到輸入令牌包后,設(shè)備就返回0長(zhǎng)度的狀態(tài)數(shù)據(jù)包。如果主機(jī)確認(rèn)該狀態(tài)包已經(jīng)正確收到,就會(huì)發(fā)送應(yīng)答包ACK給設(shè)備,設(shè)備在收到這個(gè)ACK之后,就要啟用新的設(shè)備地址了。這樣設(shè)備就分配到了一個(gè)唯一的設(shè)備地址,以后主機(jī)就通過他來訪問該設(shè)備。
3) USB主機(jī)重新發(fā)送獲取設(shè)備描述符的命令,讀取完整設(shè)備描述符。 主機(jī)向新地址重新發(fā)送Get_Device_Descriptor命令,此次讀取其設(shè)備描述符的全部字段,以了解該設(shè)備的總體信息,如VID,PID。
4) USB主機(jī)獲取配置描述符。 配置描述符總共9byte。主機(jī)在獲取到配置描述符之后,根據(jù)配置描述符中描述的配置集合總長(zhǎng)度,獲取配置集合。獲取配置描述符和獲取配置描述符集合的請(qǐng)求是差不多的,只是指定的長(zhǎng)度不一樣。
5) USB主機(jī)獲取設(shè)備字符串,獲得描述字符集。 描述字符集包括了產(chǎn)商、產(chǎn)品描述、型號(hào)等信息。
6) USB主機(jī)展示新設(shè)備信息。 此時(shí)主機(jī)將會(huì)彈出窗口,展示發(fā)現(xiàn)新設(shè)備的信息、產(chǎn)商、產(chǎn)品描述、型號(hào)等。
7) PC判斷能夠提供該類USB的驅(qū)動(dòng)。 根據(jù)設(shè)備描述符和配置描述符,PC判斷是否能夠提供USB的Driver,一般能提供幾大類的設(shè)備,如游戲操作桿、存儲(chǔ)、打印機(jī)、掃描儀等。
8) USB主機(jī)發(fā)送配置命令,請(qǐng)求為設(shè)備選擇一個(gè)配置 加載USB設(shè)備驅(qū)動(dòng)以后,主機(jī)發(fā)送Set_Configuration(x)命令請(qǐng)求為該設(shè)備選擇一個(gè)合適的配置。如果配置成功,USB設(shè)備進(jìn)入“配置”狀態(tài),并可以和客戶軟件進(jìn)行數(shù)據(jù)傳輸。
1.3 虛擬串口枚舉流程
1.3.1 第一次獲取設(shè)備描述符
struct usb_ctrlrequest {
__u8 bRequestType = 0x80;// 這是一個(gè)主機(jī)發(fā)給設(shè)備(bit0~bit4)的一個(gè)標(biāo)準(zhǔn)(bit5~bit6)的請(qǐng)求命令,請(qǐng)求的結(jié)果是要求設(shè)備給Host返回(bit7 == 1)
__u8 bRequest = 0x06;// 是一個(gè)GET_DESCRIPTOR,即獲取描述符的請(qǐng)求
__le16 wValue = 0x0100;// 高字節(jié)表示描述符類型,01表示設(shè)備,02表示配置;低字節(jié)表示索引。
__le16 wIndex = 0x0000;
__le16 wLength = 0x0040;
} __attribute__ ((packed));
struct usb_device_descriptor {
__u8 bLength = 0x12; ///長(zhǎng)度
__u8 bDescriptorType = 0x01; ///描述符類型
__le16 bcdUSB = 0x0200; //該位表示版本號(hào),使用BCD碼表示,即USB2.0版本
__u8 bDeviceClass = 0x02;///設(shè)備類信息
__u8 bDeviceSubClass = 0x00;///設(shè)備子類型
__u8 bDeviceProtocol = 0x00;///協(xié)議 碼,0表示沒指定任何協(xié)議
__u8 bMaxPacketSize0 = 0x40;///端點(diǎn)0最大傳輸大小
__le16 idVendor = 0x0525;///廠商 ID
__le16 idProduct = 0xa4a7;///設(shè)備 ID
__le16 bcdDevice = 0x0414;/// 設(shè)備版本號(hào)
__u8 iManufacturer = 0x01; ///描述廠商信息的字符串描述符的索引值
__u8 iProduct = 0x02;///描述產(chǎn)品信息的字串描述符的索引值
__u8 iSerialNumber = 0x00;///描述設(shè)備序列號(hào)信息的字串描述符的索引值-03
__u8 bNumConfigurations = 0x01;///設(shè)備當(dāng)前速度模式下支持的配置數(shù)量。有的設(shè)備可以在多個(gè)速度模式下操作,這里包括的只是當(dāng)前速度模式下的配置數(shù)目,不是總的配置數(shù)目
} __attribute__ ((packed));
1.3.2 第二次設(shè)備復(fù)位
host通過驅(qū)動(dòng)數(shù)據(jù)線到復(fù)位狀態(tài)(D+和D-全為低電平 ),并持續(xù)至少10ms。
1.3.3 分配設(shè)備地址
struct usb_ctrlrequest {
__u8 bRequestType = 0x00;// 這是一個(gè)主機(jī)發(fā)給設(shè)備(bit0~bit4)的一個(gè)標(biāo)準(zhǔn)(bit5~bit6)的請(qǐng)求命令,請(qǐng)求的結(jié)果是要求設(shè)備給Host返回(bit7 == 1)
__u8 bRequest = 0x05;// 是一個(gè)SET_ADDRESS,即配置設(shè)備地址描述符
__le16 wValue = 0x0025;// 表示設(shè)備地址為0x25。
__le16 wIndex = 0x0000;
__le16 wLength = 0x0000;
} __attribute__ ((packed));
1.3.4 第二次獲取設(shè)備描述符
這次要注意,這里以及使用新分配的設(shè)備地址3了,而不是默認(rèn)地址0。同時(shí)后面也都會(huì)使用新分配的地址來通信。
1.3.5 第一次獲取設(shè)備配置
struct usb_ctrlrequest {
__u8 bRequestType = 0x80;// 這是一個(gè)主機(jī)發(fā)給設(shè)備(bit0~bit4)的一個(gè)標(biāo)準(zhǔn)(bit5~bit6)的請(qǐng)求命令,請(qǐng)求的結(jié)果是要求設(shè)備給Host返回(bit7 == 1)
__u8 bRequest = 0x06;// 是一個(gè)GET_DESCRIPTOR,即獲取描述符的請(qǐng)求
__le16 wValue = 0x0002;// 高字節(jié)表示描述符類型,01表示設(shè)備,02表示配置。
__le16 wIndex = 0x0000;
__le16 wLength = 0x00FF;
} __attribute__ ((packed));
1.3.5.1 獲取配置描述符
struct usb_config_descriptor {
__u8 bLength = 0x09; //此描述符長(zhǎng)度為9
__u8 bDescriptorType = 0x02; // 2代表的配置描述符
__le16 wTotalLength = 0x4b; //此配置信息的總長(zhǎng)為34字節(jié)(包括配置,接口,端點(diǎn)和設(shè)備類及廠商定義的描述符)
__u8 bNumInterfaces = 0x02; //表示有一個(gè)接口描述符
__u8 bConfigurationValue = 0x02; //在SetConfiguration()請(qǐng)求中用2作參數(shù)來選定此配置-0x01
__u8 iConfiguration = 0x04; //描述此配置的字串描述表索引-0x00
__u8 bmAttributes = 0xC0; //D7: 保留(設(shè)為一)D6: 自給電源 D5: 遠(yuǎn)程喚醒 D4..0:保留(設(shè)為一) 表示這是一個(gè)由總線供電,并支持遠(yuǎn)程喚醒功能(可以睡眠節(jié)約電)
__u8 bMaxPower = 0x64; //在此配置下的總線電源耗費(fèi)量。以 2mA 為一個(gè)單位 即2 * 50 = 100ms
} __attribute__ ((packed));
1.3.5.2 獲取接口關(guān)聯(lián)描述符
struct usb_interface_assoc_descriptor {
__u8 bLength = 0x08;
__u8 bDescriptorType = 0x0b; //IAD描述符類型
__u8 bFirstInterface = 0x00; //起始接口
__u8 bInterfaceCount = 0x02; //接口數(shù)量
__u8 bFunctionClass = 0x02; //類型代碼
__u8 bFunctionSubClass = 0x02; //子類型代碼
__u8 bFunctionProtocol = 0x01; //協(xié)議代碼
__u8 iFunction = 0x07; //描述字符串索引
} __attribute__ ((packed));
1.3.5.3 獲取設(shè)備接口描述符
struct usb_interface_descriptor {
__u8 bLength = 0x09; //該描述符的字節(jié)數(shù)
__u8 bDescriptorType = 0x04; //描述符類型,4代表接口描述符
__u8 bInterfaceNumber = 0x00; //接口號(hào),當(dāng)前配置支持的接口數(shù)組索引(從零開始)
__u8 bAlternateSetting = 0x00; //可選設(shè)置的索引值,這里無
__u8 bNumEndpoints = 0x01; //端點(diǎn)描述符數(shù)量,1個(gè)
__u8 bInterfaceClass = 0x02; //接口所屬的類值,由USB說明保留, 2代表CDC contrl
__u8 bInterfaceSubClass = 0x02; //子類碼 這些值的定義視bInterfaceClass域而定
__u8 bInterfaceProtocol = 0x01; //協(xié)議碼:bInterfaceClass 和bInterfaceSubClass 域的值而定
__u8 iInterface = 0x05; //描述此接口的字串描述表的索引值
} __attribute__ ((packed));
1.3.5.4 Header Functional Descriptor
/* "Header Functional Descriptor" from CDC spec 5.2.3.1 */
struct usb_cdc_header_desc {
__u8 bLength = 0x05;
__u8 bDescriptorType = 0x24; /* bDescriptorType: CS_INTERFACE */
__u8 bDescriptorSubType = 0x00; /* bDescriptorSubtype: Header Func Desc */
__le16 bcdCDC = 0x0110; /* bcdCDC: spec release number */
} __attribute__ ((packed));
1.3.5.5 Abstract Control Management Descriptor
/* "Abstract Control Management Descriptor" from CDC spec 5.2.3.3 */
struct usb_cdc_acm_descriptor {
__u8 bLength = 0x04;
__u8 bDescriptorType = 0x24;
__u8 bDescriptorSubType = 0x02; /* bDescriptorSubtype: Abstract Control Management desc */
__u8 bmCapabilities 0x02;
} __attribute__ ((packed));
1.3.5.6 Union Functional Descriptor
/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
struct usb_cdc_union_desc {
__u8 bLength = 0x05;
__u8 bDescriptorType = 0x24;
__u8 bDescriptorSubType = 0x06; /* bDescriptorSubtype: Union func desc */
__u8 bMasterInterface0 = 0x00;
__u8 bSlaveInterface0 = 0x01;
/* ... and there could be other slave interfaces */
} __attribute__ ((packed));
1.3.5.7 Call Management Descriptor
/* "Call Management Descriptor" from CDC spec 5.2.3.2 */
struct usb_cdc_call_mgmt_descriptor {
__u8 bLength = 0x05;
__u8 bDescriptorType = 0x24; /* bDescriptorType: CS_INTERFACE */
__u8 bDescriptorSubType = 0x01; /* bDescriptorSubtype: Call Management Func Desc */
__u8 bmCapabilities = 0x00; /* bmCapabilities: D0+D1 */
__u8 bDataInterface = 0x01; /* bDataInterface: 1 *
} __attribute__ ((packed));
1.3.5.8 獲取notify端點(diǎn)描述符
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor { ///USB 端點(diǎn)描述符(每個(gè)USB設(shè)備最多有16個(gè)端點(diǎn))
__u8 bLength = 0x07; ///描述符的字節(jié)長(zhǎng)度
__u8 bDescriptorType = 0x05;///描述符類型,對(duì)于端點(diǎn)就是USB_DT_ENDPOINT
__u8 bEndpointAddress = 0x83;///bit0~3表示端點(diǎn)地址,bit8 表示方向,輸入還是輸出
__u8 bmAttributes = 0x03;///屬性(bit0、bit1構(gòu)成傳輸類型,00--控制,01--等時(shí),10--批量,11--中斷)
__le16 wMaxPacketSize = 0x000a;///端點(diǎn)一次可以處理的最大字節(jié)數(shù)
__u8 bInterval = 0x20;///希望主機(jī)輪詢自己的時(shí)間間隔
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
1.3.5.9 獲取數(shù)據(jù)類接口描述符
struct usb_interface_descriptor {
__u8 bLength = 0x09; //該描述符的字節(jié)數(shù)
__u8 bDescriptorType = 0x04; //描述符類型,4代表接口描述符
__u8 bInterfaceNumber = 0x01; //接口號(hào),當(dāng)前配置支持的接口數(shù)組索引(從零開始)
__u8 bAlternateSetting = 0x00; //可選設(shè)置的索引值,這里無
__u8 bNumEndpoints = 0x02; //端點(diǎn)描述符數(shù)量,2個(gè)
__u8 bInterfaceClass = 0x0A; //接口所屬的類值,由USB說明保留, 2代表CDC data
__u8 bInterfaceSubClass = 0x00; //子類碼 這些值的定義視bInterfaceClass域而定
__u8 bInterfaceProtocol = 0x00; //協(xié)議碼:bInterfaceClass 和bInterfaceSubClass 域的值而定
__u8 iInterface = 0x06; //描述此接口的字串描述表的索引值
} __attribute__ ((packed));
1.3.5.10 獲取OUT端點(diǎn)描述符
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor { ///USB 端點(diǎn)描述符(每個(gè)USB設(shè)備最多有16個(gè)端點(diǎn))
__u8 bLength = 0x07; ///描述符的字節(jié)長(zhǎng)度
__u8 bDescriptorType = 0x05;///描述符類型,對(duì)于端點(diǎn)就是USB_DT_ENDPOINT
__u8 bEndpointAddress = 0x02;///bit0~3表示端點(diǎn)地址,bit8 表示方向,輸入還是輸出
__u8 bmAttributes = 0x02;///屬性(bit0、bit1構(gòu)成傳輸類型,00--控制,01--等時(shí),10--批量,11--中斷)
__le16 wMaxPacketSize = 0x40;///端點(diǎn)一次可以處理的最大字節(jié)數(shù)
__u8 bInterval = 0x00;///希望主機(jī)輪詢自己的時(shí)間間隔
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
1.3.5.11 獲取IN端點(diǎn)描述符
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor { ///USB 端點(diǎn)描述符(每個(gè)USB設(shè)備最多有16個(gè)端點(diǎn))
__u8 bLength = 0x07; ///描述符的字節(jié)長(zhǎng)度
__u8 bDescriptorType = 0x05;///描述符類型,對(duì)于端點(diǎn)就是USB_DT_ENDPOINT
__u8 bEndpointAddress = 0x81;///bit0~3表示端點(diǎn)地址,bit8 表示方向,輸入還是輸出
__u8 bmAttributes = 0x02;///屬性(bit0、bit1構(gòu)成傳輸類型,00--控制,01--等時(shí),10--批量,11--中斷)
__le16 wMaxPacketSize = 0x40;///端點(diǎn)一次可以處理的最大字節(jié)數(shù)
__u8 bInterval = 0x00;///希望主機(jī)輪詢自己的時(shí)間間隔
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
1.3.6 獲取設(shè)備字符串描述符
1.3.6.1 獲取字符串描述符語言ID
struct usb_ctrlrequest {
__u8 bRequestType = 0x80;// 這是一個(gè)主機(jī)發(fā)給設(shè)備(bit0~bit4)的一個(gè)標(biāo)準(zhǔn)(bit5~bit6)的請(qǐng)求命令,請(qǐng)求的結(jié)果是要求設(shè)備給Host返回(bit7 == 1)
__u8 bRequest = 0x06;// 是一個(gè)GET_DESCRIPTOR,即獲取描述符的請(qǐng)求
__le16 wValue = 0x0300;// 高字節(jié)表示描述符類型,01表示設(shè)備,02表示配置,3表示字符串;低字節(jié)表示索引。
__le16 wIndex = 0x0000;
__le16 wLength = 0x00FF;
} __attribute__ ((packed));
/* USB_DT_STRING: String descriptor */
struct usb_string_descriptor {
__u8 bLength = 0x04;
__u8 bDescriptorType = 0x03;
__le16 wData[1] = 0x0409;/* UTF-16LE encoded 代表0x0409的語言編碼 */
} __attribute__ ((packed));
1.3.6.2 獲取字符串描述符(產(chǎn)品信息)
struct usb_ctrlrequest {
__u8 bRequestType = 0x80;// 這是一個(gè)主機(jī)發(fā)給設(shè)備(bit0~bit4)的一個(gè)標(biāo)準(zhǔn)(bit5~bit6)的請(qǐng)求命令,請(qǐng)求的結(jié)果是要求設(shè)備給Host返回(bit7 == 1)
__u8 bRequest = 0x06;// 是一個(gè)GET_DESCRIPTOR,即獲取描述符的請(qǐng)求
__le16 wValue = 0x0301;// 高字節(jié)表示描述符類型,01表示設(shè)備,02表示配置,3表示字符串;低字節(jié)表示索引。
__le16 wIndex = 0x0000;
__le16 wLength = 0x00FF;
} __attribute__ ((packed));
/* USB_DT_STRING: String descriptor */
struct usb_string_descriptor {
__u8 bLength = 0x04;
__u8 bDescriptorType = 0x03;
__le16 wData[1] = “Gadget Serial v2.4”;/
} __attribute__ ((packed));
1.3.6.3 獲取字符串描述符(商家信息)
無。
1.3.7 第三次獲取設(shè)備描述符
同上。
1.3.8 第二次獲取設(shè)備配置
同上。
1.3.9 選中設(shè)備配置
struct usb_ctrlrequest {
__u8 bRequestType = 0x00;// 這是一個(gè)主機(jī)發(fā)給設(shè)備(bit0~bit4)的一個(gè)標(biāo)準(zhǔn)(bit5~bit6)的請(qǐng)求命令,請(qǐng)求的結(jié)果是要求設(shè)備給Host返回(bit7 == 1)
__u8 bRequest = 0x09;// 是一個(gè)SET_CONFIGURATION,即配置設(shè)備。
__le16 wValue = 0x0001;// 表示選中的配置Index
__le16 wIndex = 0x0000;
__le16 wLength = 0x0000;
} __attribute__ ((packed));
1.3.10 獲取Line_Coding
struct usb_ctrlrequest {
__u8 bRequestType = 0xA1;// 這是一個(gè)主機(jī)發(fā)給設(shè)備(bit0~bit4)的一個(gè)標(biāo)準(zhǔn)(bit5~bit6)的請(qǐng)求命令,請(qǐng)求的結(jié)果是要求設(shè)備給Host返回(bit7 == 1)
__u8 bRequest = 0x21;
__le16 wValue = 0x0000;
__le16 wIndex = 0x0000;
__le16 wLength = 0x0007;
} __attribute__ ((packed));
/* Line Coding Structure from CDC spec 6.2.13 */
struct usb_cdc_line_coding {
__le32 dwDTERate = 0x00;
__u8 bCharFormat = 0x00;
#define USB_CDC_1_STOP_BITS 0
#define USB_CDC_1_5_STOP_BITS 1
#define USB_CDC_2_STOP_BITS 2
__u8 bParityType = 0x00;
#define USB_CDC_NO_PARITY 0
#define USB_CDC_ODD_PARITY 1
#define USB_CDC_EVEN_PARITY 2
#define USB_CDC_MARK_PARITY 3
#define USB_CDC_SPACE_PARITY 4
__u8 bDataBits = 0x00;
} __attribute__ ((packed));
1.3.11 配置Line_Coding
struct usb_ctrlrequest {
__u8 bRequestType = 0x21;// 這是一個(gè)主機(jī)發(fā)給設(shè)備(bit0~bit4)的一個(gè)標(biāo)準(zhǔn)(bit5~bit6)的請(qǐng)求命令,請(qǐng)求的結(jié)果是要求設(shè)備給Host返回(bit7 == 1)
__u8 bRequest = 0x22;
__le16 wValue = 0x0000;
__le16 wIndex = 0x0000;
__le16 wLength = 0x0000;
} __attribute__ ((packed));
|