基于Linux的USB从设备驱动研究

0 概述 usb是英文universal serial bus的缩写,意为通用串行总线。usb是一种快速、双向、同步、低成本、动态可连接的串行接口。usb现在已经广泛应用到各种设备上,尤其是手持设备,几乎都采用了usb接口。现在,usb即可用来与其他设备连接后高速地传递数据,又可用来充电,使手持设备可以发挥u盘、modem、无线网卡等作用。
事实上,usb只是主机和外围设备之间的连接。如何来促使这种连接发挥作用,就需要驱动程序。驱动程序主要解决硬件“需要提供什么功能”以及“如何使用这些功能”。在linux系统中,usb设备可以作为主机使用,也可作为从设备使用。对应的usb驱动程序有两种主要的类型:宿主系统上的驱动程序和设备上的驱动程序。从宿主的观点来看(例如普通的左桌面计算机),宿主系统的usb驱动程序控制插入其中的usb设备,而usb设备的驱动程序则控制该设备如何作为一个usb设备和主机通信。
1 usb设备基础
usb设备的构成包括配置接口和端点,以及usb驱动程序如何绑定到usb接口上。端点是usb通信最基本的形式,usb端点只能是往一个方向传送数据,即从主机到设备(称为输出端点)或者从设备到主机(称为输入端点),故可以看作是单向管道。usb有四种不同的类型,分别对应不同的传输类型:控制、中断、批量、等时。其次接口,usb端点被绑定即为接口。usb的一个接口只处理一种usb逻辑连接;一个usb设备可以有多个接口,不同的接口可以代表不同的功能,因此,功能不同的usb接口需要不同的驱动程序。另外就是配置,usb接口本身被绑定为配置。一个usb设备可以有多个配置,而且可以在配置之间切换以改变设备的状态;一个时刻只能激活一个配置,怛一个配置通常具有一个或者更多的接口。
usb设备可由许多不同的逻辑单元组成,实际上,也就是这三种逻辑单元组合而成的。linux内核中的usb代码一般要用urb (usbrequst block)与usb设备通信。urb用struct urb结构体描述,它能以一种异步的方式往/从特定的usb端点发送/接收数据。usb设备驱动程序可能会为单个端点分配许多的urb,也可能对许多不同的端点重用单个urb,这取决于驱动的需要。当usb驱动程序只发送或接收一些简单的usb数据时,可以使用两个很简单的接口函数:usb_bulk_msg、usb_control_msg。
2 usb设备驱动程序的结构
图1所示是linux环境下usb驱动的总体结构。从图l中可以看到:在主机侧层次结构中,实现usb驱动有两类方式:usb主机控制器驱动和usb设备驱动;usb主机控制驱动主要控制插入其中的usb设备,主机控制器可以分为三类,分别对应于三种usb主控制器;usb设备驱动则用于控制usb设备如何与主机通信;usb核心负责usb驱动管理和协议处理的主要工作。
usb核心向上可为设备驱动提供编程接口,向下可为usb主机控制器驱动提供编程接口;它可以通过全局变量维护整个系统的usb设备信息,从而完成设备的热插拔控制和总线数据传输控制等驱动。
另外,在从设备侧,linux内核中的usb设备侧驱动程序可分为3个层次:usb设备控制器(udc)驱动程序、gadget api和gadget驱动程序;udc驱动程序可直接访问硬件,控制usb设备和主机间的底层通信,并向上层提供和硬件相关的操作回调函数。不同的设备控制器硬件有不同的设备控制器驱动程序;gadget驱动主要控制usb设备功能的实现,它使用gadget api传递控制信息给udc驱动程序,以便实现具体功能。
gadget api是设备控制器的控制功能抽象接口,gadget驱动程序可以试用gadget api,它可以把下层的udc驱动程序和上层gadget驱动程序相隔离,以使得在linux系统中编写usb设备侧驱动程序时,能够把功能的实现和底层通信相分离。
如果要在s3c24.10上实现大存储类从设备,则需要运行file_storage.c和s3c2410_udc.c这两个驱动程序。file_stoarge.c具体控制usb设备功能的实现,它使用gadget api来控制s3c2410.c以实现其功能。s3c2410.c驱动程序可直接访问硬件,以控制usb设备和主机间的底层通信,同时向上层提供和硬件相关操作的回调函数。
3 usb从设备驱动
驱动程序完成的功能包括初始化设备、为各类设备提供服务、负责内核与设备间的数据交换、以及检测和处理设备工作过程中出现的错误等。
基于完成这些功能,每个驱动程序都需要注册和注销,这样,内核才能知道有这个驱动的存在或者驱动的卸载。下面是两个最基本的模块:
module_init(usb_skel_init);
module_exit(usb_skel_exit);
对于usb从设备而言,结构usb_gadget就可以代表。gadget通过“gadget驱动程序”来实现设备功能,处理所有的usb配置和接口。通过操作函数集,gadget驱动程序与硬件特定代码间接通信。它将gadget驱动程序与那个硬件细节隔开,并通过i/o队列包装硬件端点。 “usb_gadget”“usb_ep”接口则可提供对硬件的隔离。
其结构usb_gadget的代码如下:
结构usb_gadget_ops是usb设备控制期的设备控制函数集,其操作包括get_frames、wakeup、pullop、ioctl等。结构struct usb_ep是usb端点从设备侧的代表,总线控制器驱动程序中列出了在gadget->ep_list里所有的通用端点,但控制端点不在列表中,它仅在回应驱动程序的setup 0 回调函数时才被访问,其代码如下:
4 结束语
本文主要通过在s3c2401上实现usb从设备的驱动程序,介绍了usb从设备驱动的研究方法。linux作为一个开源操作系统,设备驱动程序的开发有着其它操作系统不可比拟的优势,大量的开放源代码无疑可以加速usb从设备驱动,并使其应用更加广泛。因此,usb作为一种新型的高速外设总线,它必将更加促进linux系统源码的开发和完善,同时亦会促进自身的更广泛的应用。

1.5A轨到轨输出同步降压型稳压器可通过单个电阻器进行调节
趋势所致?深入解析苹果“美国制造”战略
如何利用STC89C52RC去实现一种99秒倒计时器的设计呢
叉车油改电的背景下,如何选择一款优质国产MOS管提升控制器质量?
融合定位技术,应对物联网碎片化场景应用!
基于Linux的USB从设备驱动研究
8万级陆地移动堡垒,2023款欧萌达极致安全再进阶
SpringSoft Laker定制版图系统支持TSMC跨平
区块链到底是什么有哪些应用
电动汽车电池为住宅供电!
PLC数据采集如何实现?PLC数据采集网关怎么来选?
2020年搭载Imagination IP的海外设备有哪些?
物理隔离的操作系统
3D打印产业链分析
基于Intel Atom E3800的车载计算机解决方案
无线视频监控的两种方法
极海APM32F407工业HMI应用方案助您增强交互体验
为何高通仅仅在专利授权费方面的收入就能够高达55亿美元呢?
郭明錤:iPhone 13包含4款机型,欲将在明年9月发布
为什么我们把晶体放在IC附近?微控制器中晶体振荡器的作用是什么?