天天看點

USB協定簡介1.USB協定簡介

1.USB協定簡介

https://blog.csdn.net/songze_lee/article/details/77658094

2017年08月28日 23:20:16 songze_lee 閱讀數:22978

 版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/songze_lee/article/details/77658094

         最近學習usb相關的知識,一直感覺入不了門,看《linux那些事兒之我是usb》,對usb協定也不是很熟悉,沒能堅持看下去,直到看了《圈圈教你玩usb》一書,把自己的興趣立馬提了起來,大牛圈圈用51單片機實作了usb滑鼠鍵盤等裝置,讓人非常佩服,51單片機自己還是很熟悉,大學玩了四年單片機,單片機來實作立馬感覺親切了許多,決定先從單片機入手學,後面再看linux那些事兒之我是usb,深入學習linux核心下usb,以下先介紹usb協定,内容整理來自usb spec、網絡和圈圈書中,文中也大量引用STM32官方的USB2.0協定文檔,歡迎批評指正。另外學習《圈圈教你玩usb》動手調試實作了單片機usb滑鼠功能,源碼在https://github.com/lisongze2016/mcu_project/tree/master/USB,源碼中結合使用了linux kernel ch9.h中對描述符的結構體定義,對usb協定有了深入的了解。

        USB(Universal Serial Bus)全稱通用序列槽總線,USB為解決即插即用需求而誕生,支援熱插拔。USB協定版本有USB1.0、USB1.1、USB2.0、USB3.1等,USB2.0目前比較常用,以下以2.0為主介紹。由于USB是主從模式的結構,裝置與裝置之間、主機與主機之間不能互連,為解決這個問題,擴大USB的應用範圍,出現了USB OTG,全拼 ON The Go。USB OTG 同一個裝置,在不同的場合下可行在主機和從機之間切換。

1.1 USB特點:

USB1.0和USB1.1支援1.5Mb/s的低速模式和12Mb/bs的全速模式。在USB2.0以上支援480Mb/s的高速模式。應用如下:

USB協定簡介1.USB協定簡介

1.2 USB裝置供電方式:

USB裝置有兩種供電方式 

自供電裝置:裝置從外部電源擷取工作電壓 

總線供電裝置:裝置從VBUS(5v) 取電 

  對總線供電裝置,區分低功耗和高功耗USB裝置 

低功耗總線供電裝置:最大功耗不超過100mA 

高功耗總線供電裝置: 枚舉時最大功耗不超過100mA,枚舉完成配置結束後功耗不超過500mA 

裝置在枚舉過程中,通過裝置的配置描述符向主機報告它的供電配置(自供電/總線供電)以及它的功耗要求

如下 USB 配置描述符(以Joystick為例),後面具體介紹:

USB協定簡介1.USB協定簡介

1.3 USB總線信号:

USB使用的是差分傳輸模式,兩個資料線D+和D- 

        差分信号1:D+ > VOH(min) (2.8V) 且D- < VOL(max)(0.3V) 

        差分信号0:D- > VOH and D+ < VOL

USB協定簡介1.USB協定簡介

J狀态(高電平):D+ 高,D- 低

K狀态(低電平):D+低,D- 高

SEO狀态:D+ 低,D- 高

Reset信号:D+ and D- < VOL for >= 10ms 

主機在要和裝置通信之前會發送Reset信号來把裝置設定到預設的未配置狀态。即主機拉低兩根信号線(SE0狀态)

并保持10ms 

Idle狀态:J狀态資料發、送前後總線的狀态 

Suspend狀态:3ms以上的J狀态 

SYNC: 3個KJ狀态切換,後跟随2位時間的K狀态(看到的波形變化是總線上發送0000 0001經過NRZI編碼後的波形)

USB協定簡介1.USB協定簡介

Resume信号:20ms的K狀态+低速EOP 

主機在挂起裝置後可通過翻轉資料線上的極性并保持20ms來喚醒裝置,并以低速EOP信号結尾 

