Linux设备驱动子系统第四弹 - USB Gadget

1. 前言

2. 源码架构

3. 枚举过程


1. 前言

Gadget,小饰品。USB Gadget,就是指所开发的电子设备以USB从设备的模式通过USB连接到主机。比如手机用USB线插入PC后,手机就是USB Gadget。本文以Mavell为例,以Gadget插入主机的全过程为主线,分析USB Gadget的架构。

 

2. 源码架构

USB的源码位于/drivers/usb文件夹内,其中包括核心层core,主控制器host,U盘storage,以及USB Gadget等。

gadget文件夹里存放了各芯片厂商支援的USB Gadget控制器驱动,比如支持Mavell的PXA9XX系列的USB Gadget驱动为mv_gadget.c,其架构如下图所示,

 2.1 Gadget控制器驱动

 设备要有gadget功能,硬件上要集成gadget控制器,软件上要具备gadget控制器驱动。

首先是该驱动的数据结构 struct mv_usb_dev,

-> struct usb_gadget, 由linux定义的gadget所需要的数据成员,其中包含了sturct usb_ep。

-> struct mv_usb_ep, 其中的struct usb_ep是由linux定义的endpoint所需要的成员,关于endpoint参看USB协议。

-> struct usb_gadget_driver, 对应该gadget设备功能的驱动,下节将作具体描述。

-> void *mv_usb_handle, 指针指向芯片控制器的数据结构。

 

概括地讲,gadget控制器驱动完成了五个任务,

  • 通过platform_data和resource的到gadget芯片物理地址,中断号等 (橙色)
  • 初始化gadget芯片和相关数据 (浅灰色)
  • 初始化数据struct usb_gadget (蓝色)
  • 初始化数据struct usb_ep (粉色)
  • 注册gadget服务

gadget服务,即该设备所具备的gadget能力,比如reset, suspend, resume, speed,以及需要重点关注的枚举功能mv_usb_ep0_complete_service。注意到,注册服务的函数usb_device_register_service()的第一个参数mv_usb_handle用于得到底层芯片的数据,第三个参数回调函数实现具体功能。

 2.2 Gadget设备驱动

  需要区别gadget设备驱动与上节提到的gadget控制器驱动。gadget设备驱动,是指设备插入主机后具备的功能,该驱动被挂在到struct usb_gadget_driver下。比如手机插入PC作为U盘,那么U盘的驱动程序就是所谓的gadget设备驱动。

(*bind)绑定设备的功能,比如U盘。

(*setup)实现USB设备的枚举。

 2.3 Composite

如果一个设备插入主机后拥有多个功能,比如同时有U盘和android调试功能,那么该设备称为composite复用设备。其数据结构如下,

通过(*bind)绑定设备的各个功能。

 

 

3. 枚举过程

系统初始化USB设备的过程就是枚举过程。

根据USB协议,USB设备初始化的过程为attached->powered->default->address->configured。

当设备插入主机,将等待来自主机的中断信号,通过request_irq()进入中断处理函数。

设备通过读取控制器状态寄存器的值,得到来自主机的反馈,进而执行相应的任务,枚举就是其中的一项任务,通过调用gadget控制器驱动已经注册好的枚举服务,开始枚举过程。

该枚举服务归纳为两步,

第一步,通过读取gadget控制器,得到来自主机的请求,存放至mv_ctrl_req。

第二步,通过switch(mv_ctrl_req),对具体请求作具体处理,处理类别又可分为两类。

1) 标准请求,即所有USB设备可通用的请求,具体有得到状态请求,设置/清除feature请求,设置地址请求。

2) USB设备请求,即根据具体设备,处理具体请求,通过回调函数mv_dev->driver->setup()来实现。

PS: 关于请求,参看USB协议ch9。

重点关注mv_dev->driver->setup()的枚举过程,其实质就是主机从USB设备得到描述符。

这里的mv_dev->driver就是上文2.2所提到的gadget设备驱动,通过driver->bind绑定具体的驱动功能,如果是composite复用设备,则绑定usb_composite_driver结构,通过driver->setup实现设备的枚举过程,代码如下,其中的GET_DESCRIPTOR, SET_CONFIGURATION, 以及f->setup是必要的枚举过程。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值