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

来源:http://www.cnblogs.com/EaIE099/archive/2016/01/05/5102601.html
-Advertisement-
Play Games

USB 設備驅動:一、USB 描述符:(存在於USB 的E2PROM裡面)1、 設備描述符:struct usb_device_descriptor2、 配置描述符:struct usb_config_descriptor3、 介面描述符:struct usb_interface_descripto...


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_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 };

 

五、  管道

每個端點通過管道和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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • FrameSet框架集
  • 之前我在一篇blog中寫過如何使用多語言工具包,見http://www.cnblogs.com/yanxiaodi/p/3800767.html在WinEcos社區也發佈過一篇詳細的文章介紹多語言工具包的使用,但因社區改版那篇文章已經找不到了。當時寫的時候還沒有出Win10的SDK,都是基於UAP框...
  • 當HttpContext對象創建之後,HttpRuntime將隨後創建一個用於處理請求的對象,這個對象的類型為HttpApplication. 在ASP.NET內部,HttpRuntime管理一個定義在System.Web命名空間下的HttpApplicationFactory類的實例...
  • 在mac上截屏的幾種方式
  • 1、圖像的延遲一幀的問題,主要原因如代碼中所說,只有隊列多餘兩幀的時候才會出隊一幀。該問題對於連續的圖像幀基本無影響,只是對於非連續的情況下,進來的第一幀會延後,先出來的是上一次圖像序列中最後一幀。而當次圖像序列的最後一幀將會被刷到隊列中。 如果將其中的2改寫為1,則會出現圖像上下分層現象,上層是....
  • - check-rpaths的問題 今天在編譯varnish的時候,遇到幾個問題,其中一個就是出現如下錯誤:...+ /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot************************************....
  • 安裝參見: https://github.com/oetiker/SmokePing/blob/master/doc/smokeping_install.pod 1 Smokeping 2 3 *** General *** 4 5 owner = Ctry 6 contact...
  • 發現伺服器的cpu使用率特別高排查思路:-使用top或者mpstat查看cpu的使用情況# mpstat -P ALL 2 1Linux 2.6.32-358.el6.x86_64 (linux—host) 01/05/2016 _x86_64_ (24 CPU)04:41:13 PM CPU...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...