Linux USB驅動學習總結(二)---- USB設備驅動

USB 設備驅動:數據結構

1、USB 描述符:(存在於USB 的E2PROM裏面)app

一、  設備描述符:struct usb_device_descriptor異步

二、  配置描述符:struct usb_config_descriptor函數

三、  接口描述符:struct usb_interface_descriptorui

四、  端點描述符:struct usb_endpoint_descriptoratom

 

經過命令lsusb 列出系統中全部的USB設備:spa

經過命令lsusb -v 列出系統中全部的USB設備的各個描述符信息:指針

設備描述符:code

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));

 

 

2、USB的傳輸方式:(不一樣的設備對於傳輸的數據各有各的要求)

一、  控制傳輸---獲取/配置設備

二、  中斷傳輸---例如USB鼠標、USB鍵盤(這裏說的中斷和硬件上下文的中斷不同,它不是設備主動發送一箇中斷請求,而是主控制器在保證不大於某個時間間隔interval內安排的一次數據傳輸)

三、  批量傳輸---用於大容量數據傳輸,沒有固定的傳輸速率,例如usb打印機、掃描儀、U盤等,對應的端點就叫批量端點

四、  等時傳輸---能夠傳輸大批量數據,可是對數據是否到達沒有保證,對實時性要求很高, 例如音頻、視頻等設備(USB攝像頭、USB話筒),對應的端點就叫等時端點

 

3、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的使用方法:

一、  分配urb

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

二、  初始化urb

void usb_fill_[control | int | bulk]_urb{ } ///對應控制傳輸、中斷傳輸、批量傳輸

三、  提交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

 

4、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_PM
62     unsigned long connect_time;
63 
64     unsigned do_remote_wakeup:1;
65     unsigned reset_resume:1;
66     unsigned port_is_suspended:1;
67 #endif
68     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 };

 

5、  管道

每一個端點經過管道和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
相關文章
相關標籤/搜索