Linux USB驱动(1)---usb-skeleton.c分析

简介: 在Linux内核的源码中提供了USB设备驱动的框架代码:usb-skeleton.c我们自己的驱动程序可借助这个框架代码,做些修改就能生成我们自己的驱动程序。首先从USB设备与Linux驱动的匹配说起,当一个USB设备连接到Linux USB总线之后,USB主机控制器会使用USB设备的0号端点EPO对USB查询及设置,用以获取USB设备中提供的相关信息,然后根据这些信息,来决定加载那些驱动程序等。
在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);
目录
相关文章
|
14天前
|
缓存 算法 Linux
Linux内核中的调度策略优化分析####
本文深入探讨了Linux操作系统内核中调度策略的工作原理,分析了不同调度算法(如CFS、实时调度)在多核处理器环境下的性能表现,并提出了针对高并发场景下调度策略的优化建议。通过对比测试数据,展示了调度策略调整对于系统响应时间及吞吐量的影响,为系统管理员和开发者提供了性能调优的参考方向。 ####
|
4月前
|
存储 IDE Unix
Linux 内核源代码情景分析(四)(上)
Linux 内核源代码情景分析(四)
37 1
Linux 内核源代码情景分析(四)(上)
|
4月前
|
存储 Linux 块存储
Linux 内核源代码情景分析(三)(下)
Linux 内核源代码情景分析(三)
41 4
|
4月前
|
Linux C语言
深度探索Linux操作系统 —— 编译过程分析
深度探索Linux操作系统 —— 编译过程分析
29 2
|
4月前
|
存储 Unix Linux
Linux 内核源代码情景分析(四)(下)
Linux 内核源代码情景分析(四)
25 2
|
4月前
|
存储 Unix Linux
Linux 内核源代码情景分析(三)(上)
Linux 内核源代码情景分析(三)
38 1
|
3月前
|
存储 传感器 Linux
STM32微控制器为何不适合运行Linux系统的分析
总的来说,虽然技术上可能存在某些特殊情况下将Linux移植到高端STM32微控制器上的可能性,但从资源、性能、成本和应用场景等多个方面考虑,STM32微控制器不适合运行Linux系统。对于需要运行Linux的应用,更适合选择ARM Cortex-A系列处理器的开发平台。
278 0
|
3月前
|
Linux API
Linux里的高精度时间计时器(HPET)驱动 【ChatGPT】
Linux里的高精度时间计时器(HPET)驱动 【ChatGPT】
|
4月前
|
存储 算法 Unix
Linux 内核源代码情景分析(四)(中)
Linux 内核源代码情景分析(四)
49 0
|
4月前
|
存储 算法 Unix
Linux 内核源代码情景分析(三)(中)
Linux 内核源代码情景分析(三)
40 0