在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

深度剖析USB設備端驅動框架

strongerHuang ? 來源:漫談嵌入式 ? 作者:漫談嵌入式 ? 2021-06-07 14:12 ? 次閱讀

hello 大家好,今天帶領大家學習一下USB設備端驅動

內核版本:4.4.94

1. Linux USB 子系統在介紹設備端驅動前,我們先來看看 Linux USB子系統。這里的子系統是相對于整個Linux kernel 來說的,而非單一設備。從整體概括了USB主機端和設備端的通信框架。

Linux kernel 中早已集成了較為完善的USB協議棧,由于其規模龐大,包含多個類別的設備驅動,所以Linux系統中的USB協議棧也被稱為USB子系統。

1.1 主機端

主機端,簡化抽象三層:

各種類設備驅動:mass sotrage, CDC, HID等

USB 設備驅動:USB 核心處理

主機控制器驅動:不同的USB主機控制器(OHCI/EHCI/UHCI),抽象為HDC。

1.2 設備端

設備端,也抽象為三層:

設備功能驅動:mass sotage , CDC, HID 等,對應主機端的類設備驅動

Gadget 設備驅動:中間層,向下直接和UDC通信,建立鏈接;向上提供通用接口,屏蔽USB請求以及傳輸細節。

設備控制器驅動:UDC驅動,直接處理USB設備控制器。

2. USB 設備驅動2.1 gadget 驅動框架拆解1

我們將USB 設備端驅動拆解一下。

上文提到,Gadget 設備層起著至關重要的作用。為上層提供通用的驅動框架,與下層UDC通過Gadget Interface 建立聯系。

其中Compsite Framwork 提供了一個通用的usb_gadget_driver 模板,包括各種方法供上層Function driver 使用。(driver/usb/gadget/compsite.c)

從上圖我們可以看出,對于USB設備端驅動開發而言,更多的關注的是Function driver這層。USB 控制相關過程,內核提供了一個中間層幫我們屏蔽掉了。

2.2 gadget 驅動框架拆解2

內核版本:Linux Kernel 4.4.94,我們以這個版本進行拆解分析

4.x 的內核相對于3.x的內核在gadget 驅動上分解的更加完善,顯得目錄結構,層次分明,分工合理,更便于理解。

相對于3.x 的版本,4.4.94這個內核,將原來的、driver/usb/gadget目錄進行拆分。通用接口保持不變,比如compsite.c以及functions.c。將usb function driver 進行細分,分為legacy和functions。

有了這些背景,我們再看4.4.94這版內核,gadget驅動框架。

legacy:整個Gadget 設備驅動的入口。位于driver/usb/gadget/legacy下,里面給出了常用的usb類設備的驅動sample。其作用就是配置USB設備描述符信息,提供一個usb_composite_driver, 然后注冊到composite層。

functions:各種usb 子類設備功能驅動。位于driver/usb/gadget/functions,里面也給出了對應的sample。其作用是配置USB子類協議的接口描述以及其他子類協議,比如uvc協議,hid等。

注意:對于一個compsite 設備一個有一個或者多個function,對應的也就有多個functions driver

從這張圖上,有沒有發現,設備端驅動開發似乎越來越簡單了。沒錯,事實上,我們只需要根據legacy的源碼,添加對應的usb設備描述符信息,以及其他若干配置即可。

換言之,我們只需要關心 legacy 這一丟丟就行,對于functions這層會根據業務需要略微調整,不過整體變動不大。

usb 驅動框架之所以復雜,除了需要研究各種復雜的協議,還融合了各種驅動,對于初學者來說,理解起來有點困難。事實上,光是legacy這里也包含其他驅動,比如webcam里有大名鼎鼎的 v4l2 驅動框架。

所以當我學習USB驅動框架的時候,一定要抓大放小,【把握主要脈絡,忽略細節】。當我們把一個復雜的驅動逐一拆解的話,其實發現,就沒有那么可怕了。

2.3 usb compsite 設備構建

為了便于理解,我們來簡單了解一個usb compsite 設備的構建過程:

假設構建一個usb 復合設備,需要支持uac, uac, hid 三個功能其驅動框架。

首先,我們需要一個驅動入口 legacy,用來配置設備描述信息,支持的協議等

然后添加一個配置支持多種接口,這里支持uvc uac hid, 每個接口對應一個functions driver

最后我們把它注冊到compsite 層

對于functions driver 有個usb function driver list,在內核注冊function driver 時會自動添加到一個鏈表上。functions.c 就是用來管理所有的function drivers

3. USB gadget 驅動剖析3.1 相關數據結構

在梳理整個框架前我們先梳理一下幾個重要的數據結構,從下到上依次介紹:

usb_udc:

udc 使用,內嵌usb_gadget_driver 和 usb_gadget

struct usb_udc {

struct usb_gadget_driver *driver;

struct usb_gadget *gadget;

struct device dev;

struct list_head list;

bool vbus;

};

usb gadget:

usb 底層操作,包括udc,端點請求等。

struct usb_gadget {

struct work_struct work; /* 工作隊列 */

struct usb_udc *udc; /* udc */

/* readonly to gadget driver */

const struct usb_gadget_ops *ops; /*gadget 設備操作函數集*/

struct usb_ep *ep0; /* 控制端點,只對setup包響應*/

struct list_head ep_list; /* 將設備的所有端點連成鏈表,ep0不在其中 */

enum usb_device_speed speed; /* 高速、全速和低速 */

enum usb_device_speed max_speed; /* 最大速度 */

enum usb_device_state state;

const char *name;

struct device dev;

unsigned out_epnum; /* out ep number */

unsigned in_epnum; /* in ep number */

struct usb_otg_caps *otg_caps;

unsigned sg_supported:1;

unsigned is_otg:1;

unsigned is_a_peripheral:1;

unsigned b_hnp_enable:1;

unsigned a_hnp_support:1;

unsigned a_alt_hnp_support:1;

unsigned quirk_ep_out_aligned_size:1;

unsigned quirk_altset_not_supp:1;

unsigned quirk_stall_not_supp:1;

unsigned quirk_zlp_not_supp:1;

unsigned is_selfpowered:1;

unsigned deactivated:1;

unsigned connected:1;

};

usb_gadget_driver:

usb_gadget_driver - driver for usb ‘slave’ devices. usb 從設備驅動通用結構。

作用:提供一個通用的usb gadget driver 模板,向下注冊到udc,向上給functions driver提供bind 回調等。

關注:bind 回調、function 驅動名、setup 處理請求

struct usb_gadget_driver {

char *function; /* String describing the gadget‘s function */

enum usb_device_speed max_speed; /* Highest speed the driver handles */

int (*bind)(struct usb_gadget *gadget, /* the driver’s bind callback */

struct usb_gadget_driver *driver);

void (*unbind)(struct usb_gadget *);

int (*setup)(struct usb_gadget *, /* 處理ep0 request */

const struct usb_ctrlrequest *);

void (*disconnect)(struct usb_gadget *);

void (*suspend)(struct usb_gadget *);

void (*resume)(struct usb_gadget *);

void (*reset)(struct usb_gadget *);

/* FIXME support safe rmmod */

struct device_driver driver;

};

usb_composite_driver:

usb_composite_driver ,設備驅動的入口,用來管理設備配置信息,保存設備描述符。

重點:關注 bind 方法。

struct usb_composite_driver {

const char *name; /* 驅動名字 */

const struct usb_device_descriptor *dev ; /* 設備描述符 */

struct usb_gadget_strings **strings;

enum usb_device_speed max_speed;

unsigned needs_serial:1;

int (*bind)(struct usb_composite_dev *cdev); /* bind 方法 */

int (*unbind)(struct usb_composite_dev *);

void (*disconnect)(struct usb_composite_dev *);

/* global suspend hooks */

void (*suspend)(struct usb_composite_dev *);

void (*resume)(struct usb_composite_dev *);

struct usb_gadget_driver gadget_driver; /* usb gadget driver */

};

usb_composite_dev:

內嵌gadget對象,以及usb 設備的一些配置和請求,主要用于初始化。

