usb5-写成usb驱动
platform模型中,需要写两个驱动文件,分别是driver.ko和device.ko,然后分别insmod。
usb驱动只需要写一个驱动文件driver,只insmod driver.ko即可,为什么不insmod device.ko了呢?因为没写,恩,不必写。因为usb是实际的总线,当有usb设备插入的时候usbcore就会自动对该设备执行枚举,枚举之后usbcore就获知了该设备的相关资源,然后把资源信息返回给能匹配的驱动。
简言之,
平台驱动的insmod device.ko是一个模仿usb设备插入的动作,device.ko中记录了资源信息,通过insmod device,平台核心获取device的资源信息返回给匹配的驱动。
usb驱动模型中资源信息在储存在设备中呢,在usb设备插入时通过枚举,usbcore把资源信息读出来塞进返回给匹配的驱动。
怎么匹配的呢?对于platform是通过driver的名字和device的名字匹配的。对于usb模型,us_driver中有usb_device_id table,记录该驱动可以处理的设备 的idVerdor和idProduct
当usb设备插入时,usbcore通过枚举过程获知当前设备的信息,包括两个id,然后和注册在usb总线上的各个usb驱动里的usb_device_id table比较,有相同的的话,就调用哪个驱动的probe函数,并把该设备的资源信息(inteface)作为参数交给probe.这样哪个驱动就达到处理这个设备的目的了.
当然,先插入usb设备再insmod driver.ko,这种情况下去匹配两者的实现跟上面类似。
一下是linux/drivers/hid/usbhid/usbmouse.c里的一个usb_device_id table
static struct usb_device_id usb_mouse_id_table [] = {{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, USB_INTERFACE_PROTOCOL_MOUSE) },{ } };
在linux/include/hid.h
#define USB_INTERFACE_CLASS_HID 3//在usb协议的接口描述符的bInterfaceClass字段如果为3,表示该设备为hid设备
#define USB_INTERFACE_SUBCLASS_BOOT 1//在usb协议的接口描述符的bInterfaceSubClass字段如果为1,表示是hid的子类:支持bios引导的hid
#define USB_INTERFACE_PROTOCOL_MOUSE 2//在usb协议的接口描述符的bInterfaceProtocol字段如果为2,表示协议为鼠标(在支持bios引导时用的,键盘协议为1)
USB_INTERFACE_INFO在linux/include/usb.h中定义,如下
#define USB_INTERFACE_INFO(cl, sc, pr) \.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \.bInterfaceClass = (cl), \.bInterfaceSubClass = (sc), \.bInterfaceProtocol = (pr)
所以它表示只要是hid设备,且支持bios引导,且引导时的协议为mouse,则此驱动都可以处理。
如果只声明支持一个设备可以用如下宏
linux/include/usb.h
#define USB_DEVICE(vend,prod) \.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \.idVendor = (vend), \.idProduct = (prod)
比如在usb_device_id里 添加一项,USB_DEVICE(0606,0001)
*****************************************************************************************************************************************************************************
一下是一个最简单的usb测试程序(比较完整的见linux-2.6.32.2/drivers/usb/usb-skeleton.c),仅测试一下usbcore对设备枚举玩,是否能够成功和此驱动匹配而进入probe函数
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h>/** Version Information*/
#define DRIVER_VERSION "v1.0"
#define DRIVER_AUTHOR "song"
#define DRIVER_DESC "usb test"
#define DRIVER_LICENSE "GPL"MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);static int test_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{printk("probe\n");return 0;
}static void test_usb_disconnect(struct usb_interface *intf)
{
printk("disconnect\n");
}static struct usb_device_id test_usb_id_table [] = {{USB_DEVICE(0x0606,0x0001) }, {}
};MODULE_DEVICE_TABLE (usb, test_usb_id_table);static struct usb_driver test_usb_driver = {.name = "test_song",.probe = test_usb_probe,.disconnect = test_usb_disconnect,.id_table = test_usb_id_table,
};static int __init test_usb_init(void)
{int retval = usb_register(&test_usb_driver);if (retval == 0)printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"DRIVER_DESC "\n");return retval;
}static void __exit test_usb_exit(void)
{usb_deregister(&test_usb_driver);
}module_init(test_usb_init);
module_exit(test_usb_exit);
makefile
ifneq ($(KERNELRELEASE),)
obj-m := test_usb.o
else
KDIR := /opt/FriendlyARM/mini2440/linux-2.6.32.2
#KDIR := /lib/modules/`uname -r`/build
all: make -C $(KDIR) M=$(PWD) modules
clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif
而设备侧(我的是sic8051f320单片机,内含usb从接口)的设备描述符和接口描述符,报告描述符设置如下,一下是一个自定义hid设备的部分描述符的设置
code DEVICE_DESCRIPTOR DeviceDesc =
{18, // bLength0x01, // bDescriptorTypeSWAP16(0x0200), // bcdUSB0x00, // bDeviceClass0x00, // bDeviceSubClass0x00, // bDeviceProtocolEP0_PACKET_SIZE, // bMaxPacketSize0SWAP16(USB_HID_VID), // idVendor 0x0606 和linux侧驱动中的对应SWAP16(USB_HID_PID), // idProduct 0x0001 和linux侧驱动中的对应0x0001, // bcdDevice0x01, // iManufacturer0x02, // iProduct0x03, // iSerialNumber0x01 // bNumConfigurations
}; //end of DeviceDesc
{0x09, // bLength0x04, // bDescriptorType0x00, // bInterfaceNumber0x00, // bAlternateSetting0x02, // bNumEndpoints0x03, // bInterfaceClass 指定为hid类0x00, // bInterfaceSubClass 非鼠标键盘 00x00, // bInterfaceProcotol 非鼠标键盘 00x00 // iInterface}, //end of InterfaceDesc
//Report descriptor
code unsigned char ReportDesc[] =
{// 0x06, 0x00, 0xFF,// ; Usage Page0x05, 0x01, //桌面设备// 0x09, 0x01,// ; Usage0x09, 0x00, //未定义用途,结合接口描述符的bInterfaceClass=03,则为自动以hid0xA1, 0x01, // ; Collection//用未定义用途开集合0x09, 0x01,// ; Usage0x95, 0x20,// ; Report Count0x75, 0x08,// ; Report Size0x15, 0x00,// ; Logical Minimum0x26, 0xFF, 0x00,// ; Logical Maximum0x81, 0x02,// ; Input0x09, 0x02,// ; Usage0x95, 0x20,// ; Report Count0x75, 0x08,// ; Report Size0x91, 0x02,// ; Output0xC0
};
在板子上,先不要插usb设备
[root@FriendlyARM plg]# insmod test_usb.ko
usbcore: registered new interface driver test_song
test_usb: v1.0:usb test
插上设备,信息如下,出现probe信息,说明成功匹配到驱动
[root@FriendlyARM plg]# usb 1-1.1: new full speed USB device using s3c2410-ohci and address 8
usb 1-1.1: New USB device found, idVendor=0606, idProduct=0001//厂商和产品id。不要受迷惑,是0x0606和0x0001
usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1.1: Product: nRF24LU1 ADapter
usb 1-1.1: Manufacturer: Weisdigital
usb 1-1.1: SerialNumber: Ver1.0 N000
usb 1-1.1: configuration #1 chosen from 1 choice//以上这些信息由usbcore在枚举完设备打印出来
probe
拔出设备,触发函数test_usb_disconnect,信息如下
usb 1-1.1: USB disconnect, address 8
disconnect
****************************************************************************************************************************************************************
另外在mini2440上已经有一个配置,
Device Drivers ---> [*] HID Devices ---> <*> USB Human Interface Device (full HID) support
这个驱动貌似通吃所有hid设备,包括mouse kbd,自定义hid等。所以如果我插入我的自定义hid设备时,就会被usbcore把我的设备优先匹配给这个驱动(即使我自己写的驱动已经insmod),这个驱动会在其probe函数中为我的设备自动创建一个input驱动,设备文件在/dev/input/eventx(x=1 2 3 ...)。但是我的设备没有按鼠标或键盘的数据格式给主机usbcore传送数据(当然我也不想这样传输,因为我的设备是自定义hid设备,当然要自定义的数据及格式,当然也不想让这个驱动去处理我的设备发来的数据)。
目前的解决办法是把这个选项给禁掉。这样usbcore就会把我的自定义hid设备匹配给我自己写的驱动了。
当然禁掉之后,usb鼠标 键盘都不能用了。不过可以配置一下另外一个鼠标和键盘的驱动,也可用的。如下
Device Drivers ---> [*] HID Devices --->USB HID Boot Protocol drivers ---> <*> USB HIDBP Keyboard (simple Boot) support
<*> USB HIDBP Mouse (simple Boot) support
不过要想出现USB HID Boot Protocol drivers项目,需要一些操作,在Kconfig文件line 47如下
menu "USB HID Boot Protocol drivers"depends on USB!=n && USB_HID!=y && EMBEDDED
即
USB符号不要选择为空(要选择m或y),USB_HID符号不要选择为y。最后那个符号EMBEDDED暂时没找到在哪里配的,就删掉了。即
menu "USB HID Boot Protocol drivers"
depends on USB!=n && USB_HID!=y
按照上面设置以后就会make menuconfig里就会出现USB HID Boot Protocol drivers项目。
再看一下/linux-2.6.32.2/drivers/hid/usbhid/Makefile,
# Multipart objects.
usbhid-objs := hid-core.o hid-quirks.o# Optional parts of multipart objects.ifeq ($(CONFIG_USB_HIDDEV),y)usbhid-objs += hiddev.o
endif
ifeq ($(CONFIG_HID_PID),y)usbhid-objs += hid-pidff.o
endifobj-$(CONFIG_USB_HID) += usbhid.o
obj-$(CONFIG_USB_KBD) += usbkbd.o
obj-$(CONFIG_USB_MOUSE) += usbmouse.
可知
<*> USB Human Interface Device (full HID) support 对应的驱动应该是/linux-2.6.32.2/drivers/hid/usbhid/usbhid.c
<*> USB HIDBP Keyboard (simple Boot) support 对应的驱动是/linux-2.6.32.2/drivers/hid/usbhid/usbkbd.c
<*> USB HIDBP Keyboard (simple Boot) support 对应的驱动是/linux-2.6.32.2/drivers/hid/usbhid/usbmouse.c
后两者还好说,目录下确实有usbkbd.c和usbmouse.c,但是没有usbhid.c文件,那么usbhid.o哪里来的呢?恩,没人规定usbhid.o非得只由usbhid.c才能生成。
同目录下有一个文件.usbhid.o.cmd ,记录了usbhid.o由hid-quirks.o和hid-core.o生成。目前为止感觉很麻烦の。
arm-linux-ld -EL -r -o drivers/hid/usbhid/usbhid.o drivers/hid/usbhid/hid-core.o drivers/hid/usbhid/hid-quirks.o
转载于:https://www.cnblogs.com/-song/archive/2011/10/31/3331936.html
usb5-写成usb驱动相关推荐
- rfid3-micro2440,linux2.6.32.2,写成misc驱动
接上文的进度,将keil下已经成功的读卡程序写成linux驱动的形式 采用misc来写比较方便简单,仅是为了方便测试,好多都在驱动中实现. 主文件是rfid.c #include "rc52 ...
- 10 怎么写USB驱动,Cadence USB 2.0 Controller和PHY IP驱动移植
怎么写USB驱动,Cadence USB 2.0 Controller和PHY IP驱动移植 作者 将狼才鲸 日期 2022-03-26 本子文档所属的上级文档(Gitee仓库): 才鲸 / 嵌入式知 ...
- linux usb驱动 probe,linux USB设备驱动之2:usb设备的probe全过程
本文将详细讲述2.6.22下的一个USB设备插上linux系统的PC后是如何一步一步调到我们的usb设备驱动的probe函数的,我们知道我们的USB驱动的probe函数中的一个参数是interface ...
- linux鼠标驱动程序,Linux usb子系统(一) _写一个usb鼠标驱动
USB总线是一种典型的热插拔的总线标准,由于其优异的性能几乎成为了当下大小设备中的标配. USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动 ...
- 旗舰版ndows7bios设置,戴尔成铭 3988台式机装win7系统的方法(intel 9代BIOS设置方法和USB驱动)...
戴尔成铭 3988是一个台式机电脑,这台电脑就在出厂的时候采用的处理器是intel的第9代系列平台,这代平台的话官方是没有兼容win7系统的usb驱动的,因而用普通的方法安装完成了Win7后,全部的u ...
- Linux下烧写工具DNW和USB驱动安装
Linux下编译记录: 编译PC端USB驱动和写入工具 dnw_linux.tgz压缩包文件结构如下 dnw_linux/ dnw_linux/secbulk/ dnw_linux/secbulk/M ...
- Linux USB驱动框架分析 【转】
转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...
- 通用usb驱动libusb介绍和使用示例
小知识: sudo insmod /lib/modules/2.6.22-14-generic/kernel/drivers/usb/serial/usbserial.ko vendor=0x8086 ...
- 【驱动】USB驱动·入门
Preface USB是目前最流行的系统总线之一.随着计算机周围硬件的不断扩展,各种设备使用不同的总线接口,导致计算机外部总线种类繁多,管理困难.USB总线正是因此而诞生的. USB总线提供了所有外部 ...
最新文章
- 伦理困境:人工智能浪潮与“AI威胁论”之争
- C++__min_element()和max_element()函数的使用
- 软件架构:5种你应该知道的模式
- 工业用微型计算机笔记(2)-二进制有符号数
- java抽象类的构造函数如何定义_我们可以在Java的抽象类中定义参数化的构造函数吗?...
- controlleradvice 参数_Spring MVC之@ControllerAdvice详解
- HDFS常用的Api
- ESP8266-01学习笔记01:如何使用USB转串口对ESP-01进行入门调试、烧录固件?
- python打印菱形星号代码_Python打印“菱形”星号代码
- 为普通用户添加root权限
- AntTweakBar with OpenGL
- 如何判断两物体加速度相等_高中物理知识点总结解题技巧:关联物体问题的求解方法...
- zmap扫描mysql_网站安全扫描工具 zmap怎么进行全网检测 - 驱动管家
- html页面怎么加入qq群,qq群申请
- 人工合成生命的最新进展比AI还快
- PowerBI 实现中国式报表
- 关于Python爬取热搜的另一种方法
- 微信小程序时间显示几分钟前、几小时前、几天前....
- Docker Image 基础使用命令
- 记录-关于网站的欢迎页,初次进入可见欢迎页,再次进入就直接显示主页了
热门文章
- WMI使用的WIN32_类库名
- Configuring Locales
- java.util.ConcurrentModificationException
- 解决Unable to create group (name already exists)
- git个人使用总结 —— idea命令行、撤销commit (未完待续)
- python 游戏 —— 汉诺塔(Hanoita)
- vs2015网站发布时,设置页面合并后程序集的文件版本
- 项目拆分子工程(简单版)
- Fiddler插件开发 - 实现网站离线浏览功能
- Python中的生成器与yield