USB驱动模型
1.USB host controller driver(主控器驱动):为USB主控制器提供驱动程序
2.USB core(USB核心):连接USB主控制器驱动和USB设备驱动
3.USB client driver:为USB外部设备提供驱动程序
USB设备模型
device(设备)->config(配置)->interface(接口)->endpoint(端点),构成了USB设备的四个层次。一个usb driver(驱动)对应的是一个interface(接口)。一个接口对应一个基本功能。
在Linux内核中,使用struct usb_driver结构描述一个usb驱动。
struct usb_driver{
const char *name; //驱动设备名
int (*)probe(struct usb_interface *intf, const struct usb_device_id *id); //当USB核心发现了该驱动能够处理USB接口时,调用该函数
void (*disconnect)(struct usb_interface *intf); //当相应的USB接口被移除时,调用该函数
const struct usb_device_id *id_table; //USB驱动能够处理的设备列表
};
URB通讯模式
主机向设备发出请求,然后设备响应请求。发起请求的源是usb client driver,然后提供给usb core,接着传给usb host controller driver,最后通过主控制器发给usb设备。主控器收到响应后按原路返回,交给usb client driver。USB请求是通过内核中的URB来描述的。
USB请求块(USB request block-URB)是USB设备驱动中用来与USB设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff结构体,是USB主机与设备通信的电波。
URB使用方法
1.USB设备驱动程序创建并初始化一个访问特定端口的urb,并提交给USB core
2.USB core提交该urb到USB主控制器驱动程序。
3.USB主控器驱动程序根据该urb描述信息,来访问USB设备。
4.当设备访问结束后,USB主控制器驱动程序按原来返回,通过usb core来通知USB设备驱动程序。
1.创建URB
struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
参数:
iso_packets:urb所包含的等时数据包个数
mem_flags:内存分配标识(如GFP_KERNEL),参考kmalloc
2.初始化URB
对于中断urb,使用usb_fill_int_urb函数来初始化
对于批量urb,使用usb_fill_bulk_urb函数来初始化
对于控制urb,使用usb_fill_control_urb函数来初始化
对于等时urb,只能手动初始化urb
static inline void usb_fill_int_urb(
struct urb *urb, //待初始化的urb
struct usb_device *dev, //urb所要访问的设备
unsigned int pipe, //要访问的端点所对应的管道
void *transfer_buffer, //保存传输数据的buffer
int buffer_length, //buffer长度
usb_complete_t complete_fn, //urb完成时调用的函数
void *context, //赋值到urb->context的数据
int interval //urb被调度的时间间隔
)
3.提交URB
在完成urb的创建和初始化后,USB驱动需要将urb提交给USB核心。
int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
参数:
urb:要提交的urb指针
mem_flags:内存分配标识(如GFP_KERNERL),参考kmalloc
URB被提交到USB核心后,USB核心指定usb主控制器驱动程序来处理该urb。处理完成之后,urb完成函数将被调用。
HID协议
HID(Human Interface Device)是属于人机交互的设备。如USB鼠标,USB键盘,USB游戏操纵杆等。这类设备必须遵循HID设计规范。
HID设备如何把数据报给主机
设备通过4个字符的报告描述符把数据回传给主机