
文章目录
USB驱动程序简介
USB设备驱动程序(分层划分)

USB设备驱动程序位于不同的内核子系统和USB主机控制器之间. USB内核为USB驱动程序提供了访问和控制USB硬件的软件接口,因此USB设备驱动程序不需要考虑USB硬件控制设备.
USB设备级别:

从上图可以看出,USB设备的逻辑层次可以分为: 设备,配置,接口,端点
要点:
USB驱动程序说明
在Linux内核中,使用struct usb_driver结构描述USB驱动程序.
struct usb_driver
{
const char *name; //驱动程序名
/*当USB核心发现了该驱动能够处理USB接口时,调用次函数*/
int (*probe)(struct usb_interface *intf,const struct usb_device_id *id);
/*当相应的USB接口被移除时,调用此函数*/
void (*disconnect)(struct usb_interface *intf);
/*USB驱动能够处理的设备列表*/
const struct usb_device_id *id_table;
};
USB设备列表
设备:
Linux内核提供了一个宏USB_DEVICE来定义USB设备

USB_DEVICE(销售,生产)
参数:
示例(USB OV511):
USB_DEVICE(VEND_OMNIVISION,PROD_OV511)
#define VEND_OMNIVISION 0x05A9
#define PROD_OV511 0x0511
构造usb_device_id

一流的设备:
Linux内核提供了USB_INTERFACE_INFO宏来帮助定义USB设备的类型
USB_INTERFACE_INFO(cl,sc,pr)
参数:
示例(USB鼠标)
USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE)
注册驱动程序

Linux内核提供了usb_register函数来注册USB驱动程序.
static inline int usb_register(struct usb_driver *driver)
Linux USB描述符设备描述
Linux内核使用struct usb_device来描述USB设备
struct usb_device
{
int devnum; //USB设备号
char devpath[16]; //设备ID字符串
enum usb_device_state state; //设备状态:未连接,已配置
enum usb_device_speed speed; //高速;全速;低速
struct usb_device_descriptor descriptor; //USB设备描述符
struct usb_host_config *config;
char *product; //产品号
char *manufacturer; //厂商名
char *serial; //设备串号
};
设备说明
上述结构中包含的结构: usb_device_descriptor对应于USB描述符中的设备描述符
struct usb_device_descriptor
{
__u8 bLength;
__u8 bDescriptorTypr;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__le16 idVendor;
__le16 idProduct;
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__((packed)); //按字节对齐
严格遵循与USB协议一致的USB设备描述符;
配置说明:
上述结构struct usb_device: usb_device_host_config中包含的结构用于描述USB配置:
struct usb_host_config
{
struct usb_config_descriptor desc; //配置描述符
char *string; //配置的字符串(如果存在)
//接口链表
struct usb_interface *interface[USB_MAXINTERFACES];
};
在上述结构中构造usb_config_descriptor

界面说明

Linux内核使用struct usb_interface来描述USB接口.
struct usb_interface
{
struct usb_host_interface *altsetting; //接口设置数组
struct usb_host_interface *cur_altsetting; //当前设置
unsigned num_altsetting; //设置数
};
配置VS设置
示例:

界面设置
Linux内核使用struct usb_host_interface描述USB接口设置
struct usb_host_interface
{
struct usb_interface_descriptor desc;//接口描述符
struct usb_host_endpoint *endpoint; //接口包含的端点
};
接口描述符
Linux内核使用struct usb_interface_descriptor来对应USB描述符中的接口描述符:

端点描述
Linux内核使用结构usb_host_endpoint来描述USB端点
struct usb_host_endpoint
{
struct usb_endpoint_descriptor desc; //端点描述符
struct list_head usb_list; //urb
.........
.........
};


USB URBURB定义
USB请求块(USB请求块,urb)在USB设备驱动程序中用于描述用于与USB设备通信的基本载体和核心数据结构. 它与网络设备驱动程序中的sk_buff结构非常相似. 它是USB主机和用于设备通信的“波”.
URB处理流程USB设备驱动程序创建并初始化一个访问特定USB设备特定端点的urb,并将其提交给USB内核. USB内核将urb提交给USB主机控制器驱动程序;根据urb的USB主机控制器驱动程序. 所描述的信息用于访问USB设备;设备访问结束后,USB主机控制器驱动程序会通知USB设备驱动程序. 创建URB
创建URB函数为:
struct *usb_alloc_urb(int iso_packets,gtp_t mem_flags)
参数:
初始化URB
static inline void usb_fill_int_urb(struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,
void *context,
int interval)
参数:
提交URB
创建并初始化urb之后,可以通过usb_submit_urb函数将urb提交到USB内核
int usb_submit_urb(struct urb *urb,gfp_t mem_flags)
参数:
处理URB
在提交URB之后,USB内核会指定主机控制器驱动程序来处理urb. 在3种情况下,urb将被视为已处理.
urb已成功发送到设备,并且设备返回正确的确认. 如果urb-> status为0,则表示对于输出urb,数据已成功发送;对于输入urb,请求的数据已成功接收. 如果向设备发送数据或从设备接收数据时发生错误,则urb-> status将记录错误值. urb是““已取消””. 当驱动程序通过usb_unlink_urb()或usb_kill_urb()函数取消urb或已提交urb但拔掉USB设备时,会发生这种情况.
urb处理完成后,将调用urb完成功能.
USB鼠标驱动程序的分析与设计
代码部分mouse.c
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-291805-1.html
跟中国实体经济不是因果关系
胜利就在前方我们一起来~~~~