你的位置:首页 > 操作系统

[操作系统]Linux USB驱动学习总结(二)


USB 设备驱动:

一、USB 描述符:(存在于USB 的E2PROM里面)

1、  设备描述符:struct usb_device_descriptor

2、  配置描述符:struct usb_config_descriptor

3、  接口描述符:struct usb_interface_descriptor

4、  端点描述符:struct usb_endpoint_descriptor

 

通过命令lsusb 列出系统中所有的USB设备:

通过命令lsusb -v 列出系统中所有的USB设备的各个描述符信息:

设备描述符:

struct usb_device_descriptor {  __u8 bLength; ///长度  __u8 bDescriptorType; ///描述符类型  __le16 bcdUSB;  __u8 bDeviceClass;///设备类型  __u8 bDeviceSubClass;///设备子类型  __u8 bDeviceProtocol;///协议  __u8 bMaxPacketSize0;///最大传输大小  __le16 idVendor;///厂商 ID  __le16 idProduct;///设备 ID  __le16 bcdDevice;///  __u8 iManufacturer;  __u8 iProduct;  __u8 iSerialNumber;///序列号  __u8 bNumConfigurations;///包含的配置数目(每个USB设备会对应多个配置)} __attribute__ ((packed));


配置描述符:

struct usb_config_descriptor {     ///USB 配置描述符     __u8 bLength;     __u8 bDescriptorType;     __le16 wTotalLength;///总长度     __u8 bNumInterfaces;///接口数目(每个接口代表一种功能)     __u8 bConfigurationValue;///     __u8 iConfiguration;     __u8 bmAttributes;     __u8 bMaxPower;} __attribute__ ((packed));

 

 

接口描述符:

 

struct usb_interface_descriptor { ///USB 接口描述符     __u8 bLength;     __u8 bDescriptorType;     __u8 bInterfaceNumber;     __u8 bAlternateSetting;     __u8 bNumEndpoints;     __u8 bInterfaceClass;     __u8 bInterfaceSubClass;     __u8 bInterfaceProtocol;     __u8 iInterface;} __attribute__ ((packed));

 

 

端点描述符:

struct usb_endpoint_descriptor {  ///USB 端点描述符(每个USB设备最多有16个端点)     __u8 bLength; ///描述符的字节长度     __u8 bDescriptorType;///描述符类型,对于端点就是USB_DT_ENDPOINT     __u8 bEndpointAddress;///bit0~3表示端点地址,bit8 表示方向,输入还是输出     __u8 bmAttributes;///属性(bit0、bit1构成传输类型,00--控制,01--等时,10--批量,11--中断)     __le16 wMaxPacketSize;///端点一次可以处理的最大字节数     __u8 bInterval;///希望主机轮询自己的时间间隔     /* NOTE: these two are _only_ in audio endpoints. */     /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */     __u8 bRefresh;     __u8 bSynchAddress;} __attribute__ ((packed));

 

 

二、USB的传输方式:(不同的设备对于传输的数据各有各的要求)

1、  控制传输---获取/配置设备

2、  中断传输---例如USB鼠标、USB键盘(这里说的中断和硬件上下文的中断不一样,它不是设备主动发送一个中断请求,而是主控制器在保证不大于某个时间间隔interval内安排的一次数据传输)

3、  批量传输---用于大容量数据传输,没有固定的传输速率,例如usb打印机、扫描仪、U盘等,对应的端点就叫批量端点

4、  等时传输---可以传输大批量数据,但是对数据是否到达没有保证,对实时性要求很高, 例如音频、视频等设备(USB摄像头、USB话筒),对应的端点就叫等时端点

 

三、URB(usb request block),USB请求块

urb 是usb数据传输机制使用的核心数据结构,urb供usb协议栈使用;

struct urb { //由主机控制器发送给USB设备  struct kref kref;    /* reference count of the URB */  void *hcpriv;      /* private data for host controller */  atomic_t use_count;    /* concurrent submissions counter */  atomic_t reject;    /* submissions will fail */  struct list_head urb_list;  /* list head for use by the urb's           * current owner */  struct list_head anchor_list;  /* the URB may be anchored */  struct usb_anchor *anchor;  struct usb_device *dev;    /* (in) pointer to associated device */ ///urb所发送的目标指针,在urb可以被发送到USB核心之前必须由USB驱动程序初始化  struct usb_host_endpoint *ep;  /* (internal) pointer to endpoint */  unsigned int pipe;  //通过端点的number来得到,决定了主机数据要发送给哪一个设备  unsigned int stream_id;    /* (in) stream ID */  int status;      /* (return) non-ISO status */  unsigned int transfer_flags;  /* (in) URB_SHORT_NOT_OK | ...*/  void *transfer_buffer;    /* (in) associated data buffer */ ///in---接收数据buffer,out----发送数据buffer  dma_addr_t transfer_dma;  /* (in) dma addr for transfer_buffer *////存在于支持DMA的设备  struct scatterlist *sg;    /* (in) scatter gather buffer list */  int num_mapped_sgs;    /* (internal) mapped sg entries */  int num_sgs;      /* (in) number of entries in the sg list */  u32 transfer_buffer_length;  /* (in) data buffer length */  u32 actual_length;    /* (return) actual transfer length */  unsigned char *setup_packet;  /* (in) setup packet (control only) */  dma_addr_t setup_dma;    /* (in) dma addr for setup_packet */  int start_frame;    /* (modify) start frame (ISO) */  int number_of_packets;    /* (in) number of ISO packets */  int interval;      /* (modify) transfer interval ///主机轮询的时间间隔  void *context;      /* (in) context for completion *////上下文  usb_complete_t complete;  /* (in) completion routine *////完成例程(回调)--当主机发送完urb,设备返回回应信号时执行};

 

urb的使用方法:

1、  分配urb

struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags);  //\drivers\usb\core\urb.c

2、  初始化urb

void usb_fill_[control | int | bulk]_urb{ } ///对应控制传输、中断传输、批量传输

3、  提交urb(提交给主控制器,由主控制器发送给USB设备)

(1)  异步提交urb,提交完成后执行通过usb_fill_[control | int | bulk]_urb 传入的回调函数

int usb_submit_urb(struct urb *urb, gfp_t mem_flags); //\drivers\usb\core\urb.c

(2) 同步提交urb

int  usb_[control | interrupt | bulk]_msg ()  //\drivers\usb\core\Message.c

 

四、usb驱动数据结构 usb_device

