1、USB总线驱动程序的作用:
A、识别USB设备
B、查找并安装对应的设备USB设备驱动程序
C、提供USB读写函数
2、将USB设备接入USB口观察输出信息,然后拔掉,然后再接上,观察串口打印信息
3、在内核代码driver目录下,搜索上面打印的内容:
grep "xxx" * -nR
4、分析/usb/core/hub.c ,找到2657行
5、
给新设备分配编号:
把编号地址告诉USB设备:
获取设备描叙符:
初始化新设备
把device放入usb_bus_type的dev链表,从usb_bus_type的driver链表里取出usb_driver,
把usb_interface和usb_driver的id_table比较,如果能匹配,调用usb_driver的probe
6、内核中头文件ch9.h表示USB协议的第9章,该头文件中定义了几个设备、配置、接口、端口描叙符的定义
设备描叙符:
配置描叙符
接口描叙符
端口描叙符
7、接入USB设备后,用lsusb命令察看,可以看到对应的描叙符
8、usb_driver结构体描叙了一个USB设备驱动,在编写USB设备驱动的时候,主要应该完成的工作是probe()和disconnect()函数,即探测和断开函数,它们在设备插入和拔出的时候被调用。Id_table成员描叙了这个USB驱动所支持的USB设备列表,指向一个usb_device_id数组。该结构体中的函数是USB设备驱动中USB相关的部分,而USB只是一个总线,真正的USB设备驱动的本体工作仍然是USB设备本身所属类型的驱动,如字符设备驱动
9、尽管USB本身所属设备驱动的结构与不挂在USB总线上时完全相同,但是在访问方式上却发生了很大的变化。例如,对于字符设备驱动而言,尽管仍然是write(), read(), ioctl()这些函数,但是在这些函数中,与USB设备通信时不再是I/O内存和I/O端口的访问,而贯穿始终的是称为URB的USB请求块,这些请求块通过USB总线驱动提供的读写等接口进行操作
10、USB请求块是USB设备驱动中用来描叙与USB设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buffer结构体,是USB主机与设备通信的“电波”
11、 URB处理流程:USB设备中的每个端点都处理一个URB对列
A、创建URB结构体
Struct urb *usb_alloc_urb(int iso_packet, int mem_flags);
B、初始化并安排URB给一个特定的USB设备的特点端点
对于中断传输方式 ,使用函数usb_fill_int_urb
上面pipe参数可以通过usb_rcvintpipe()创建
C、提交URB给USB核心,开始一次USB数据传输
Usb_submit_urb(struct urb *urb, int mem_flags);
12、USB鼠标驱动,注意要去掉原来的鼠标驱动
HID devices------
USB Human Interface Device (full HID) support
Usb驱动的相关结构体
struct usb_driver {
const char *name;
int (*probe) (struct usb_interface *intf,
const struct usb_device_id *id);
void (*disconnect) (struct usb_interface *intf);
int (*ioctl) (struct usb_interface *intf, unsigned int code,
void *buf);
int (*suspend) (struct usb_interface *intf, pm_message_t message);
int (*resume) (struct usb_interface *intf);
int (*reset_resume)(struct usb_interface *intf);
int (*pre_reset)(struct usb_interface *intf);
int (*post_reset)(struct usb_interface *intf);
const struct usb_device_id *id_table;
struct usb_dynids dynids;
struct usbdrv_wrap drvwrap;
unsigned int no_dynamic_id:1;
unsigned int supports_autosuspend:1;
unsigned int soft_unbind:1;
};