Chinaunix首页 | 论坛 | 博客
  • 博客访问: 318589
  • 博文数量: 69
  • 博客积分: 352
  • 博客等级: 入伍新兵
  • 技术积分: 296
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-16 15:41
文章分类
文章存档

2023年(1)

2021年(1)

2020年(2)

2017年(4)

2016年(3)

2015年(1)

2013年(1)

2012年(21)

2011年(35)

分类:

2012-07-09 10:21:00

在Linux内核的源码中提供了USB设备驱动的框架代码:usb-skeleton.c
我们自己的驱动程序可借助这个框架代码,做些修改就能生成我们自己的驱动程序。

首先从USB设备与Linux驱动的匹配说起,当一个USB设备连接到Linux USB总线之后,USB主机控制器会使用USB设备的0号端点EPO对USB查询及设置,用以获取USB设备中提供的相关信息,然后根据这些信息,来决定加载那些驱动程序等。其中比较关键的USB设备的信息是:

idVendor  厂商ID这个是需要统一申请的,例如Cypress为0x04B4
idProduct 产品ID这个是厂家自己给产品分配的ID,例如CY68013为0x8613

由这两个信息我们得到一个唯一的设备ID标示,这个ID标示会和驱动程序中通过MODULE_DEVICE_TABLE(usb, xxxx_table)这个宏导出的idVendor和idProduct进行匹配,如果匹配成功则加载相应的驱动,并调用驱动的probe函数,进行相关处理如加载固件等。

可以通过USBFS文件系统来查看连接到系统USB总线上的USB设备的各种信息,USBFS文件系统的挂载命令为:

mount -t usbfs none /proc/bus/usb 

挂载成功之后可以在/proc/bus/usb/devices文件中查看连接到USB总线上的设备的信息以及与之匹配的驱动的名称等信息


在USB设备驱动中通过USB_DEVICE(VENDOR_ID, PRODUCT_ID)这个宏将指定的VENDOR_ID和PRODUCT_ID赋值到struct usb_device_id结构体中的idVendor和idProduct元素。

然后在通过MODULE_DEVICE_TABLE这个宏将驱动名称和唯一标示的ID导出,这个语句创建一个局部变量称为 __mod_usb_device_table, 它指向 struct usb_device_id 的列表. 稍后在内核建立过程中, depmod 程序在所有的模块中寻找 __mod_usb_device_table. 如果找到这个符号, 它将数据拉出模块并且添加到文件 /lib/modules/KERNEL_VERSION/modules.usbmap. 在 depmod 完成后, 所有的被内核中的模块支持的 USB 设备被列出, 带有它们的模块名子, 在那个文件中. 当内核告知热插拔系统有新的 USB 设备已找到, 热插拔系统使用 moudles.usbmap 文件来找到正确的驱动来加载,并把设备的usb_device_id指针作为probe函数的第二个参数传递。

例:CY68013的struct usb_device_id,该结构中的driver_info可以保存一个结构体的指针,用来保存设备的相关信息如加载什么固件,使用那个设置等等
  1.  28 /* Define these values to match your devices */
  2.  29 #define CY68013_VENDOR_ID   0x04B4
  3.  30 #define CY68013_PRODUCT_ID  0x8613
  4.  31
  5.  32 #define CY_FIX_FW   "cy_fix.hex"
  6.  33 static struct cy68013_info cy_info = {
  7.  34     .alt    =   1,
  8.  35     .fwname =   "cy_var.hex"
  9.  36 };
  10.  37
  11.  38 /* table of devices that work with this driver */
  12.  39 static const struct usb_device_id cy68013_table[] = {
  13.  40     { USB_DEVICE(CY68013_VENDOR_ID, CY68013_PRODUCT_ID),
  14.  41         .driver_info = (unsigned long)&cy_info },
  15.  42     { }                 /* Terminating entry */
  16.  43 };
  17.  44 MODULE_DEVICE_TABLE(usb, cy68013_table);
阅读(1366) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~