 1 struct usb_device { ///描述一个USB 设备 2   int    devnum; 3   char    devpath[16]; 4   u32    route; 5   enum usb_device_state  state; 6   enum usb_device_speed  speed; 7  8   struct usb_tt  *tt; 9   int    ttport;10 11   unsigned int toggle[2];12 13   struct usb_device *parent;14   struct usb_bus *bus;15   struct usb_host_endpoint ep0;16 17   struct device dev;18 19   struct usb_device_descriptor descriptor;20   struct usb_host_bos *bos;21   struct usb_host_config *config;22 23   struct usb_host_config *actconfig;24   struct usb_host_endpoint *ep_in[16];25   struct usb_host_endpoint *ep_out[16];26 27   char **rawdescriptors;28 29   unsigned short bus_mA;30   u8 portnum;31   u8 level;32 33   unsigned can_submit:1;34   unsigned persist_enabled:1;35   unsigned have_langid:1;36   unsigned authorized:1;37   unsigned authenticated:1;38   unsigned wusb:1;39   unsigned lpm_capable:1;40   unsigned usb2_hw_lpm_capable:1;41   unsigned usb2_hw_lpm_besl_capable:1;42   unsigned usb2_hw_lpm_enabled:1;43   unsigned usb2_hw_lpm_allowed:1;44   unsigned usb3_lpm_enabled:1;45   int string_langid;46 47   /* static strings from the device */48   char *product;49   char *manufacturer;50   char *serial;51 52   struct list_head filelist;53 54   int maxchild;55 56   u32 quirks;57   atomic_t urbnum;58 59   unsigned long active_duration;60 61 #ifdef CONFIG_PM62   unsigned long connect_time;63 64   unsigned do_remote_wakeup:1;65   unsigned reset_resume:1;66   unsigned port_is_suspended:1;67 #endif68   struct wusb_dev *wusb_dev;69   int slot_id;70   enum usb_device_removable removable;71   struct usb2_lpm_parameters l1_params;72   struct usb3_lpm_parameters u1_params;73   struct usb3_lpm_parameters u2_params;74   unsigned lpm_disable_count;75 };

 

五、  管道

每个端点通过管道和usb主控制器连接,管道包括以下几个部分:

(1)     端点地址

(2)     数据传输方向(in 或 out)

(3)     数据传输模式

usb_[rcv| snd| ctrl| int| bulk| isoc ]pipe

根据端点地址、传输方式和传输方向创建不同的pipe:

#define usb_sndctrlpipe(dev, endpoint)  \  ((PIPE_CONTROL << 30) | __create_pipe(dev, endpoint))#define usb_rcvctrlpipe(dev, endpoint)  \  ((PIPE_CONTROL << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN)#define usb_sndisocpipe(dev, endpoint)  \  ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev, endpoint))#define usb_rcvisocpipe(dev, endpoint)  \  ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN)#define usb_sndbulkpipe(dev, endpoint)  \  ((PIPE_BULK << 30) | __create_pipe(dev, endpoint))#define usb_rcvbulkpipe(dev, endpoint)  \  ((PIPE_BULK << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN)#define usb_sndintpipe(dev, endpoint)  \  ((PIPE_INTERRUPT << 30) | __create_pipe(dev, endpoint))#define usb_rcvintpipe(dev, endpoint)  \  ((PIPE_INTERRUPT << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN