91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深度剖析USB設(shè)備端驅(qū)動框架

strongerHuang ? 來源:漫談嵌入式 ? 作者:漫談嵌入式 ? 2021-06-07 14:12 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

hello 大家好,今天帶領(lǐng)大家學(xué)習(xí)一下USB設(shè)備端驅(qū)動

內(nèi)核版本:4.4.94

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

Linux kernel 中早已集成了較為完善的USB協(xié)議棧,由于其規(guī)模龐大,包含多個類別的設(shè)備驅(qū)動,所以Linux系統(tǒng)中的USB協(xié)議棧也被稱為USB子系統(tǒng)。

1.1 主機(jī)端

主機(jī)端,簡化抽象三層:

各種類設(shè)備驅(qū)動:mass sotrage, CDC, HID等

USB 設(shè)備驅(qū)動:USB 核心處理

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

1.2 設(shè)備端

設(shè)備端,也抽象為三層:

設(shè)備功能驅(qū)動:mass sotage , CDC, HID 等,對應(yīng)主機(jī)端的類設(shè)備驅(qū)動

Gadget 設(shè)備驅(qū)動:中間層,向下直接和UDC通信,建立鏈接;向上提供通用接口,屏蔽USB請求以及傳輸細(xì)節(jié)。

設(shè)備控制器驅(qū)動:UDC驅(qū)動,直接處理USB設(shè)備控制器。

2. USB 設(shè)備驅(qū)動2.1 gadget 驅(qū)動框架拆解1

我們將USB 設(shè)備端驅(qū)動拆解一下。

上文提到,Gadget 設(shè)備層起著至關(guān)重要的作用。為上層提供通用的驅(qū)動框架,與下層UDC通過Gadget Interface 建立聯(lián)系。

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

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

2.2 gadget 驅(qū)動框架拆解2

內(nèi)核版本:Linux Kernel 4.4.94,我們以這個版本進(jìn)行拆解分析

4.x 的內(nèi)核相對于3.x的內(nèi)核在gadget 驅(qū)動上分解的更加完善,顯得目錄結(jié)構(gòu),層次分明,分工合理,更便于理解。

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

有了這些背景,我們再看4.4.94這版內(nèi)核,gadget驅(qū)動框架。

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

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

注意:對于一個compsite 設(shè)備一個有一個或者多個function,對應(yīng)的也就有多個functions driver

從這張圖上,有沒有發(fā)現(xiàn),設(shè)備端驅(qū)動開發(fā)似乎越來越簡單了。沒錯,事實(shí)上,我們只需要根據(jù)legacy的源碼,添加對應(yīng)的usb設(shè)備描述符信息,以及其他若干配置即可。

換言之,我們只需要關(guān)心 legacy 這一丟丟就行,對于functions這層會根據(jù)業(yè)務(wù)需要略微調(diào)整,不過整體變動不大。

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

所以當(dāng)我學(xué)習(xí)USB驅(qū)動框架的時候,一定要抓大放小,【把握主要脈絡(luò),忽略細(xì)節(jié)】。當(dāng)我們把一個復(fù)雜的驅(qū)動逐一拆解的話,其實(shí)發(fā)現(xiàn),就沒有那么可怕了。

2.3 usb compsite 設(shè)備構(gòu)建

為了便于理解,我們來簡單了解一個usb compsite 設(shè)備的構(gòu)建過程:

假設(shè)構(gòu)建一個usb 復(fù)合設(shè)備,需要支持uac, uac, hid 三個功能其驅(qū)動框架。

首先,我們需要一個驅(qū)動入口 legacy,用來配置設(shè)備描述信息,支持的協(xié)議等

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

最后我們把它注冊到compsite 層

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

3. USB gadget 驅(qū)動剖析3.1 相關(guān)數(shù)據(jù)結(jié)構(gòu)

在梳理整個框架前我們先梳理一下幾個重要的數(shù)據(jù)結(jié)構(gòu),從下到上依次介紹:

usb_udc:

udc 使用,內(nèi)嵌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,端點(diǎn)請求等。

