linux - bluetooth - hid - demo

2015-12-29  本文已影响365人  初见破晓

linux HID驱动分析
http://blog.csdn.net/walkingman321/article/details/7213710

HID 总线
HID的总线在hid-core.c的hid-init中初始化:
bus_register(&hid_bus_type);
hid_bus_type的定义:
static struct bus_type hid_bus_type = {

};
一般来说,HID驱动很少定义自己的probe函数,所以HID设备的匹配基本都是由总线probe和match函数完成。
HID的匹配
hid_bus_match用于检查设备和驱动的VID、PID是否匹配,代码如下:
*static int hid_bus_match(struct device *dev, struct device_driver drv)

if (!hid_match_device(hdev, hdrv))

匹配了PID、VID之后,就进入到hid_device_probe函数:
*static int hid_device_probe(struct device dev)

id = hid_match_device(hdev, hdrv);

hid_parse函数的作用是解析HID描述符,具体实现由hid_device->ll_driver->parse函数完成。关于HID描述符的文档可在www.usb.org下载。
*static inline int __must_check hid_parse(struct hid_device hdev)

由于HID描述符的解析是通用操作,所以HID框架中实现了一个解析函数hid_parse_report。一般来说,hdev->ll_driver->parse函数中只要调用hid_parse_report即可。
hid_parse_report比较复杂,其功能是解析HID描述符,然后把解析出的结果放在hid_device->report_enum[type]-> report_list中。每个解析出的HID结构由一个hid_report描述。report_enum中的type可以是HID_INPUT_REPORT、HID_OUTPUT_REPORT或者HID_FEATURE_REPORT。
parse之后,probe函数又会调用hid_hw_start启动HID设备:

注意这里的HID_CONNECT_DEFAULT被定义为:
*#define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| *

在hid_hw_start中,首先会调用hdev->ll_driver->start启动设备,然后是hid_connect将设备与HID框架关联起来。
hdev->ll_driver->start函数由hid的具体设备提供,由该设备所属的总线提供,用于底层的初始化,这里暂不讨论。
hid_connect会将hid_dev与具体驱动关联起来。
*int hid_connect(struct hid_device hdev, unsigned int connect_mask)

由此可见,hid_connect共支持3种设备,首先是input设备,调用hidinput_connect登记;其次是hid_dev设备,调用hdev->hiddev_connect登记;最后是raw设备,调用hidraw_connect登记。
HID input
HID中最常用的是input设备,使用hidinput_connect登记到系统。hidinput_connect的主要作用是对hiddev中的每一个report,都建立一个input_dev设备,并登记到input框架中。
*int hidinput_connect(struct hid_device hid, unsigned int force)

for (k = HID_INPUT_REPORT; k <= max_report_type; k++)

HID dev
HID dev设备目前仅在USB总线中用到,其用于登记的hiddev_connect函数指针目前仅有一个实例hiddev_connect,在usbhid_probe函数中被赋值。
hid->hiddev_connect = hiddev_connect;
HID raw dev
hidraw.c中定义了一个class hidraw,并创建设备设备驱动
alloc_chrdev_region(&dev_id, HIDRAW_FIRST_MINOR, HIDRAW_MAX_DEVICES, "hidraw");
cdev_init(&hidraw_cdev, &hidraw_ops);
hidraw_ops中定义了一个基本的字符设备驱动
static const struct file_operations hidraw_ops = {

};
由于是raw设备,所以这个驱动中不会解析任何数据,只是简单的将应用层数据传给下层设备,以及将设备产生的数据传给应用层。具体实现可查看代码。

hid-core.c
http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/hid/hid-core.c#L495
hid-sersor-gyro-3d.c
http://lxr.free-electrons.com/source/drivers/iio/gyro/hid-sensor-gyro-3d.c#L264

android 驱动学习
http://blog.csdn.net/vv0_0vv/article/category/1067351

上一篇 下一篇

猜你喜欢

热点阅读