驱动模型简介之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驱动因为没有添加设备所以不会匹配任何设备。