struct usb_composite_dev {

struct usb_gadget *gadget;

struct usb_request *req;

struct usb_request *os_desc_req;

struct usb_configuration *config; /* usb 配置信息 */

/* OS String is a custom (yet popular) extension to the USB standard. */

u8 qw_sign[OS_STRING_QW_SIGN_LEN];

u8 b_vendor_code;

struct usb_configuration *os_desc_config;

unsigned int use_os_string:1;

/* private: */

/* internals */

unsigned int suspended:1;

struct usb_device_descriptor desc; /* 設備描述符 */

struct list_head configs;

struct list_head gstrings;

struct usb_composite_driver *driver; /* composite driver */

u8 next_string_id;

char *def_manufacturer;

/* the gadget driver won‘t enable the data pullup

* while the deactivation count is nonzero.

*/

unsigned deactivations;

/* the composite driver won’t complete the control transfer‘s

* data/status stages till delayed_status is zero.

*/

int delayed_status;

/* protects deactivations and delayed_status counts*/

spinlock_t lock;

unsigned setup_pending:1;

unsigned os_desc_pending:1;

};

3.2 驅動剖析

為一個通用的usb gadget 驅動剖析,框圖中只列出了兩個function,如果有多個function可以繼續添加。關于udc控制器部分,,沒有繼續畫下去,注意我們始終保持一個原則,【抓大放小】,把握重要的脈絡即可。

分層分塊

上下分層,左右分離的思想。

設備功能驅動

legacy 驅動入口

functions 驅動實現

Gadget 設備層:最重要的是compsite_bind 方法,承上啟下的作用。

udc 設備控制器層。usb 協議的真正處理。

驅動走向

向下:usb_composite_driver -》 usb_gadget_driver-》usb_udc

向上回調:udc_bind_to_driver -》 composite_bind -》 webcam_bind其中其主要作用的兩個結構就是usb_gadget_driver 和 usb_compsite_dev。前者向下注冊到udc list 里面,與udc控制器建立綁定關系;后者向上提供接口,供上層配置usb 設備的各種functions 和其他配置信息。

代碼分析

注冊usb_composite_driver

module_usb_composite_driver(webcam_driver)

module_driver(webcam_driver, usb_composite_probe,

usb_composite_unregister)

usb_composite_probe

usb_composite_probe(webcam_driver);

driver-》gadget_driver = composite_driver_template;

gadget_driver = &driver-》gadget_driver;

。。。

usb_gadget_probe_driver(composite_driver_template);

udc_bind_to_driver(udc, driver);

composite_driver_template-》bind(udc-》gadget, composite_driver_template);

usb_gadget_udc_start(udc);

composite_bind

composite_bind(udc-》gadget,composite_driver_template);

cdev-》gadget = gadget;

composite_dev_prepare(webcam_driver,cdev);

cdev-》req = usb_ep_alloc_request(gadget-》ep0, GFP_KERNEL); /* 申請端點0 */

cdev-》req-》complete = composite_setup_complete;

cdev-》driver = webcam_driver;

usb_ep_autoconfig_reset(gadget);

webcam_driver-》bind(cdev);

webcam_bind

webcam_bind(cdev);

usb_get_function_instance(“uvc”);

try_get_usb_function_instance(“uvc”);

uvc_alloc_inst();

usb_add_config();

webcam_config_bind();

usb_get_function();

usb_add_function();

others_config_bind();

其他

關于function driver 我們這里沒有詳細介紹,這個框圖只是一個通用的usb 設備驅動框架圖,對于具體的usb function driver 我們這里沒有做具體分析。

以f_uvc簡單舉例,詳細過程見內核源碼。

DECLARE_USB_FUNCTION_INIT(uvc, uvc_alloc_inst, uvc_alloc);

DECLARE_USB_FUNCTION_INIT(uvc, uvc_alloc_inst, uvc_alloc);

usb_function_register(&uvcusb_func);

list_for_each_entry(fd, &func_list, list)

list_add_tail();

DECLARE_USB_FUNCTION_INIT

一個通用的驅動模板,用來注冊usb_function_driver,并添加到func_list上。

#define DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc)

static struct usb_function_driver _name ## usb_func = {

.name = __stringify(_name),

.mod = THIS_MODULE,

.alloc_inst = _inst_alloc,

.alloc_func = _func_alloc,

};

MODULE_ALIAS(“usbfunc:”__stringify(_name));#define DECLARE_USB_FUNCTION_INIT(_name, _inst_alloc, _func_alloc)

DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc)

static int __init _name ## mod_init(void)