帶遠端喚醒功能的裝置還可自己發起該喚醒信号;前提是裝置已進入idle狀态至少5ms,然後發出喚醒K信号,維持1ms到15ms并由主機在1ms内接管來繼續驅動喚醒信号 

SOP:從IDLE狀态切換到K狀态 

EOP:持續2位時間的SE0信号,後跟随1位時間的J狀态 

Keep alive即低速EOP信号

USB協定簡介1.USB協定簡介

1.4 USB插入檢測和速度檢測:

USB協定簡介1.USB協定簡介

主機通過裝置在D+或D-上的1.5K上拉來檢測裝置的連接配接和斷開事件,并由此判别裝置的速度 

主機先把高速裝置檢測為全速裝置,然後再通過“Chirp序列”的總線握手機制來識别高速和全速裝置

USB連接配接和斷開連接配接:

裝置連上主機時(連接配接)

當主機檢測到某一個資料線電平拉高并保持了一段時間,就認為有裝置連上來了

主機必需在驅動SE0狀态以複位裝置之前,立刻采樣總線狀态來判斷裝置的速度 

USB協定簡介1.USB協定簡介

沒有裝置連上主機時(斷開)

D+和D-資料線上的下拉電阻起作用,使得二者都在低電平;主機端看來就是個SE0狀态;同樣地,當資料線上的SE0狀态持續一段時間了,就被主機認為是斷開狀态

USB協定簡介1.USB協定簡介

1.5 資料編解碼和位填充 

USB采用NRZI(非歸零編碼)對發送的資料包進行編碼 

輸入資料0, 編碼成“電平翻轉” 

輸入資料1, 編碼成“電平不變” 

編碼出來的序列,高電平:J狀态;低電平:K狀态 

USB協定簡介1.USB協定簡介

位填充是為了保證發送的資料序列中有足夠多的電平變化 

填充的對象是(輸入資料),即先填充再編碼 

資料流中每6個連續的“1”,就要插入1個“0”,進而保證編碼

資料出現電平變化 

接收方指派解碼NRZI碼流,然後識别出填充位,并丢棄它們

2. USB傳輸

一個傳輸有多個事務組成,一個事務由2/3個包組成。

傳輸又分為四種類型:批量傳輸、等時(同步)傳輸、中斷傳輸、控制傳輸。

注意:USB傳輸資料先發資料低位再發高位資料

USB協定簡介1.USB協定簡介

2.1 包

包的組成:

USB協定簡介1.USB協定簡介

包的内容:

USB協定簡介1.USB協定簡介

Packet分四大類: 指令 (Token) 、Packet 幀首 (Start of Frame) 、Packet 資料 (Data) 、Packet 握手 (Handshake) Packet

不同類型包,以上的組成部件有所不同

PID:

USB協定簡介1.USB協定簡介

這裡隻用(PID0~4),PID4~7是PID0~4的取反,用來校驗PID

PID1~0:01 令牌包、11 資料包、10 握手包、00 特殊包

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介

位址:

USB協定簡介1.USB協定簡介

幀号:

USB協定簡介1.USB協定簡介

資料:

USB協定簡介1.USB協定簡介

CRC:

USB協定簡介1.USB協定簡介

四種Packet類型之令牌包(Token Packet):

令牌包用來啟動一次USB傳輸。

輸出(OUT)令牌包:用來通知裝置将要輸出一個資料包

輸入(IN)令牌包:用來通知裝置傳回一個資料包

建立(SETUP)令牌包:隻用在控制傳輸中,和輸出令牌包作用一樣,也是通知裝置将要輸出一個資料包,兩者差別在于:

SETUP令牌包後隻使用DATA0資料包,且隻能發送到裝置的控制端點,并且裝置必須要接收,而OUT令牌包沒有這些限制

USB協定簡介1.USB協定簡介

例子:

USB協定簡介1.USB協定簡介

四種Packet類型之SOF Packet

幀起始包:在每幀(或微幀)開始時發送,以廣播的形式發送,所有USB全速裝置和高速裝置都可以接收到SOF包。

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介

