USB 驱动开发 --- Gadget 驱动框架梳理(一)

本文由 Linux 内核文档翻译与总结而来,个人学习笔记仅供参考。

Gadget 框架

在 USB 协议交互过程中,角色定义:

  • the device driver is the master (or “client driver”)

    Linux 内核中称为 HCD(Host Controller Driver),负责与 USB 主机控制器硬件(通常是计算机的 USB 控制器)进行交互,管理 USB 数据传输。

  • the gadget driver is the slave (or “function driver”)

    Linux 内核中称为 UDC(USB Device Controller),管理连接到 USB 设备端的硬件,处理设备端的数据传输、设备枚举和其他 USB 设备相关的操作。

在这里插入图片描述

USB Controller Driver(UDC 驱动)

  • <linux/usb/gadget.h> 定义的API中,对底层 USB 控制器端点硬件抽象成 endpoint (能够接收 IN/OUT 数据流),通过回调与 Gadget Driver 交互。
  • Controller Driver 采用分时复用的方式进而可以对接任意数量的 Gadget Driver 交互;

Gadget Driver

对 USB Controller 的硬件抽象以支持 USB Function 开发,形式为各种调用接口。Gadget Driver 工作职责如下:

  • 响应 setup 请求, 由 ep0 负责的相关协议的应答也包含 calss 类别相关功能实现;
  • 响应 configuration、String 描述符;
  • (重新)设定 Configuration 和 Interface, 包含对端点的 使能与配置;
  • 报告 活动事件,例如:绑定到硬件、挂起/恢复、远程唤醒、断连等;
  • 管理 所有端点的 IN/OUT 收发;

Linux 社区并不鼓励通过这个方式添加如此多的专有驱动。

Upper Level

在 Gadget driver 之上可以连接到 Linux 内核的其他驱动或框架,通过绑定的形式与 Dadget 驱动完成数据的收发。可参考:

  • 用户空间,使用 gadgetfs 或 /dev 下相应节点操作;
  • 网络子系统,如:CDC Ethernet Model gadget 驱动;
  • 其他:Input 子系统(HID gadgets)、Sound 子系统(Aduio gadget)、文件系统(PTP gadget)等;

Additional Layers

可选的层,如:内核网络模块栈、用户应用、标准 POSIX 系统调用等。

Gadget API

在这里插入图片描述

数据结构

