[图解linux][USB子系统系列]:图解USB设备驱动结构

[图解linux][USB子系统系列]:图解USB设备驱动结构

文章目录
1、Linux USB 子系统2、Linux USB 设备驱动结构2.1、UDC 设备控制器层2.2、Gadget设备层2.3、Gadget 功能驱动层

1、Linux USB 子系统

Linux系统内核中早已集成了较为完善的USB协议栈,由于其规模庞大,包含多个类别的设备驱动,所以Linux系统中的USB协议栈也被称为USB子系统。
[图解linux][USB子系统系列]:图解USB设备驱动结构

2、Linux USB 设备驱动结构

Gadget驱动指的是运行在设备中的固件,也就是USB设备驱动模型。
Linux Gadget 三个软件层:

    USB设备控制器层Gadget设备层USB功能驱动层[图解linux][USB子系统系列]:图解USB设备驱动结构

完整的 USB设备端软件是由这三层软件层融合在一起来实现 USB 设备的功能,下面我们看下他们是如何串起来的。
USB 设备层定义了并初始化了一个结构体 struct usb_composite_driver。这个结构体中定义了一些函数指针,并且在 USB 设备层实现了这些函数。这些函数是融合 USB 设备层与上层软件功能驱动层的关键函数。数据结构只是完成了软件架构的构建, 如果需要融合还需 要函数的调用,在这里这个函数就是usb_composite_register。这个函数在 USB 设备层中实现,提供给上层软件功能驱动层来调用。当功能软件层调用这个函数成功后,USB 设备层与上层软件就融合在了一起,这个函数调用还触发了 USB 设备层调用 usb_gadget_register_driver,从而完成USB 设备层与下层软件的融合。这样三层软件都融合在了一起,组成了完整的 USB 设备端软件。
[图解linux][USB子系统系列]:图解USB设备驱动结构

2.1、UDC 设备控制器层

UDC设备控制器层与硬件相关,由于UCD的设计和实现不仅限于一个家厂商,不同厂商的UCD IP核会有特性上的差异,所以UDC驱动也分为两部分,上层是UDC Core,它是对各类UDC IP的功能的抽象,为Gadget设备层提供统一接口,重要的数据结构

static struct udc {
struct usb_gadget gadget;
struct usb_gadget_driver *driver;
struct device dev;
struct list_head list;
};

udc意为USB设备控制器( USB Device Controller),其结构中包含了usb_gadgetusb_gadget_driver两个重要的数据结构:

usb_gadget结构体代表一个从机设备驱动,它是对控制器的抽象,向上层提供控制器的I/O相关和非I/O相关的两类服务,分别对应其结构成员中的usb_gadget_opsusb_ep数据结构;usb_gadget_driver结构是从gadget设备驱动层传递下来的,是gadget设备驱动层的核心数据结构,最终也会挂载在udc结构中。 UDC层的一项基本任务是向上层提供usb_gadget_probe_driver()接口函数,并实现为usb_gadget服务的相关函数,这些函数将通过usb_gadget结构回传到gadget设备层。另外, UDC层还需要提供gadget设备的中断服务程序,在USB协议中,传输一般都是由主机发起的, gadget设备驱动只有通过中断来判断是否有传输请求,中断处理程序工作在整个USB gadget驱动架构的第一现场。
[图解linux][USB子系统系列]:图解USB设备驱动结构

由于USB设备控制器一般是以IP核授权的方式集成在SOC中,所以,在Linux系统的UDC IP核心驱动会以平台设备的方式注册到系统中,在驱动的探测函数中完成控制器时钟及相关数据结构初始化,获得控制器的物理地址并向内核申请中断,开辟udc结构体所需资源并初始化usb_gadget数据结构,最后通过调用UDC核心提供的usb_add_gadget_udc函数来注册gadget服务。

2.2、Gadget设备层

Gadget设备层属于硬件无关层,相关代码在kernel/drivers/usb/gadget/composite.c文件中实现, Gadget设备层把Gadget功能驱动与硬件相关的UDC层隔离开来,并向Gadget功能驱动提供统一的UDC应用接口,Gadget功能驱动着重于USB功能的子协议实现, UDC层则重点关注自身IP的物理特性和工作机制。若无Gadget设备层,每个功能驱动都要实现自己的Gadget设备,如此将导致严重的代码重用。