例子:

USB協定簡介1.USB協定簡介

0xA5:1010 0101:對應上面PID表可知是幀起始包

四種Packet類型之Data Packet

USB協定簡介1.USB協定簡介

例子:

USB協定簡介1.USB協定簡介

四種Packet類型之Handshake Packet 

USB協定簡介1.USB協定簡介

例子:

USB協定簡介1.USB協定簡介

2.2 事務

Transaction可以分成三類 

Setup transaction:主機用來向裝置發送控制指令 

Data IN transaction:主機用來從裝置讀取資料 

Data OUT transaction:主機用來向裝置發送資料 

Transaction的packet組成 

Token packet:總是由主機發出 

Data packet:包含此次transaction的資料負載 

可選的Handshake packet 

例子:

USB協定簡介1.USB協定簡介

2.3 傳輸

USB協定定義了四種傳輸類型: 

批量(大容量資料)傳輸(Bulk Transfers): 非周期性,突發  

大容量資料的通信,資料可以占用任意帶寬,并容忍延遲 。如USB列印機、掃描器、大容量儲存裝置等 

中斷傳輸(Interrupt Transfers): 周期性,低頻率

允許有限延遲的通信 如人機接口裝置(HID)中的滑鼠、鍵盤、軌迹球等

等時(同步)傳輸(Isochronous Transfers): 周期性 

持續性的傳輸,用于傳輸與時效相關的資訊,并且在資料中儲存時間戳的資訊 ,如音頻視訊裝置

控制傳輸(Control Transfers): 非周期性,突發

用于指令和狀态的傳輸

2.3.1 批量傳輸

批量輸出事務,(1)主機先發出一個OUT令牌包(包含裝置位址,端點号),(2)然後再發送一個DATA包,這時位址和端點比對的裝置就會收下這個資料包,主機切換到接收模式,等待裝置傳回握手包,(3)裝置解碼令牌包,資料包都準确無誤,并且有足夠的緩沖區來儲存資料後就會使用ACK/NYET握手包來應答主機(隻有高速模式才有NYET握手包,他表示本次資料成功接收,但是沒有能力接收下一次傳輸),如果沒有足夠的緩沖區來儲存資料,就傳回NAC,告訴主機目前沒有緩沖區可用,主機會在稍後時間重新該批量傳輸事務。如果裝置檢查到資料正确,但端點處于挂起狀态,傳回STALL。如果檢測到有錯誤(如校驗錯誤,位填充錯誤),則不做任何響應,讓主機等待逾時。

批量輸入事務,(1)主機首先發送一個IN令牌包(包含裝置位址,端點号),(2)主機切換到接收資料狀态等待裝置傳回資料。如果裝置檢測到錯誤,不做任何響應,主機等待逾時。如果此時有位址和端點比對的裝置,并且沒有檢測到錯誤,則該裝置作出反應:裝置有資料需要傳回,就将一個資料包放在總線上;如果沒有資料需要傳回,裝置傳回NAK響應主機;如果該端點處于挂起狀态,裝置傳回STALL。如果主機收到裝置發送的資料包并解碼正确後,使用ACK握手包應答裝置。如果主機檢測到錯誤,則不做任何響應,裝置會檢測到逾時。注意:USB協定規定,不允許主機使用NAK來拒絕接收資料包。主機收到NAK,知道裝置暫時沒有資料傳回,主機會在稍後時間重新該批量輸入事務。

PING令牌包,它不發送資料,直到等待裝置的握手包。

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介

2.3.2 中斷傳輸

中斷傳輸是一種保證查詢頻率的傳輸。中斷端點在端點描述符中要報告它的查詢間隔,主機會保證在小于

這個時間間隔的範圍内安排一次傳輸。

USB協定簡介1.USB協定簡介

2.3.3 等時傳輸