gadget driver 使用struct usb_gadget_driver包含自身信息之外还包含另外三种数据类型。理解这些数据类型和使用方法就算是掌握了API。

  • usb_gadget_driver dadget信息;

    //----> linux_5.10/include/linux/usb/gadget.hstruct usb_gadget_driver {...int			(*setup)(struct usb_gadget *, const struct usb_ctrlrequest *);        
    
  • usb_gadget,枚举信息;

    struct usb_gadget {...struct usb_udc			*udc;    
    
  • usb_ep,端点配置;

    struct usb_ep {...const struct usb_ep_ops	*ops;     ...struct usb_ep_caps	caps;        ...u8			address;const struct usb_endpoint_descriptor	*desc;    
    
  • usb_request,数据收发;

    struct usb_request {void			*buf;unsigned		length;
    
  • linux/usb/ch9.h,Gadget 驱动使用的在USB ch9 中定义的公共的 USB 数据结构,不分 Host 与 Device。

使用中关注:

  • 规定使用端点0作为作为各种硬件限定信息的配置与管理,如:发送类型、地址、包大小、缓存和其他能力集;
  • USB message 臃肿(chunky),一个IO请求需要由一个或多个”数据包“组成且边界可被驱动感知;
  • USB 协议更像是异步通信协议(如:HDLC,每帧有 N 个 Byte,多个地址,Host 第一站,Device 其次)超过异步通信协议(如:TTY,每帧8个 Bit,无奇偶检验位,无停止位);
  • USB 数据包是有边界的,如: 一个 USB IN 包数据是 two-byte 一个单元,因此不能将两个单字节直接写入一个单元;

对象与方法

Gadget 设备
核心
  • <linux/usb/gadget.h>, 定义了 Gadget 驱动核心对象与方法;
可选

核心 API 已足够支撑 Gadget 驱动开发,但还另外提供了一些可选工具用以简化常用任务。

  • drivers/usb/gadget/usbstring.c
  • drivers/usb/gadget/config.c
composite 设备

核心 API 已足够开发 Composite 设备(一个 configuration 中有多个功能)和 多功能设备驱动的开发,composite 复合框架将简化这些设备驱动的开发。

框架

composite 设备框架定义了一个设备结构体 struct usb_composite_driver ,其内可关联多个struct usb_configuration 实例。每个 configuration 又包含多个 struct usb_function 定义。在 function 中定义了用户可感知的设备角色,如:Network Link、mass storage device,也可包含管理功能,如:Device Firmware Upgrade。

  • include/linux/usb/composite.h,数据结构定义;
  • drivers/usb/gadget/composite.c,框架实现;
功能

当前只要是使用 DECLARE_USB_FUNCTION_INIT声明的 Gadget 驱动就都是 composite设备,可对应查看源码 drivers/usb/gadget/function/f_xxx.c

Legacy 设备

源码目录 drivers/usb/gadget/legacy/xxx.c

活动事件

Gadget 驱动执行I/O请求时时不用关注硬件细节要求,而当驱动执行 setup/configuration 时就需要关注流程:

  1. 注册 UDC 驱动(USB Device Controller,作为**设备(Slave)**角色的 USB 控制器驱动);

    当前作为设备插入 Host 后会处于 attached 初始化状态( USB ch9 中定义)。此时既无功率消耗也法被使用(还不支持枚举)。

    因为当前数据线上的上拉未使能,所以即使 VBus 正常供电,Host 也无法感知到当前设备的存在(Host 通过设备是否上拉数据线探测设备)。

  2. 注册 Gadget 驱动;

    这些更高层级的 Fuction 驱动将调用 bind() 绑定到具体的 gadget 设备( struct usb_gadget 对象) 。有时这些 Function会在识别到 VBUS 后使能数据线上拉。

  3. 硬件驱动开始枚举;

    此时设备可以接受 USB powerset_address 请求,余下步骤由 gadget driver 接管。如果 dadget driver 在枚举前还未加载,忽略其后步骤直接跳转至步骤 7,执行 unbind()

  4. 实现 Gadget 驱动中 setup()方法;

    setup()方法将返回当前设备的:描述符、硬件接口和能力集等信息。如果硬件允许,甚至可以执行更复杂的设定和配置。

  5. 实现 set_configuration 请求的应答;

    Gadget 驱动需要在setup()方法中实现对主机set_configuration请求的应答(枚举的最后一步),使用所有在 Configuration 中使用的端点 和 默认 settings 中的接口;

  6. 实现数据收发;

  7. 实现 Gadget 驱动中 unbind()方法;

    当 Gadget 驱动卸载时,同时卸载 UDC 驱动;

注:

  1. 在设备连接到Hub后会导致Hub的D+或D-电平变化,Hub根据变化的引脚分辨接进来的是全速设备还是低速设备:

    • 低速设备内部的D-有1.5K的上拉电阻;

    • 全速设备内部的D+有1.5K的上拉电阻;

    • 高速设备一开始也是作为全速设备被识别的,高速模式时,D+的上拉电阻是断开的;

UDC 驱动

UDC(USB Device Controller),即USB从机(设备)控制器,内核文档也称为 Peripheral Controller Drivers。内核中第一个支持的硬件的是 NetChip 2280 控制器(基于PCI 的支持 USB 2.0 调整模式)。其他的控制器基于 gadget 框架开发,见驱动源码文件: linux_5.10/drivers/usb/gadget/udc/xxx_udc.c

虚拟UDC

方便硬件控制器未准备好(缺失或功能异常)时的软件调试,内核实例了一个虚拟的 UDC 驱动。它像 net2280、pxa25x 和 sa11x0 等硬件控制器一样指代多个端点和速率模式,也能够模拟 控制传输、批量传输 和 中断传输。这也就方便了开发支持在

Gadget 驱动

gadget_Zero驱动(主要用于UDC功能验证)之外,内核还有示例了多个常用的 gadget 驱动。

CDC 类

CDC(Communications Device Class)是太网模型的两个强制选项之一,也是电缆调制解调器交互操作性的标准之一。在USB主机看来,使用此代码的gadget 就像是以个太网适配器。

CDC类实现源码文件位于:drivers/usb/gadget/function/f_xxx.c,其下包含:

  • USB CDC serial 类: ACM;
  • USB CDC Ethernet 类:ECM、EEM、RNDIS,简单辨析如下:
    请添加图片描述

注:暂且把 微软的 RNDIS 驱动也纳入CDC Ethernet 类,因为 RNDIS 更适合运行在轻量化的 USB 控制器设备中。RNDIS 为设备接入 Windows 系统使用提供了便捷。

MSC 类

MSC(Mass Storage class)指常用的存储设备,如:U盘、CD-ROM等。大容量存储类设备驱动使用一种不同于 MS-Windows 和 MacOS 的交互方式:

  • USB 设备端,驱动使用一个具体的文件或块设备作为其后端存储介质;
  • USB 主机端,主机遵循 BBB, CB 或 CBI 版本的 MSC 类规格要求使用 SCSI 命令访问后端不认介质;

MSC 类实现源码文件包含:

  • drivers/usb/gadget/function/f_mass_storage.c,被主机视为 磁盘、CD-ROM 等存储设备访问;
  • drivers/usb/gadget/function/f_loopback.c,主要用于应用回环测试;

OTG 功能

USB OTG(USB On-The-GO)指代可以进制双角色切换机制的 USB 控制器:

  • 作为 Host时,使用标准 Linux-USB 主机侧驱动栈;
  • 作为 Device时,使用 Gadget 框架;

见下图,可以看到:Host Controllere、 Device Controller、OTG Bus Monitor 三个重要组成
请添加图片描述

在不同角色下,系统都应尽量复用顶层已申请的、硬件无关的顶层控制器驱动(Host, usb_bus;Device, usb_gadget)内存池;保证功能正常的最小修改;保证对非 OTG 产品的影响。可以抽象出以下几个控制特性:

  • is_otg,Gadget 驱动检查这个标记以确认是否需要在其 configurations 中添加 OTG 描述符;
  • b_hnp_enable, Gadget 驱动如果需要支持两种新的 OTG 协议:
    • HNP, 通过用户接口(如:两个 LED 灯)指示当前设备被 Host 挂起;
    • SRP, 可由用户发起(就像远程唤醒),如按下相关按键;
  • 白名单,如同主机侧,驱动必须支持 OTG 目标外设名单,用以声明支持的 OTG 控制器,即 OTG 白名单。修改文件 otg_whitelist.h

需知

  1. 每个 USB Function 都会在 config_groups 中定义期望用户配置的内容,可配置参考对应 Function 的实现文件:drivers/usb/gadget/f_*.c
  2. 主要阅读 USB 规范章节9 和 内核 gadget.rst 文档,以免忽略掉关键信息,如:端点自动配置,否则需要同时参考头文件与示例源码(如 Gadget Zere);

参考

  • 内核文档 linux_5.10/Documentation/usb/gadget_configfs.rst
  • 11_Gadget驱动程序框架

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/3635.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python实现pdf转word和excel

一、引言   在办公中&#xff0c;我们经常遇收到pdf文件格式&#xff0c;因为pdf格式文件不易修改&#xff0c;当我们需要编辑这些pdf文件时&#xff0c;经常需要开通会员或收费功能才能使用编辑功能。今天&#xff0c;我要和大家分享的&#xff0c;是如何使用python编程实现…

Jenkins-基于Role的鉴权机制

jenkins自带了一些全局性的安全配置。 但无法通过job等相对细粒度的来控制使用者的权限。但它可以借助相关的插件实现细颗粒的权限控制。 插件&#xff1a; Role-based Authorization Strategy 需要在configure global security中配置授权策略如下&#xff1a; 保存后&#x…

差分(前缀和的逆运算)

作用&#xff1a; 在 [ l ,r ] 数组中&#xff0c;对全部数字c 思路 原数组a 构造差分数组b使得a[i]b1b2b3...bi; a数组是b数组的前缀和,b1b2b3...bnan b[i] a[i]-a[i-1]; 在d21,那在前缀和时&#xff0c;这些a都1 在数组中&#xff0c;要l~r这段数c 在l处c后&#xff0c…

【转】厚植根基,同启新程!一文回顾 2024 OpenHarmony 社区年度工作会议精彩瞬间

在数字化浪潮奔腾不息的今天&#xff0c;开源技术已成为推动科技创新与产业发展的强大引擎。2025年1月10日-11日&#xff0c;OpenAtom OpenHarmony&#xff08;开放原子开源鸿蒙&#xff0c;以下简称“OpenHarmony”或“开源鸿蒙”&#xff09;社区2024年度工作会议于深圳盛大启…

flutter 常用UI组件

文章目录 1. Toast 文本提示框oktoastbot_toast2. loading 加载窗flutter_easyloading3. 对话框gex dialog4.下拉刷新pull_to_refresh5. pop 窗custom_pop_up_menu6. pin code 密码框pinput7. 二维码qr_flutter8. swiper 滚动组件carousel_sliderflutter_swiper_view9. Badge 角…

重学SpringBoot3-Spring Retry实践

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞??收藏评论 重学SpringBoot3-Spring Retry实践 1. 简介2. 环境准备3. 使用方式 3.1 注解方式 基础使用自定义重试策略失败恢复机制重试和失败恢复效果注意事项 3.2 编程式使用3.3 监听重试过程 监…

爬虫第二篇

太聪明了怎么办&#xff1f;那就&#xff0c;给脑子灌点水&#xff01;&#xff01; 本篇文章我们来简单讲一下如何爬取mv,也就是歌曲视频&#xff0c;那么我们进入正题。 由于上次拿网易云开了刀&#xff0c;那么这次我们拿酷狗开刀。 还是进入上次讲过的页面 注意&#xff…

【ArcGIS微课1000例】0140:总览(鹰眼)、放大镜、查看器的用法

文章目录 一、总览工具二、放大镜工具三、查看器工具ArcGIS中提供了三种局部查看的工具: 总览(鹰眼)、放大镜、查看器,如下图所示,本文讲述这三种工具的使用方法。 一、总览工具 为了便于效果查看与比对,本实验采用全球影像数据(位于配套实验数据包中的0140.rar中),加…

快手极速版如何查找ip归属地?怎么关掉

在数字化时代&#xff0c;个人隐私的保护成为了广大用户关注的焦点。快手极速版作为一款备受欢迎的短视频应用&#xff0c;其IP归属地的显示与关闭功能自然也成了用户热议的话题。本文将详细介绍如何在快手极速版中查找IP归属地以及如何关闭IP属地显示&#xff0c;帮助用户更好…

MQ消息队列

1、消息队列特点 2、RabbitMQ

Web自动化:Cypress 测试框架概述

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Cypress 测试框架概述 1.1 Cypress 默认文件结构 在Cypress安装完成后&#xff0c;其生成的默认文件目录如下所示&#xff1a; 1.1.1 Fixtures Fixture又称之为测…

基于SSM汽车美容管家【提供源码+答辩PPT+文档+项目部署】(高质量源码,可定制,提供文档,免费部署到本地)

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

tlias部门管理-新增部门-接口开发

需求 点击 "新增部门" 的按钮之后&#xff0c;弹出新增部门表单&#xff0c;填写部门名称之后&#xff0c;点击确定之后&#xff0c;保存部门数据。 了解了需求之后&#xff0c;我们再看看接口文档中&#xff0c;关于新增部门的接口的描述&#xff0c;然后根据接口…

蓝桥杯 Python 组知识点容斥原理

容斥原理 这张图初中或者高中数学课应该画过 也就是通过这个简单的例子引出容斥原理的公式 这张图的面积&#xff1a;s1 s3 s7 - 2 * s2 - 2 * s4 - 2 * s6 3 * s5 通过此引导出容斥原理公式 那么下面来一起看看题目 题目描述 给定 n,m 请求出所有 n 位十进制整数中有多…

本地仓库管理之当前分支内的操作

以刚搭建好的git仓库为例&#xff0c;刚搭建完的仓库只有master分支&#xff0c;使用git branch查看当前的分支情况。 elfubuntu:~/work/example/hello$ git branch *所在分支为当前分支&#xff0c;即master分支 当前分支进行源码修改时简单流程图如下&#xff1a; 在当前分…

Spring Web MVC综合案例

承接上篇文章——Spring Web MVC探秘&#xff0c;在了解Spring Web MVC背后的工作机制之后&#xff0c;我们接下来通过三个实战项目&#xff0c;来进一步巩固一下前面的知识。 一、计算器 效果展示&#xff1a;访问路径&#xff1a;http://127.0.0.1:8080/calc.html 前端代码&a…

Linux之文件系统前世今生(一)

Linux在线1 Linux在线2 一、 基本概念 1.1 块&#xff08;Block&#xff09; 在计算机存储之图解机械硬盘这篇文章中我们提到过&#xff0c;磁盘读写的最小单位是扇区&#xff0c;也就是 512 Byte&#xff1b;很明显&#xff0c;每次读写的效率非常低。 为了提高IO效率&…

SpringMVC 实战指南:打造高效 Web 应用的秘籍

第一章&#xff1a;三层架构和MVC 三层架构&#xff1a; 开发服务器端&#xff0c;一般基于两种形式&#xff0c;一种 C/S 架构程序&#xff0c;一种 B/S 架构程序使用 Java 语言基本上都是开发 B/S 架构的程序&#xff0c;B/S 架构又分成了三层架构三层架构&#xff1a; 表现…

MySQL、HBase、ES的特点和区别

MySQL&#xff1a;关系型数据库&#xff0c;主要面向OLTP&#xff0c;支持事务&#xff0c;支持二级索引&#xff0c;支持sql&#xff0c;支持主从、Group Replication架构模型&#xff08;本文全部以Innodb为例&#xff0c;不涉及别的存储引擎&#xff09;。 HBase&#xff1…

Formality:参考设计/实现设计以及顶层设计

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482​​​ Formality存在两个重要的概念&#xff1a;参考设计/实现设计和顶层设计&#xff0c;本文就将对此进行详细阐述。参考设计/实现设计是中两个重要的全局概念&am…