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

   日期:2020-09-23     浏览:229    评论:0    
核心提示:文章目录1、Linux USB 子系统2、Linux USB 设备驱动结构2.1、UDC 设备控制器层2.2、Gadget设备层2.3、Gadget 功能驱动层1、Linux USB 子系统Linux系统内核中早已集成了较为完善的USB协议栈,由于其规模庞大,包含多个类别的设备驱动,所以Linux系统中的USB协议栈也被称为USB子系统。2、Linux USB 设备驱动结构Gadget驱动指的是运行在设备中的固件,也就是USB设备驱动模型。Linux Gadget 三个软件层:USB设备控.

文章目录

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

1、Linux USB 子系统

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

2、Linux USB 设备驱动结构

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

  1. USB设备控制器层
  2. Gadget设备层
  3. USB功能驱动层

完整的 USB设备端软件是由这三层软件层融合在一起来实现 USB 设备的功能,下面我们看下他们是如何串起来的。
USB 设备层定义了并初始化了一个结构体 struct usb_composite_driver。这个结构体中定义了一些函数指针,并且在 USB 设备层实现了这些函数。这些函数是融合 USB 设备层与上层软件功能驱动层的关键函数。数据结构只是完成了软件架构的构建, 如果需要融合还需 要函数的调用,在这里这个函数就是usb_composite_register。这个函数在 USB 设备层中实现,提供给上层软件功能驱动层来调用。当功能软件层调用这个函数成功后,USB 设备层与上层软件就融合在了一起,这个函数调用还触发了 USB 设备层调用 usb_gadget_register_driver,从而完成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驱动架构的第一现场。

由于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;
};

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()函数中调用,结果是成功的将三层结构串联起来。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服