等時(同步)傳輸用在資料量大、對實時性要求高的場合,如音頻裝置,視訊裝置等,這些裝置對資料的延遲很敏感。對于音頻或視訊裝置資料的100%正确性要求不高,少量的資料錯誤是可以容忍的,主要是保證資料不能停頓,是以等時傳輸是不保證資料100%正确的。當資料錯誤時,不再重傳操作。是以等時傳輸沒有應答包,資料是否正确,由資料的CRC校驗來确認。

USB協定簡介1.USB協定簡介

2.3.4 控制傳輸

控制傳輸可分為三個過程:(1)建立過程 (2)資料過程(可選) (3)狀态過程

 特性:  

每個USB裝置都必須有控制端點,支援控制傳輸來進行指令和狀态的傳輸。USB主機驅動将通過控制傳輸與USB裝置的控制端點通信,完成USB裝置的枚舉和配置 

方向:  

控制傳輸是雙向的傳輸,必須有IN和OUT兩個方向上的特定端點号的控制端點來完成兩個方向上的控制傳輸 

資料的拆分和資料傳輸完畢的判定 

以高速裝置的最大資料包長度64位元組為例 

要傳輸250位元組,拆分成4個packet 

USB協定簡介1.USB協定簡介

要傳輸正好256位元組,通過最後一個0位元組包告訴裝置傳輸完成

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介

各種傳輸特性比較

USB協定簡介1.USB協定簡介

3. USB标準請求

3.1 USB标準請求的資料結構

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介

3.2 USB 裝置枚舉及描述符介紹 

當一個USB裝置插入主機後,會有以下活動: 

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介
  1. include/uapi/linux/usb/ch9.h

  2. struct usb_device_descriptor {

  3. __u8 bLength;

  4. __u8 bDescriptorType;

  5. __le16 bcdUSB;

  6. __u8 bDeviceClass;

  7. __u8 bDeviceSubClass;

  8. __u8 bDeviceProtocol;

  9. __u8 bMaxPacketSize0;

  10. __le16 idVendor;

  11. __le16 idProduct;

  12. __le16 bcdDevice;

  13. __u8 iManufacturer;

  14. __u8 iProduct;

  15. __u8 iSerialNumber;

  16. __u8 bNumConfigurations;

  17. } __attribute__ ((packed));

  18. #define USB_DT_DEVICE_SIZE 18

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介
  1. struct usb_config_descriptor {

  2. __u8 bLength;

  3. __u8 bDescriptorType;

  4. __le16 wTotalLength;

  5. __u8 bNumInterfaces;

  6. __u8 bConfigurationValue;

  7. __u8 iConfiguration;

  8. __u8 bmAttributes;

  9. __u8 bMaxPower;

  10. } __attribute__ ((packed));

  11. #define USB_DT_CONFIG_SIZE 9

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介
  1. struct usb_interface_descriptor {

  2. __u8 bLength;

  3. __u8 bDescriptorType;

  4. __u8 bInterfaceNumber;

  5. __u8 bAlternateSetting;

  6. __u8 bNumEndpoints;

  7. __u8 bInterfaceClass;

  8. __u8 bInterfaceSubClass;

  9. __u8 bInterfaceProtocol;

  10. __u8 iInterface;

  11. } __attribute__ ((packed));

  12. #define USB_DT_INTERFACE_SIZE 9

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介
  1. struct usb_endpoint_descriptor {

  2. __u8 bLength;

  3. __u8 bDescriptorType;

  4. __u8 bEndpointAddress;

  5. __u8 bmAttributes;

  6. __le16 wMaxPacketSize;

  7. __u8 bInterval;

  8. __u8 bRefresh;

  9. __u8 bSynchAddress;

  10. } __attribute__ ((packed));

  11. #define USB_DT_ENDPOINT_SIZE 7

  12. #define USB_DT_ENDPOINT_AUDIO_SIZE 9

USB協定簡介1.USB協定簡介
USB協定簡介1.USB協定簡介
  1. struct usb_string_descriptor {

  2. __u8 bLength;

  3. __u8 bDescriptorType;

  4. __le16 wData[1];

  5. } __attribute__ ((packed));

USB協定簡介1.USB協定簡介