{

return usb_function_register(&_name ## usb_func);

}

static void __exit _name ## mod_exit(void)

{

usb_function_unregister(&_name ## usb_func);

}

module_init(_name ## mod_init);

module_exit(_name ## mod_exit)

4. 總結本文以拆解的方式,逐步剝離 usb 設備端驅動框架,帶領大家來重新認識usb 設備端驅動,同時給出了一個 compsite 設備的通用驅動框架模型,并從源碼層次分析整個驅動流程。

有關USB 或者 其他類似的高級驅動,筆者有個建議,在初學時一點更要【把握主次,忽略細節】。

比如一個復合的usb 設備可能包含,uvc,uac,hid,等等,視頻有uvc function驅動和v4l2驅動,uac也有相應的驅動,衍生展開會非常復雜。

所以當我們先掌握設備端驅動框架以及流程,等后面需要加入其他usb function 驅動再去研究其協議或者驅動,以及衍生驅動。

編輯:jq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • usb
    usb
    +關注

    關注

    60

    文章

    8150

    瀏覽量

    271146
  • Linux
    +關注

    關注

    87

    文章

    11469

    瀏覽量

    212921

原文標題:一文搞懂 USB 設備端驅動框架

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    KaihongOS筆記本電腦開發實戰第九節:全功能TypeC驅動框架適配

    《手把手教你做PC》系列直播課再度開播 !《 KaihongOS筆記本電腦開發實戰第九節九:全功能TypeC驅動框架適配》將于5月21日19:00開播 ↑掃碼入群,領課程講義資料包↑ 深開鴻資深
    發表于 05-19 18:29

    3014 USB驅動程序無法檢測到USB設備是怎么回事?

    我已將我的 USB 設備連接到運行 Windows 10 X64 的計算機,我已嘗試使用 1.2.3 和 1.3.0 版本的 cyapi 和 USB 驅動程序。 有時CYPRESS?
    發表于 05-09 06:11

    動量感知規劃的自動駕駛框架MomAD解析

    自動駕駛框架實現了感知與規劃的無縫集成,但通常依賴于一次性軌跡預測,這可能導致控制不穩定,并且對單頓感知中的遮擋問題較為敏感。為解決這一問題,我們提出了動量感知駕駛框架Momen
    的頭像 發表于 03-18 09:31 ?805次閱讀
    動量感知規劃的<b class='flag-5'>端</b>到<b class='flag-5'>端</b>自動駕駛<b class='flag-5'>框架</b>MomAD解析

    飛凌嵌入式ElfBoard ELF 1板卡-字符驅動之字符驅動框架描述

    字符驅動框架的核心組件包括以下部分: 文件操作函數 (file_operations):字符驅動框架通過 file_operations結構體定義了一組函數指針,用于處理
    發表于 03-14 09:45

    如何在USB視頻類(UVC)框架中使用EZ-USB?FX3實現圖像傳感器接口USB視頻類(UVC)

    電子發燒友網站提供《如何在USB視頻類(UVC)框架中使用EZ-USB?FX3實現圖像傳感器接口USB視頻類(UVC).pdf》資料免費下載
    發表于 02-28 17:36 ?2次下載

    USB串口驅動

    USB串口驅動
    發表于 02-10 13:49 ?3次下載

    艾體寶干貨 深度防御策略:構建USB安全防線的五大核心層次

    在應對USB相關威脅的征途上,IT專家日益傾向于采納深度防御策略,這一策略通過多層安全防護,為敏感數據和系統筑起堅不可摧的防線。根據《2024年USB連接設備安全態勢》研究報告,企業平
    的頭像 發表于 02-07 17:40 ?359次閱讀

    USB驅動問題:設備無法識別的全面指南!

    今天我把USB驅動問題,關于設備無法識別方面做一個全面指南供大家參考。連接USB無法識別模組設備,是不是
    的頭像 發表于 11-26 12:35 ?1121次閱讀
    <b class='flag-5'>USB</b><b class='flag-5'>驅動</b>問題:<b class='flag-5'>設備</b>無法識別的全面指南!

    基于RT-Thread的usb設備msc驅動測試

    msc驅動簡介:USBMSC(MassStorageClass)是一種USB設備類別,用于在計算機和外部存儲設備之間進行數據傳輸。USBMSC允許外部存儲
    的頭像 發表于 11-12 01:07 ?903次閱讀
    基于RT-Thread的<b class='flag-5'>usb</b><b class='flag-5'>設備</b>msc<b class='flag-5'>驅動</b>測試

    揭秘動態化跨框架在鴻蒙系統下的高性能解決方案

    作者:京東科技 胡大海 前言 動態化跨框架 (后文統稱“ 動態化” ) 是一個由京東金融大前端團隊全自主研發的,一份代碼,可以在 HarmonyOS、 iOS、Android、Web四運行的跨
    的頭像 發表于 10-08 13:46 ?1356次閱讀
    揭秘動態化跨<b class='flag-5'>端</b><b class='flag-5'>框架</b>在鴻蒙系統下的高性能解決方案

    MEMS 可編程振蕩器的卓越代表:SiT9121 系列(1 to 220 MHZ)深度剖析

    MEMS 可編程振蕩器的卓越代表:SiT9121 系列(1 to 220 MHZ)深度剖析
    的頭像 發表于 08-13 10:56 ?933次閱讀
    MEMS 可編程振蕩器的卓越代表:SiT9121 系列(1 to 220 MHZ)<b class='flag-5'>深度</b><b class='flag-5'>剖析</b>

    探索巔峰性能 | 迅為RK3588開發板深度剖析

    探索巔峰性能 | 迅為RK3588開發板深度剖析
    的頭像 發表于 08-12 14:07 ?1497次閱讀
    探索巔峰性能 | 迅為RK3588開發板<b class='flag-5'>深度</b><b class='flag-5'>剖析</b>

    NVIDIA推出全新深度學習框架fVDB

    在 SIGGRAPH 上推出的全新深度學習框架可用于打造自動駕駛汽車、氣候科學和智慧城市的 AI 就緒型虛擬表示。
    的頭像 發表于 08-01 14:31 ?1042次閱讀

    表面貼裝低相位噪音晶體振蕩器 DSO531SHH 深度剖析

    表面貼裝低相位噪音晶體振蕩器 DSO531SHH 深度剖析
    的頭像 發表于 07-26 14:12 ?644次閱讀
    表面貼裝低相位噪音晶體振蕩器 DSO531SHH <b class='flag-5'>深度</b><b class='flag-5'>剖析</b>

    TensorFlow與PyTorch深度學習框架的比較與選擇

    深度學習作為人工智能領域的一個重要分支,在過去十年中取得了顯著的進展。在構建和訓練深度學習模型的過程中,深度學習框架扮演著至關重要的角色。TensorFlow和PyTorch是目前最受
    的頭像 發表于 07-02 14:04 ?1551次閱讀
    主站蜘蛛池模板: 国产亚洲网站 | 夜夜狠狠| 色月| 日本黄色一区 | 特黄特黄一级高清免费大片 | 黄 色 成 年人网站 黄 色 成 年人在线 | 四虎亚洲国产成人久久精品 | 特级做a爰片毛片免费看 | 理论毛片 | 日韩美女三级 | 狠狠色丁香婷婷综合激情 | 欧美潘金莲一级风流片a级 欧美片欧美日韩国产综合片 | 欲香欲色天天综合和网 | 亚洲欧美国产视频 | 亚洲精品美女视频 | 高清一级毛片一本到免费观看 | 久久99精品久久久久久牛牛影视 | 欧美图片小说视频 | 天天操天天舔天天射 | 天天干天天干天天干 | 4hc44四虎www视频 | 中文字幕一区二区三区在线播放 | 免费人成在线观看视频播放 | 日本亚洲精品成人 | 黄色绿像一级片 | 亚洲人成网站色7799在线播放 | 日本加勒比在线精品视频 | 日本最新免费网站 | 性欧美视频 | 亚洲αv久久久噜噜噜噜噜 亚洲аv电影天堂网 | 丰满放荡岳乱妇91www | 伊人久久大香线蕉综合爱婷婷 | 国产成人精品怡红院 | 国产午夜免费视频 | 男女交性永久免费视频播放 | 一级特黄aaa大片免色 | 免费一级视频在线播放 | 亚洲欧美视频在线播放 | 国产精品综合色区在线观看 | 天天干天天舔天天操 | 国产色爽女小说免费看 |