USB學(xué)習(xí)筆記, 同時(shí)希望能幫助快速上手做USB應(yīng)用開發(fā).
整理自以下資料:
Universal Serial Bus Specification Revision 2.0
https://wenku.baidu.com/view/dd150ee3482fb4daa48d4b0a.html
USB的八個(gè)問(wèn)題和答案(出處不詳)
USB基礎(chǔ)知識(shí)概論 by Crifan Li
USB OTG協(xié)議基礎(chǔ)
OTG中的ID腳風(fēng)波釋疑
usb設(shè)備 配置 接口 端點(diǎn)
wiki
對(duì)于終端用戶來(lái)說(shuō),對(duì)USB最直觀的認(rèn)識(shí)就是USB的接口插頭,看圖:
現(xiàn)時(shí)間點(diǎn)大家最熟悉的幾種USB插頭莫過(guò)于USB2.0的TypeA、Mini-B、Micro-B;最近開始頻繁露臉的USB3.0的TypeA、TypeC。
USB是Universal Serial Bus的縮寫,中文譯為通用串行總線,USB出現(xiàn)之前,計(jì)算機(jī)領(lǐng)域中的接口太多太繁雜,USB出現(xiàn)之后減少了接口的種類,總的來(lái)說(shuō)就是設(shè)計(jì)出了一個(gè)萬(wàn)能的接口,各種外設(shè)都能用同一種接口,所以才冠以“通用(是Universal)”為名。
通用串行總線
非對(duì)稱式總線(Host drive), 就是說(shuō)任何一次通訊傳輸都是由主機(jī)(host)發(fā)起的
支持熱插拔(Plug-and-Play)
支持端口擴(kuò)展(Port Expansion), 也就是用戶可以用USB-HUB(usb擴(kuò)展塢)來(lái)擴(kuò)充USB接口的數(shù)量
支持多種速度的設(shè)備: 低速(Low Speed), 全速(Full Speed), 高速(High Speed), 還有USB3.0之后的SuperSpeed
可以對(duì)設(shè)備供電(也可以設(shè)備自供電)
維基百科圖:
維基百科圖:
主機(jī)就是USB總線中作主設(shè)備角色的設(shè)備, 負(fù)責(zé)管理USB總線中的數(shù)據(jù)傳輸及端口管理.
比如一個(gè)U盤(USB大容量?jī)?chǔ)存設(shè)備)和PC通訊, PC在這里就是USB Host.
USB Device就是在USB總線中作從設(shè)備角色的設(shè)備
它的實(shí)現(xiàn)也就是USB擴(kuò)展塢啦
USB Hub可以將一個(gè)USB口轉(zhuǎn)換為多個(gè)
USB Host帶有Root Hub
USB Hub對(duì)于上游而言是一個(gè)USB Device, 對(duì)于下游而言扮演USB Host, 所以USB設(shè)備本身不知道自己連接在Hub還是Root Hub上
該層為硬件設(shè)備連接. USB相關(guān)的基礎(chǔ)知識(shí) - USB相關(guān)的硬件中有更詳細(xì)的介紹.
Host側(cè), USB Host Controller(USB主控制器)是Host的具體硬件實(shí)現(xiàn), 如上文所說(shuō), 它負(fù)責(zé)USB總線中的數(shù)據(jù)傳輸及端口管理. 具體到摸得著的東西就是PC主板上與USB端口直接相連, 掛在PCI總線上, windows的設(shè)備管理器里可以看到這里有3個(gè)USB主控制器, 2個(gè)EHCI(USB 2.0),1個(gè)XHCI(USB 3.0):
Device側(cè), USB Bus Interface可以認(rèn)為是USB Devvice Controller(USB設(shè)備控制器).
該層可以理解為USB總線的驅(qū)動(dòng)層, 有關(guān)USB通訊的部分由這一層實(shí)現(xiàn), 為上層提供服務(wù).
Function也就是除了Hub以外的Device, 它為整個(gè)系統(tǒng)提供了某些具體能力, 比如U盤為系統(tǒng)提供儲(chǔ)存設(shè)備.
Host側(cè), Client SW(客戶軟件)具體就是對(duì)應(yīng)Device提供的Function的驅(qū)動(dòng), 不論是Linux下, 還是Windows下,都已經(jīng)實(shí)現(xiàn)了常見的驅(qū)動(dòng)了, 所以一般來(lái)說(shuō), 很少需要驅(qū)動(dòng)開發(fā)者再去寫驅(qū)動(dòng).
Device側(cè), Function則實(shí)現(xiàn)了具體的功能, 這部分通常由軟件實(shí)現(xiàn).
比如一個(gè)U盤(USB大容量?jī)?chǔ)存設(shè)備)接入U(xiǎn)SB系統(tǒng)后, Client SW為操作系統(tǒng)提供訪問(wèn)儲(chǔ)存設(shè)備的能力, 而Function則實(shí)現(xiàn)了操作存儲(chǔ)器件的功能比如在NandFlash芯片上讀寫數(shù)據(jù).
搞USB開發(fā), 我們關(guān)心的是Function Layer層通訊: 設(shè)備上Function通過(guò)Interface, 經(jīng)由Endpoint與Client SW通訊.
看上面的架構(gòu)圖, 可知一個(gè)Function里可以有多個(gè)Interface, 比如一個(gè)鍵盤可以和攝像頭做在一起, 用兩個(gè)Interface實(shí)現(xiàn).
端點(diǎn)是Device中的概念, 有點(diǎn)像Socket通訊中的Port(端口), 用于區(qū)分USB總線中當(dāng)?shù)臄?shù)據(jù)是哪個(gè)Interface的, 一個(gè)Interface可能使用了多個(gè)Endpoint. 端點(diǎn)是有方向的, 可以是IN(Device->Host)或者OUT(Host->Device). 端點(diǎn)可以理解成Deivce上的一個(gè)由USB Device管理的緩沖區(qū), 數(shù)據(jù)到達(dá)后通知上層Interface來(lái)處理.
管道表示主機(jī)與端點(diǎn)間的通訊, 是Host和Endpoint間抽象的傳輸通道, 可以理解為USB地址(枚舉時(shí)確定的地址)+EP編號(hào)構(gòu)成, 由Host側(cè)的System Drvier維護(hù)EP信息以便上層與Device通訊. 我們可以把端點(diǎn)和管道當(dāng)做同一個(gè)東西.
USB通訊實(shí)際上就是端點(diǎn)通訊,在Host看來(lái)每一個(gè)Device就是一堆端點(diǎn), Host通過(guò)端點(diǎn)與設(shè)備進(jìn)行通信,以使用設(shè)備的功能。每一個(gè)端點(diǎn)都有它的屬性,比如傳輸方式(Transfers, 后面會(huì)講)、總線訪問(wèn)頻率、帶寬、端點(diǎn)號(hào)和數(shù)據(jù)包的最大容量等。一個(gè)USB端點(diǎn)只能在一個(gè)方向承載數(shù)據(jù),或者從主機(jī)到設(shè)備(稱為輸出端點(diǎn)),或者從設(shè)備到主機(jī)(稱為輸入端點(diǎn)),因此端點(diǎn)可看作一個(gè)單向的管道。
包是在Pipe上傳輸?shù)臄?shù)據(jù)(包是由”域”組成的, 它是USB數(shù)據(jù)的最小單位, 這里不討論).
Transaction翻譯成”事務(wù)”, 我理解為”一次通訊過(guò)程”, 分別有IN事務(wù)、OUT事務(wù)和SETUP事務(wù)三大事務(wù), 每種事務(wù)通常由Token(令牌包)、Data(數(shù)據(jù)包)、Handshake(握手包)三個(gè)階段構(gòu)成,這里用階段的意思是因?yàn)檫@些包的發(fā)送是有一定的先后順序的:
先由主機(jī)發(fā)出Token, 指定數(shù)據(jù)包的目標(biāo)/來(lái)源(指定具體地址上的某Endpoint);
Data為數(shù)據(jù), IN事務(wù)時(shí)由設(shè)備
Handshake用來(lái)表示傳輸是否成功.
上圖就是典型的事務(wù): 主機(jī)發(fā)Token–數(shù)據(jù)包–握手包–結(jié)束
USB是主從式總線, 所以所有事務(wù)都是由主機(jī)發(fā)送的Token開始, 任一時(shí)刻USB系統(tǒng)中僅有一個(gè)包在傳輸.
傳輸由事務(wù)構(gòu)成, Endpoint的傳輸方式可以是以下四種中的其中一種.
這部分內(nèi)容涉及到較多細(xì)節(jié), 深入了解可查閱協(xié)議手冊(cè)的8.5章.
1 | Control data is used by the USB System Software to configure |
USB總線保證這種方式下數(shù)據(jù)不會(huì)丟失. 用于Device插入后配置/獲取設(shè)備信息, 設(shè)備也可以自定用途, 比如用于查詢?cè)O(shè)備狀態(tài).
SETUP事務(wù)圖示:
控制傳輸?shù)腞ead/Write序列, 讀寫操作由一串有序的事務(wù)組成:
1 | Bulk data typically consists of larger amounts of data, |
用于可靠傳輸大量數(shù)據(jù), 單次允許傳輸更多的數(shù)據(jù)(所以在Device中它們端點(diǎn)的緩存區(qū)會(huì)更大), 保證數(shù)據(jù)的正確性但不保證實(shí)時(shí)性(取決于總線的繁忙程度).
如打印機(jī)/掃描儀.
1 | A limited-latency transfer to or from a device is referred to |
用于少量數(shù)據(jù)的低延遲傳輸, Host以不低于Device指定的頻率向設(shè)備發(fā)令牌請(qǐng)求數(shù)據(jù), 也可以由Host向Device發(fā)送數(shù)據(jù).
比如鍵盤/鼠標(biāo)/游戲控制器就用這種方式來(lái)傳輸.
通常不用來(lái)傳送大量數(shù)據(jù).
1 | Isochronous data is continuous and real-time in creation, |
用于傳輸大量數(shù)據(jù), 不要求可靠性但要求實(shí)時(shí)性. 類似中斷傳輸, 同步傳輸也是由Host周期訪問(wèn)設(shè)備, 只是同步傳輸不能保證數(shù)據(jù)成功傳輸.
適用于音頻和視頻設(shè)備, 如麥克風(fēng)/攝像頭.
為了能讓最常用的設(shè)備普及和提高兼容性, USB組織定義了很多標(biāo)準(zhǔn)Class, 比如HID(人體輸入設(shè)備), Mass Storage(大容量?jī)?chǔ)存設(shè)備), 這些設(shè)備接入Host上一般不需要額外的驅(qū)動(dòng), 因?yàn)橐呀?jīng)預(yù)置了通用的驅(qū)動(dòng), 做USB應(yīng)用很多時(shí)候都是在某個(gè)Class上做開發(fā).
Device的廠商也可以在Class的基礎(chǔ)上做一些定義(當(dāng)然這時(shí)候就要在Host上做專門的驅(qū)動(dòng)了).
另外Class下也會(huì)有Sub Class, 比如HID下還分鼠標(biāo)鍵盤等.
USB接口設(shè)備Class文檔可以找到各Class的文檔
既然USB是種通用串行口, 插入U(xiǎn)SB設(shè)備到主機(jī)之后, 主機(jī)又怎么知道插入的是什么設(shè)備(USB版本? PID/VID? 端點(diǎn)數(shù)量和傳輸能力如何?), 實(shí)現(xiàn)了什么功能呢(有哪些Function/Interface?), 把這些信息弄清楚的過(guò)程叫做枚舉.
該部分內(nèi)容對(duì)應(yīng)協(xié)議手冊(cè)的第9章.
設(shè)備狀態(tài)圖如下, 枚舉就是從Attached狀態(tài)轉(zhuǎn)換到Configured狀態(tài)的過(guò)程:
1、接入態(tài)(Attached):設(shè)備接入主機(jī)后,主機(jī)通過(guò)檢測(cè)信號(hào)線上的電平變化來(lái)發(fā)現(xiàn)設(shè)備的接入;
2、供電態(tài)(Powered):就是給設(shè)備供電,分為設(shè)備接入時(shí)的默認(rèn)供電值,配置階段后的供電值(按數(shù)據(jù)中要求的最大值,可通過(guò)編程設(shè)置)
3、缺省態(tài)(Default):USB在被配置之前,通過(guò)缺省地址0與主機(jī)進(jìn)行通信;
4、地址態(tài)(Address):經(jīng)過(guò)了配置,USB設(shè)備被復(fù)位后,就可以按主機(jī)分配給它的唯一地址來(lái)與主機(jī)通信,這種狀態(tài)就是地址態(tài);
5、配置態(tài)(Configured):通過(guò)各種標(biāo)準(zhǔn)的USB請(qǐng)求命令來(lái)獲取設(shè)備的各種信息,并對(duì)設(shè)備的某此信息進(jìn)行改變或設(shè)置。
6、掛起態(tài)(Suspended):總線供電設(shè)備在3ms內(nèi)沒(méi)有總線操作,即USB總線處于空閑狀態(tài)的話,該設(shè)備就要自動(dòng)進(jìn)入掛起狀態(tài),在進(jìn)入掛起狀態(tài)后,總的電流功耗不超過(guò)280UA。
1 | All USB devices are required to implement a default control method |
所有USB設(shè)備需要實(shí)現(xiàn)一個(gè)默認(rèn)的控制方式, 它就是既能輸入也能輸出的端點(diǎn)0, Host通過(guò)這端點(diǎn)0獲取設(shè)備的描述、配置、狀態(tài),對(duì)設(shè)備進(jìn)行設(shè)置。
端點(diǎn)0在Device上電后就默認(rèn)存在, 這是STM32HAL庫(kù)中重置USBD的代碼, 可見對(duì)EP0_IN和EP0_OUT進(jìn)行了配置:
可見, 端點(diǎn)0實(shí)際上是IN/OUT兩個(gè)端點(diǎn), 以控制傳輸(Control Transfers)的方式通訊.
通過(guò)端點(diǎn)0, Host可以使用一些”默認(rèn)的控制方式”完成一些基本的操作, 每個(gè)Device都要實(shí)現(xiàn)這些操作, 這就是”通用USB設(shè)備操作”.
閱讀bmRequestType定義可知, “USB設(shè)備請(qǐng)求”允許Host通過(guò)端點(diǎn)0使用控制傳輸方式向USB設(shè)備發(fā)出請(qǐng)求, 這些請(qǐng)求可以是”標(biāo)準(zhǔn)設(shè)備請(qǐng)求”/“Class求”/“設(shè)備制造商自定義請(qǐng)求”.
“標(biāo)準(zhǔn)設(shè)備請(qǐng)求”是”通用USB設(shè)備操作”的具體實(shí)現(xiàn), 它規(guī)定了一些命令比如”Set Descriptor”(獲取描述符)/“Set Configuration”(設(shè)置配置索引), 使用這些命令可以完成枚舉過(guò)程(但不僅用于枚舉).
描述符儲(chǔ)存在設(shè)備中, 有幾種描述符儲(chǔ)存著設(shè)備的各種信息, 枚舉過(guò)程中主機(jī)通過(guò)標(biāo)準(zhǔn)設(shè)備請(qǐng)求從設(shè)備獲取這些描述符.
標(biāo)準(zhǔn)描述符(Standard USB Descriptor)包含以下幾種:
設(shè)備(Devcie)描述符, USB版本號(hào)、設(shè)備類型等信息,一個(gè)USB設(shè)備只有一個(gè)設(shè)備描述符;
配置(Configuration)描述符, 描述一個(gè)USB設(shè)備的屬性和能力等配置信息,如接口總數(shù)、當(dāng)前配置、供電方式、遠(yuǎn)程喚醒和須獲取電流量等,一個(gè)USB設(shè)備可以有幾種相對(duì)獨(dú)立的配置;
接口(Interface)描述符, 描述一個(gè)接口的屬性,如接口類型、使用了哪些非0端點(diǎn)等。一個(gè)配置可擁n個(gè)接口,每個(gè)接口有唯一編號(hào);
端點(diǎn)(Endpoint)描述符, 描述非0端點(diǎn)的屬性,包括輸入/輸出方向、端點(diǎn)號(hào)和端點(diǎn)容量。需注意的是端點(diǎn)描述符是作為配置描述符的一部分來(lái)返回給主機(jī)的,而不能直接通過(guò)控制傳輸中的Get_Descriptor
或Set_Descriptor
來(lái)訪問(wèn);
字符串(String)描述符, 用于存放一些字符串, 其他描述符可以用索引號(hào)來(lái)引用其中的字符串
各類描述符的具體定義請(qǐng)參考USB2.0協(xié)議手冊(cè)9.6章及其他資料.
主機(jī)獲取配置描述符時(shí), 接口描述符/端點(diǎn)描述符/等等相關(guān)的描述符附著在它后面一同提交.
梳理一下Endpoint/Interface/Configuration間的關(guān)系:
一個(gè)Device可以有多個(gè)Configuration, 提供多個(gè)Configuration, 枚舉期間由Host按需選其一
一個(gè)Configuration可以有多個(gè)Interface (多個(gè)Interface的設(shè)備稱為組合設(shè)備Composite Device)
一個(gè)Interface可以使用多個(gè)Endpoint(也可以不使用端點(diǎn))
假設(shè)一個(gè)配置集合包含2個(gè)Interface, 均為XXX Class, 每個(gè)Interface兩個(gè)Endpoint, 那么它大概是這個(gè)樣子:
1 | 配置描述符(bNumInterfaces=2) |
這部分在USB基礎(chǔ)知識(shí)概論的4.4章中講得很清楚了, 這里為了防死鏈復(fù)制一份pdf.
對(duì)于工程師來(lái)說(shuō), 文檔永遠(yuǎn)是你最值得信任的伙伴(除了文檔還太新沒(méi)幾個(gè)勘誤表的時(shí)候..).
這本書很大白話, 實(shí)現(xiàn)了HID鼠標(biāo)/HID鍵盤/CDC串口/MIDI設(shè)備/U盤/自定義設(shè)備和驅(qū)動(dòng)開發(fā), 推薦.
免費(fèi)/開源軟件, 顯示USB設(shè)備樹形結(jié)構(gòu), 顯示設(shè)備連接信息/描述符, 枚舉時(shí)調(diào)試比較方便.
強(qiáng)力的調(diào)試工具, 能抓USB包, 免費(fèi)版只能捕獲最多32條數(shù)據(jù), 每條數(shù)據(jù)最多8字節(jié), 完整版價(jià)格400刀每用戶.
官網(wǎng)
付費(fèi)軟件, 看起來(lái)很強(qiáng)大, 沒(méi)實(shí)際用過(guò).
聯(lián)系客服