驅動模型簡介之usbhid和hid-generic驅動區別
參考書籍:《LINUX設備驅動程序》
(一)驅動模型簡介,三個重要結概念總線,設備,驅動
1.總線:
a、處理器與單個或多個設備通信的通道
b、可以互相插入
表示結構體
bus_type
{
var:
name //名字
subsystem //子系統,常常是自己
devices//此總線上添加的設備
drivers//此總線上添加的驅動
func:
match//當添加新設備或者新驅動時被調用,判斷是否能找到一個設備和驅動相適配
add
hotplug
}
註冊新結構體方式:
bus_register(bus_type)//成功後會在/sys/bus下面找到
爲總線添加屬性
bus_create_file(bus_type,bus_attribute)
2.設備:
表示結構體
struct device
{
var:
parent //通常是總線或者主控制器
kobj //對應sys文件系統中的device
bus_id //總線上表示設備的id,而不是表示總線的id(或者不僅僅表示總線id)
bus_type //所連總線的類型
device_driver //管理設備的驅動
driver_data //設備驅動所使用的數據
func:
realease
}
設備註冊:
device_register(device)
實際的總線在作爲一個總線的同時也是一個設備,所以要進行兩次註冊
設備屬性:
同總線屬性,也可以爲設備添加設備屬性
device_create_file(device,device_attribute)
實際的設備都有各自的定義,然後將device嵌入自定義的設備中當做成員對象,然後在自定義的設備註冊函數中調用device_register
3.驅動:
device_driver{
var:
name //sysfs中顯示的driver名字
bus_type //驅動操作的總線類型
kobject
devices //驅動操作的設備列表
func:
probe //查詢設備是否存在
remove
shutdown
}
驅動註冊:
driver_register(device_driver)
驅動也有屬性
驅動程序也可設備device結構體一樣,被嵌入自定義的驅動中
(二)添加設備過程
1.可以用如圖的流程圖表示,設備控制器監測設備的動作,當設備添加時,控制器發起設備添加流程,然後內核進行設備枚舉,創建設備結構體,並將設備添加到總線上,總線列舉自己綁定的驅動去匹配設備,匹配成功則調用指定驅動的探測函數probe。
(三)usbhid和hid-generic的區別
1.之所以產生這個問題,是因爲之前寫鼠標驅動usbmouse的時候,怎麼insmod usbmouse也無法使鼠標驅動生效,於是想深究下原因,這纔有這篇文章誕生。
2.我們可以從sysfs文件系統中查看linux設備模型,也就是可以查看所有總線,所有驅動,所有設備,以及總線包含哪些設備和驅動,驅動綁定哪個設備等等重要信息,這樣就配合代碼就可以找到usbhid驅動和和hid-generic驅動的區別。
3.各模塊啓動時調用關係:
usbhid模塊
module_init
-->usbhid_quirks_init初始化黑名單等等
-->usb_register註冊usb_driver
-->usb_driver.probe 當usb總線監測到設備,將執行usbhid驅動的probe函數進行探測
-->usbhid_probe
-->hid_add_device 這裏從usb總線的usbhid驅動調用到hid總線的hid_add_device函數
-->device_add 驅動模型中添加設備
hid-generic模塊
module_hid_driver
-->module_init
-->hid_register_driver註冊hid_driver
-->driver_register註冊device_driver
從這兩個模塊調用可以看出,usbhid驅動註冊了usb驅動結構體,所以usbhid是usb總線上的驅動,相對應的hid-generic是hid總線上的驅動。
對應sysfs中的文件:
(1)當兩驅動都在時,插入usb鼠標設備
(2)刪掉hid-generic驅動後進行同樣操作
此時hid/drivers下沒有hid_generic驅動
(3)刪usbhid,編譯usbmouse進行同樣操作
此時hid-generic驅動雖然在但是卻沒有配對任何設備。
(四)總結
hid總線並沒有自己監測usb總線上的設備熱插拔(也無法自己監測),而是靠其他總線的熱插拔功能監測設備動作然後調用hid總線的hid_add_device函數進行設備綁定。所以刪掉hid_generic驅動,usbhid驅動仍然會將設備交給hid總線,所以即使insmod usbmouse,usb總線也不會指定usbmouse驅動處理鼠標設備(總線上只有一個驅動會處理此設備),而當刪掉usbhid時,usb總線上就只有一個鼠標驅動,usbmouse就可以在usb總線上匹配usb鼠標設備,hid總線上的hid-generic驅動因爲沒有添加設備所以不會匹配任何設備。