Gadget设备层与UDC设备控制器层的交互是通过两个结构体和一个函数进行的,第一个结构体usb_gadgetDCD设备控制器驱动中已经初始化,另一个结构体usb_gadget_driver会在本层中初始化,然后通过usb_gadget_probe_driver()传入到DCD设备控制器层赋值到udc驱动中,将Gadget设备驱动与DCD设备控制器驱动相互关联起来。

另外, DCD设备控制器驱动会调用的usb_gadget_driver中的bind()函数,把usb_gadget数据结构及其服务回传到Gadget设备层; usb_gadget_driver中的setup()函数指针是Gadget设备驱动的中断服务程序的重要组成部分,设备在枚举阶段的交互都要跳转到这里, setup ()函数指针会指向composite_setup()函数,在其中在分类处理标准主机请求和自定义主机请求。

struct usb_gadget_driver {
(*bind)(); (*unbind)();
(*setup)(); (*disconnect)();
(*suspend)(); (*resume)();
};

Gadget设备层与Gadget功能驱动通过数据结构usb_composite_dev以及函数usb_composite_probe()进行交互:

struct usb_composite_dev {
usb_gadget *gadget;
usb_request *req;
usb_configuration *config;
usb_composite_driver *driver;
};

[图解linux][USB子系统系列]:图解USB设备驱动结构

usb_composite_dev结构代表一个USB gadget设备, 该结构中包含设备描述符和配置信息,其中usb_gadget结构的实例是从UDC层回传而来,回传机制为UDC层调用usb_gadget_driverbind()函数指针,该函数指针指向定义在Gadget设备层的composite_bind()函数,该函数中首先定义了usb_composite_dev结构的实例,再将UDC层的usb_gadget赋值到usb_composite_dev中; req成员是用于向UDC层分配数据传输任务的,通常枚举过程中主机请求的设备信息都使用此数据结构传递到UDC层。

usb_composite_dev中的driver的数据结构类型为usb_composite_driver,它的实例是在gadget功能驱动中定义的, 在调用usb_composite_probe()注册函数传递到gadget设备层,最后同样在composite_bind()函数中赋值给usb_composite_devdriver成员,完成设备和驱动的匹配,其结构如下:

struct usb_composite_driver {
usb_gadget_driver gadget_driver;
(*bind)(); (*unbind)();
(*suspend)(); (*resume)(); (*disconnect)();
};

usb_composite_driver结构代表一个USB gadget设备驱动,是USB gadget设备关联Gadget功能驱动的核心数据结构,其中的bind()函数指针是指向Gadget功能驱动层中的function_bind()函数。在Gadget设备层的核心函数usb_composite_probe()中定义usb_gadget_driver数据结构实例并将usb_composite_drivergadget_driver成员指向它,后续底层udc数据结构中的driver也将指向该usb_gadget_drive实例。

2.3、Gadget 功能驱动层

Gadget功能驱动层位于USB gadget驱动框架的最顶层,着重于功能相关的子协议实现,USB协议中的接口( Interface)的就在该层中体现, Linux系统中实现了如下标准功能接口驱动:

通信设备类接口: CDC( Communication Device Class)Android 调试接口: ADB( Android Debug Bridge)人机接口设备接口: HID( Human Interface Device)媒体传输协议接口: MTP( Media Transfer Protocol)大容量存储接口: UMS( USB Mass storage)用户模式文件系统接口:Gadget File System串行通信接口: Serial Function音频类接口: Audio Class视频类接口: Video Class

Gadget设备的composite体系提供了一套数据结构和相应的接口函数用于建立Gadget 组合设备驱动,支持一个配置下有多个功能,一个典型的应用是Android系统中USB gadget 设备,功能驱动的设备和配置在drivers/usb/gadget/android.c 文件中实现的,功能接口包含Mass storageRndisAccessoryMTP以及ADB调试端口,可根据应用需求自由增减, android.c 文件定义了struct usb_configuration 数据结构的实例( android_config_driver),它代表USB设备的一个配置,当该文件中的android_bind()函数被调用时,会通过usb_add_config()usb_add_function()这两个函数将组合设备中所涉及到的功能驱逐一动添加到该配置中。

Gadget功能驱动作为一个独立模块注册到内核中,模块init函数调用usb_composite_probe()函数,把一个usb_composite_driver结构的实例传入Gadget设备层, usb_composite_driver结构中的bind()函数也将在USB gadget设备驱动中的composite_bind()函数中调用,结果是成功的将三层结构串联起来。

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

[图解linux][USB子系统系列]:图解USB设备驱动结构

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » [图解linux][USB子系统系列]:图解USB设备驱动结构
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