Linux USB总线驱动框架分析
1、USB驅動引入
USB(全稱 Universal Serial Bus,通用串行總線),已經成為PC及嵌入式設備中最常用、最便捷的通信接口。Linux USB子系統較為龐大,本文主要對Linux系統下的USB總線驅動框架進行概述,重點的細節待后續文章展開。
首先來看一個現象,插入USB設備后linux系統打印如下日志:
?
拔出后提示:usb 1-1: USB disconnect, address 2
1.1 USB的硬件結構
如圖集線器(USB Root Hub)端兩條數據線(D+D-),都接有15K的下拉電阻,當無設備接入時,集線器數據線D+D-的電壓為低電平。當設備接入時,由于設備的數據線上接有1.5K上拉電阻,使得1根數據線被拉高。集線器根據數據線被拉高得知有設備接入,并根據D+為高還是D-為高來判斷所接入的設備是全速USB設備(D+為高)還是低速USB設備(D-為高)。
1.2 USB接入識別大致過程
當識別出有USB設備插入后,linux內的USB總線驅動程序發出命令至該設備,與設備對話,并詢問設備信息(描述符),設備收到請求后,回復設備描述符給總線驅動程序。且總線驅動程序會為該設備分配一個地址,如上地址為2,當后期訪問某個USB設備時,均會通過這個地址編號,當新接入的USB設備被第一次訪問時,以地址0來訪問。當USB總線驅動程序識別出設備后,會為其找到該USB設備驅動程序,如鍵盤,鼠標,U盤。
?
USB通信過程均為主從結構,USB主機發起通信請求,設備進行數據回復,USB設備不具備主動向主機通信的能力。
2、USB總線驅動框架
如上,我們大致了解了USB的簡單通信過程,那么什么是USB總線驅動程序?什么是USB設備驅動呢?
2.1 USB的總線驅動框架? ? ?
USB總線框架總結為如下圖:
?
2.2?USB Core
USB Core這個模塊是純軟件部分,并不代表一個設備,是獨立于硬件的協議棧,它是所有USB設備賴以生存的模塊,即USB子系統的核心。代碼位于kernel/drivers/usb/core目錄下。
?
USB Core為設備驅動程序提供服務,提供一個用于訪問和控制USB硬件的接口,而不用考慮系統當前使用的哪種HOST Controller。USB Core將用戶的請求映射到相關的HCD,用戶不能直接訪問HCD。USB Core就是HCD與USB設備的橋梁。
?
其Makefile為:
USB的初始化函數在kernel/drivers/usb/core/usb.c中定義,主要完成bus_register(USB總線注冊)、usb_major_init(注冊usb主控器字符設備)、usb_register(注冊usbfs驅動)、usb_hub_init(USB Hub初始化,注冊hub驅動、創建內核守護線程來監測hub端口的狀態變化)等工作,后續具體分析。
?
2.3 USB HCD(Host Controller Driver)
硬件主機控制器Host Controller之上運行的是HCD,是對主機控制器硬件的一個抽象,實現核心層與控制器之間的對話接口,USB?HCD包含多種USB接口規范:
(1)UHCI:Intel提供,通用主機控制接口,USB1.0/1.1;
(2)OHCI:微軟提供,開放主機控制接口,USB1.0/1.1;
(3)EHCI:增強主機控制接口,USB2.0;
2.4 USB Device Driver
USB設備驅動框架如下圖所示:
USB設備是由一些配置(configuration)、接口(interface)和端點(endpoint)組成,,即一個USB設備可以含有一個或多個配置,在每個配置中可含有一個或多個接口,在每個接口中可含有若干個端點。一個USB設備驅動可能包含多個子驅動。一個USB設備子驅動程序對應一個USB接口,而非整個USB設備。
?
USB設備使用各種描述符來說明其設備架構,包括設備描述符、配置描述符、接口描述符、端點描述符、字符串描述符。后面單獨討論USB設備描述符。
?
USB傳輸的對象為端點(endpoint),每一個端點都有傳輸類型,傳輸方向,除了端點0外,每一個端點只支持一個方向的數據傳輸,端點0用于控制傳輸,既能輸出也能輸入。輸入(IN)、輸出(OUT) "都是" 基于USB主機的立場說的。比如鼠標的數據是從鼠標傳到PC機, 對應的端點稱為"輸入端點"。
USB的傳輸類型:
a. 控制傳輸:可靠,時間有保證,比如:USB設備的識別過程
b. 批量傳輸: 可靠, 時間沒有保證, 比如:U盤
c. 中斷傳輸:可靠,實時,比如:USB鼠標
d. 實時傳輸:不可靠,實時,比如:USB攝像頭
?
針對不同類型的USB設備,需要實現特定的USB驅動程序。如HID(Human Interface Device), 屬于人機交互類的設備,如USB鼠標,USB鍵盤等。該類設備必須遵循HID設計規范。
?
在Linux內核中,使用 struct usb_driver結構體來描述一個USB驅動,通過usb_register在USB驅動中注冊進內核。
?
因此USB設備驅動開發,主要包含如下兩個部分:
分配/設置usb_driver結構體,實現并填充結構體內容
注冊usb_driver
后續將對USB鼠標驅動進行詳細分析,其代碼在kernel/drivers/hid/usbhid/usbmouse.c
3、USB設備識別過程
通過以上分析,USB設備驅動模型可以概括為如下圖。
主要包含三個部分:USB控制器驅動,USB核心,USB設備驅動。如上圖khubd是USB守護進程,當USB設備插入的時候,守護進程監測到,USB主機控制器就會產生一個hub_irq中斷,控制器調用hub的探測函數,來解析設備信息。
下面分析一下USB設備的識別過程。
以上顯示了設備插入到USB設備驅動被調用的函數流程,后面將拿出一章具體分析函數內部實現來進一步分析USB設備識別中做了哪些事情。
4、總結
通過以上內容,我們從整體上認識了USB硬件識別過程,USB總線框架及USB設備驅動框架。后續會針對一些重點知識進行專題分析。主要包括:
USB設備描述符解析
USB四類傳輸類型
USB數據包格式分析
USB鼠標設備驅動代碼分析
USB初始化代碼分析
USB枚舉過程代碼分析
?
-END-
總結
以上是生活随笔為你收集整理的Linux USB总线驱动框架分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [会议分享]2020全球软件大会分享-P
- 下一篇: MSSQLSERVER启动不了,报SQL