USB 滑鼠驅動原始碼分析

2021-08-23 14:32:16 字數 4006 閱讀 9734

kernel:kernel-3.4.39

uhci: intel,

低速(1.5mbps)/全速(12mbps)

ohci: microsoft

低速/全速

ehci:

高速(480mbps)

usb匯流排驅動程式的作用: 1

、分配位址給usb裝置,同時將分配的位址發給usb裝置(最開始通訊位址是埠0) 2

、發出命令獲取描述符 3

、查詢和安裝對應的裝置驅動程式 4

、提供usb讀寫函式

乙個usb硬體有乙個「裝置描述符」;乙個裝置描述符下會有乙個或多個「配置」;乙個配置裡可能有多個「介面——邏輯裝置」;乙個「介面」裡面有多個「端點描述符」

「端點描述符」裡面描述了一次性最多可以傳輸多少的資料;埠編號、方向、傳輸型別等資訊。

usb主要有4種描述符:裝置描述符、配置描述符、介面描述符、端點描述符(這是必須存在的描述符)

struct usb_device_descriptor __attribute__ ((packed));

blength:描述符長度

bdescriptortype:裝置描述符 usb_dt_device 0x01

bcdusb:usb: 描述符版本號,乙個裝置如果可以進行高速傳輸,那麼裝置描述符就是0200h

bdeviceclass:

bdevicesubclass:

bdeviceprotocol:

bmaxpacketsize0:端點0一次可以處理最大位元組,可選8、16、32、64低速8,高速64

idvendor:廠商id

idproduct: 產品id

bcddevice:裝置版本號

imanufacturer:廠商對應的字串描述的索引值

iproduct:產品對應的字串描述的索引值

iserialnumber:序列號對應的字串描述的索引值

bnumconfigurations:裝置當前速度模式下支援的配置數量

配置描述符:

struct usb_config_descriptor __attribute__ ((packed));

blength:描述符長度

bdescriptortype:描述符型別

wtotallength:使用get_descriport請求從裝置獲取的配置描述符資訊返回的資料長度

bnuminte***ces:配置包含的介面數目

bconfigurationvalue:要啟用的配置

iconfiguration:描述配置資訊的字串描述符的索引值

bmattributes:

bmaxpower:從匯流排獲取的最大電流值,2ma為單位

介面描述符:

struct usb_host_inte***ce ;

struct usb_inte***ce_descriptor __attribute__ ((packed));

__attribute__ ((packed)),意思就是告訴編譯器,這個結構的元素都是 1 位元組對齊的,不要再新增填充位了。如果不給編譯器這麼個暗示,編譯器就會依據你平台的型別在結構的每個元素之間新增一定的填充位

blength:描述符的位元組長度。協議裡規定,每個描述符必須以乙個位元組打頭來表明描述符的長度。那可以扳著指頭數一下,介面描述符的 blength 應該是 9

bdescriptortype:描述符的型別,介面描述符在ch9.h的標頭檔案中有定義usb_dt_inte***ce

binte***cenumber:介面號。每個配置可以包含多個介面,這個值就是介面的索引值。

balternatesetting:介面使用的是哪個可選設定。協議裡規定,介面預設使用的設定總為 0 號設定。

bnumendpoints:介面擁有的端點數量。這裡並不包括端點 0,端點 0 是所有的裝置都必須提供的,所以這裡就沒必要再包括它了。

binte***ceclass 、 binte***cesubclass、 binte***ceprotocol:

binte***ceclass介面類

binte***cesubclass介面子類

binte***ceprotocol介面協議

每個device或inte***ce屬於乙個class,然後 class 下面又分了 subclass, 完了 subclass 下面又按各種裝置所遵循的不同的通訊協議繼續細分。 usb 協議裡邊為每一種 class,每一種 subclass,每一種 protocol 定義乙個數值

iinte***ce:介面對應的字串描述符的索引值。一些裝置專門準備了一些字串描述符(string descriptor),就用來記這些長串的東西。字串描述符主要就是提供一些裝置介面相關的描述性資訊, 比如廠商的名字, 產品序列號等等。 字串描述符當然可以有多個,這裡的索引值就是用來區分它們的。

埠描述符:

struct usb_host_endpoint ;

struct usb_endpoint_descriptor __attribute__ ((packed));

與上面的介面描述符類似

blength:描述符的位元組長度,這裡是9個位元組

bdescriptortype:描述符型別

bendpointaddress:這個字段包含了端點位址、輸入端點還是輸出端點;bits 0~3表示端點號,bit 8表示方向,輸入還是輸出

bmattributes:屬性。bits 0~1表示傳輸型別,00 控制、01等時、10批量、11中斷

wmaxpacketsize:端點一次可以處理的最大位元組數

binterval:輪詢時間

最後兩個位元組是針對音訊的擴充套件

乙個usb裝置可能有多種功能,例:可以錄音、錄影;鍵盤帶有揚聲器等

乙個介面表示usb裝置的乙個功能 介面下的端點表示的是資料通道,讀、寫端點是不同的

usb匯流排驅動裝置模型程式,在插入usb裝置時,會構造乙個新的usb_dev註冊到「usb_bus_type」usb匯流排裝置驅動模型中。寫驅動時我們需要宣告乙個usb_driver結構體,也註冊到usb_bus_type中。在usb裝置插入時,就要去匹配驅動usb_driver結構體中id_table,是否有驅動去支援這個裝置,當裝置在id_table中找到對應的裝置驅動則呼叫usb_driver的.probe函式。

首先構造乙個usb_driver結構體

.probe :表示「usb 匯流排驅動程式」發現乙個新裝置後,就會與 driver 比較,若 id_table 表示能支援它,就呼叫.probe 函式。

.disconnect :拔掉 usb 裝置時呼叫這個函式

.id_table :表示能支援的裝置

首先確定我們的驅動要支援哪一類裝置 id_table

我們需要設定的支援項包括介面類,介面子類,介面協議三個匹配項。

.match_flags                      :表示要匹配「裝置描述符」中的哪一項

.binte***ceclass                : 介面描述符裡的類cl

.binte***cesubclass                  : 介面描述符裡的子類sc

這個id_table中

類是usb_inte***ce_class_hid  hid

子類是usb_inte***ce_subclass_boot  boot

協議是usb_inte***ce_protocol_mouse  mouse

如果想支援某乙個裝置,則需要vid(廠家id)、pid(裝置id)

這樣就可以支援對應廠家對應的裝置了。

假設插入裝置與id_table匹配,就呼叫.probe

待續·······

USB 24 usb滑鼠驅動驅動例項分析 2 管道

端點是usb裝置的唯一可識別部分,其是主機和裝置之間的通訊流的終點。管道,就是乙個usb主機和usb裝置端點之間的資料傳輸的通道。站在主機的角度,它的目的是裝置的某個端點。而管道這算是主機和端點之間的連線。這裡我們先看一下管道在usb裡的定義 for various legacy reasons,l...

Linux網路驅動原始碼分析 一

網路驅動是一種典型的pci裝置驅動,無論在嵌入式平台還是在pc領域,網路相關的專案開發有著比較廣闊的前景,因此,分析當前linux核心中網路裝置的驅動,不但能了解網路相關的基本原理,而且可以借鑑linux核心的先進的技術,將其應用到嵌入式或其他領域。本文以linux核心中的rtl8139網路驅動為例...

驅動學習之led class c原始碼分析

1 subsys initcall巨集 1 2 3 4 define define initcall level,fn,id static initcall t initcall fn id used attribute section initcall level init fn define s...