struct usb_gadget {

struct work_struct work; /* 工作隊(duì)列 */

struct usb_udc *udc; /* udc */

/* readonly to gadget driver */

const struct usb_gadget_ops *ops; /*gadget 設(shè)備操作函數(shù)集*/

struct usb_ep *ep0; /* 控制端點(diǎn),只對setup包響應(yīng)*/

struct list_head ep_list; /* 將設(shè)備的所有端點(diǎn)連成鏈表,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 從設(shè)備驅(qū)動通用結(jié)構(gòu)。

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

關(guān)注:bind 回調(diào)、function 驅(qū)動名、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 ,設(shè)備驅(qū)動的入口,用來管理設(shè)備配置信息,保存設(shè)備描述符。

重點(diǎn):關(guān)注 bind 方法。

struct usb_composite_driver {

const char *name; /* 驅(qū)動名字 */

const struct usb_device_descriptor *dev ; /* 設(shè)備描述符 */

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:

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

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; /* 設(shè)備描述符 */

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 驅(qū)動剖析

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

分層分塊

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

設(shè)備功能驅(qū)動

legacy 驅(qū)動入口

functions 驅(qū)動實(shí)現(xiàn)

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

udc 設(shè)備控制器層。usb 協(xié)議的真正處理。

驅(qū)動走向

向下:usb_composite_driver -》 usb_gadget_driver-》usb_udc

向上回調(diào):udc_bind_to_driver -》 composite_bind -》 webcam_bind其中其主要作用的兩個結(jié)構(gòu)就是usb_gadget_driver 和 usb_compsite_dev。前者向下注冊到udc list 里面,與udc控制器建立綁定關(guān)系;后者向上提供接口,供上層配置usb 設(shè)備的各種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); /* 申請端點(diǎn)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();

其他

關(guān)于function driver 我們這里沒有詳細(xì)介紹,這個框圖只是一個通用的usb 設(shè)備驅(qū)動框架圖,對于具體的usb function driver 我們這里沒有做具體分析。

以f_uvc簡單舉例,詳細(xì)過程見內(nèi)核源碼。

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

一個通用的驅(qū)動模板,用來注冊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. 總結(jié)本文以拆解的方式,逐步剝離 usb 設(shè)備端驅(qū)動框架,帶領(lǐng)大家來重新認(rèn)識usb 設(shè)備端驅(qū)動,同時給出了一個 compsite 設(shè)備的通用驅(qū)動框架模型,并從源碼層次分析整個驅(qū)動流程。

有關(guān)USB 或者 其他類似的高級驅(qū)動,筆者有個建議,在初學(xué)時一點(diǎn)更要【把握主次,忽略細(xì)節(jié)】。

比如一個復(fù)合的usb 設(shè)備可能包含,uvc,uac,hid,等等,視頻有uvc function驅(qū)動和v4l2驅(qū)動,uac也有相應(yīng)的驅(qū)動,衍生展開會非常復(fù)雜。

所以當(dāng)我們先掌握設(shè)備端驅(qū)動框架以及流程,等后面需要加入其他usb function 驅(qū)動再去研究其協(xié)議或者驅(qū)動,以及衍生驅(qū)動。

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • usb
    usb
    +關(guān)注

    關(guān)注

    60

    文章

    8438

    瀏覽量

    284454
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11758

    瀏覽量

    219009

原文標(biāo)題:一文搞懂 USB 設(shè)備端驅(qū)動框架

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    汽車級 USB-C 專用充電端口利器:MAX20459 深度剖析

    汽車級 USB-C 專用充電端口利器:MAX20459 深度剖析 在汽車電子領(lǐng)域,USB 充電端口的需求日益增長,對充電效率、兼容性和安全性的要求也越來越高。MAX20459 作為一款
    的頭像 發(fā)表于 03-05 14:20 ?114次閱讀

    串口協(xié)議的深度剖析

    串口通信協(xié)議作為電子設(shè)備間數(shù)據(jù)交互的基礎(chǔ)技術(shù),自20世紀(jì)60年代誕生以來,始終在工業(yè)控制、嵌入式系統(tǒng)和物聯(lián)網(wǎng)等領(lǐng)域扮演著核心角色。本文將從技術(shù)原理、協(xié)議架構(gòu)、應(yīng)用場景及未來演進(jìn)四個維度,對串口協(xié)議展開深度剖析。
    的頭像 發(fā)表于 03-02 17:32 ?1019次閱讀

    軟通動力基于OpenClaw開源框架深度自研側(cè)智能體平臺

    隨著人工智能加速從云端下沉至終端、從被動交互邁向主動執(zhí)行,側(cè)智能體正成為定義智能硬件體驗(yàn)的核心引擎。軟通動力基于OpenClaw開源框架深度自研側(cè)智能體平臺,以輕量化推理、本地自主
    的頭像 發(fā)表于 02-27 11:48 ?475次閱讀

    深度剖析TPS61158:高效WLED驅(qū)動芯片的卓越之選

    深度剖析TPS61158:高效WLED驅(qū)動芯片的卓越之選 在電子設(shè)備飛速發(fā)展的今天,小型化、高效能的需求日益凸顯。對于WLED(白光發(fā)光二極管)驅(qū)動
    的頭像 發(fā)表于 02-27 10:55 ?120次閱讀

    深度剖析MAX77751:3.15A USB - C單節(jié)Li+電池自主充電器

    深度剖析MAX77751:3.15A USB - C單節(jié)Li+電池自主充電器 一、引言 在當(dāng)今的電子設(shè)備中,電池充電管理是一個至關(guān)重要的環(huán)節(jié)。隨著U
    的頭像 發(fā)表于 02-12 16:05 ?1355次閱讀

    深度剖析 TPS2511:USB 充電端口控制與電流限制的理想之選

    深度剖析 TPS2511:USB 充電端口控制與電流限制的理想之選 一、引言 在當(dāng)今電子設(shè)備高度普及的時代,USB 充電技術(shù)變得至關(guān)重要。從
    的頭像 發(fā)表于 02-09 10:50 ?109次閱讀

    汽車高速USB 2.0保護(hù)神器——MAX20046深度剖析

    汽車高速USB 2.0保護(hù)神器——MAX20046深度剖析 在汽車電子領(lǐng)域,USB接口的使用越來越廣泛,從汽車收音機(jī)、導(dǎo)航系統(tǒng)到各種連接設(shè)備
    的頭像 發(fā)表于 02-08 10:25 ?172次閱讀

    德州儀器PCM2704/5/6/7:單芯片USB立體聲音頻DAC的深度剖析

    、PCM2705、PCM2706和PCM2707系列單芯片USB立體聲音頻DAC以其卓越的特性和廣泛的應(yīng)用場景,成為了眾多電子工程師的首選。今天我們就來詳細(xì)剖析一下這些芯片,看看它們究竟有何過人之處。 文件下載: pcm2705.pdf 一、特性概覽 (一)集成
    的頭像 發(fā)表于 02-03 16:00 ?606次閱讀

    LT3519:高性能LED驅(qū)動芯片的深度剖析

    LT3519/LT3519 - 1/LT3519 - 2:高性能LED驅(qū)動芯片的深度剖析 在電子設(shè)計領(lǐng)域,LED驅(qū)動芯片的性能直接影響著LED照明系統(tǒng)的穩(wěn)定性和效率。LT3519/LT
    的頭像 發(fā)表于 02-02 11:30 ?193次閱讀

    DRV8313:高性能電機(jī)驅(qū)動芯片的深度剖析

    DRV8313:高性能電機(jī)驅(qū)動芯片的深度剖析 在電機(jī)驅(qū)動領(lǐng)域,找到一款性能卓越、功能豐富且適配性強(qiáng)的芯片并非易事。今天,我們就來深入探討德州儀器(TI)的DRV8313,一款專為電機(jī)
    的頭像 發(fā)表于 01-09 16:45 ?889次閱讀

    深度剖析TSU8111:一款集成充電器的USB 2.0高速開關(guān)芯片

    深度剖析TSU8111:一款集成充電器的USB 2.0高速開關(guān)芯片 在電子設(shè)備的設(shè)計中,USB接口的應(yīng)用無處不在,而如何高效、穩(wěn)定地實(shí)現(xiàn)
    的頭像 發(fā)表于 12-23 15:15 ?345次閱讀

    深度剖析TS3USB3000:一款高性能的USB與MHL開關(guān)芯片

    深度剖析TS3USB3000:一款高性能的USB與MHL開關(guān)芯片 在電子設(shè)備的設(shè)計中,對于信號切換和傳輸?shù)男枨笕找嬖鲩L,尤其是在處理高速信號
    的頭像 發(fā)表于 12-23 14:25 ?350次閱讀

    TUSB551:1.8-V USB 3.0單通道均衡重驅(qū)動器的深度剖析

    TUSB551:1.8-V USB 3.0單通道均衡重驅(qū)動器的深度剖析 在電子設(shè)備飛速發(fā)展的今天,USB
    的頭像 發(fā)表于 12-23 09:35 ?478次閱讀

    電子工程師必看:TUSB501-Q1 USB 3.0轉(zhuǎn)接驅(qū)動深度剖析

    電子工程師必看:TUSB501-Q1 USB 3.0轉(zhuǎn)接驅(qū)動深度剖析 在電子設(shè)備高速發(fā)展的今天,USB
    的頭像 發(fā)表于 12-19 11:05 ?330次閱讀

    EZ - PD? CCG7SCF:單端口 USB Type - C 電源解決方案深度剖析

    EZ - PD? CCG7SCF:單端口 USB Type - C 電源解決方案深度剖析 在當(dāng)今電子設(shè)備快速發(fā)展的時代,USB Type -
    的頭像 發(fā)表于 12-18 15:05 ?407次閱讀