如何在嵌入式linux开发板上使用USB键盘

如何在嵌入式linux开发板上使用USB键盘,第1张

鼠标驱动可分为几个部分:驱动加载部分、伏亏probe部分、open部分、urb回调函数处理部分。

下文阴影部分为注解。

一、驱动加载部分

static int __init usb_mouse_init(void)

{

int retval = usb_register(&usb_mouse_driver)//注册鼠标驱动

if (retval == 0)

info(DRIVER_VERSION ":" DRIVER_DESC)

return retval

}

其中usb_mouse_driver的定义为:

static struct usb_driver usb_mouse_driver = {

.owner = THIS_MODULE,

.name = "usbmouse",

.probe = usb_mouse_probe,

.disconnect = usb_mouse_disconnect,

.id_table = usb_mouse_id_table,

}

如果注册成功的话,将会调用usb_mouse_probe。那么什么时候才算注册成功呢?

和其它驱动注册过程一样,只有在其对应的“总线”上发现匹配的“设备”才会调用probe。总线匹配的方历碰法和具体总线相关,如:缺烂神platform_bus_type中是判断驱动名称和平台设备名称是否相同;那如何确认usb总线的匹配方法呢?

Usb设备是注册在usb_bus_type总线下的。查看usb_bus_type的匹配方法。

struct bus_type usb_bus_type = {

.name ="usb",

.match = usb_device_match,

.hotplug =usb_hotplug,

.suspend = usb_generic_suspend,

.resume = usb_generic_resume,

}

其中usb_device_match定义了匹配方法

static int usb_device_match (struct device *dev, struct device_driver *drv)

{

struct usb_interface *intf

struct usb_driver *usb_drv

const struct usb_device_id *id

/* check for generic driver, which we don't match any device with */

if (drv == &usb_generic_driver)

return 0

intf = to_usb_interface(dev)

usb_drv = to_usb_driver(drv)

id = usb_match_id (intf, usb_drv->id_table)

if (id)

return 1

return 0

}

可以看出usb的匹配方法是usb_match_id (intf, usb_drv->id_table),也就是说通过比对“dev中intf信息”和“usb_drv->id_table信息”,如果匹配则说明驱动所对应的设备已经添加到总线上了,所以接下了就会调用drv中的probe方法注册usb设备驱动。

usb_mouse_id_table的定义为:

static struct usb_device_id usb_mouse_id_table[] = {

{ USB_INTERFACE_INFO(3, 1, 2) },

{ } /* Terminating entry */

}

#define USB_INTERFACE_INFO(cl,sc,pr) /

.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, /

.bInterfaceClass = (cl), /

.bInterfaceSubClass = (sc), /

.bInterfaceProtocol = (pr)

鼠标设备遵循USB人机接口设备(HID),在HID规范中规定鼠标接口类码为:

接口类:0x03

接口子类:0x01

接口协议:0x02

这样分类的好处是设备厂商可以直接利用标准的驱动程序。除了HID类以外还有Mass storage、printer、audio等

#define USB_DEVICE_ID_MATCH_INT_INFO /

(USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)

匹配的过程为:

usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)

{

struct usb_host_interface *intf

struct usb_device *dev

/* proc_connectinfo in devio.c may call us with id == NULL. */

if (id == NULL)

return NULL

intf = interface->cur_altsetting

dev = interface_to_usbdev(interface)

/* It is important to check that id->driver_info is nonzero,

since an entry that is all zeroes except for a nonzero

id->driver_info is the way to create an entry that

indicates that the driver want to examine every

device and interface. */

for (id->idVendor || id->bDeviceClass || id->bInterfaceClass ||

id->driver_infoid++) {

if ((id->match_flags &USB_DEVICE_ID_MATCH_VENDOR) &&

id->idVendor != le16_to_cpu(dev->descriptor.idVendor))

continue

if ((id->match_flags &USB_DEVICE_ID_MATCH_PRODUCT) &&

id->idProduct != le16_to_cpu(dev->descriptor.idProduct))

continue

/* No need to test id->bcdDevice_lo != 0, since 0 is never greater than any unsigned number. */

if ((id->match_flags &USB_DEVICE_ID_MATCH_DEV_LO) &&

(id->bcdDevice_lo >le16_to_cpu(dev->descriptor.bcdDevice)))

continue

if ((id->match_flags &USB_DEVICE_ID_MATCH_DEV_HI) &&

(id->bcdDevice_hi <le16_to_cpu(dev->descriptor.bcdDevice)))

continue

if ((id->match_flags &USB_DEVICE_ID_MATCH_DEV_CLASS) &&

(id->bDeviceClass != dev->descriptor.bDeviceClass))

continue

if ((id->match_flags &USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&

(id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))

continue

if ((id->match_flags &USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&

(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))

continue

//接口类

if ((id->match_flags &USB_DEVICE_ID_MATCH_INT_CLASS) &&

(id->bInterfaceClass != intf->desc.bInterfaceClass))

continue

//接口子类

if ((id->match_flags &USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&

(id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))

continue

//遵循的协议

if ((id->match_flags &USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&

(id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))

continue

return id

}

return NULL

}

从中可以看出,只有当设备的接口类、接口子类、接口协议匹配鼠标驱动时鼠标驱动才会调用probe方法。

嵌入式USB就是使用在嵌入式的USB接口,比如我们的手机上的USB,机山猛顶盒的USB都可以叫USB接口。

你可以去嵌入式学习网蚂唯宽看看,他们的嵌入式视频教程闷亮现在有赠送USB培训的视频。

还是很不错的。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12499682.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存