嵌入式Linux的USB驱动设计
嵌入式Linux下USB2.0海量存储设备驱动设计

性 、 享 式通 信 、 成 本 等 优 点 。 由 于 U B接 1的 优 点 和 流 行 , V C A E & etf s来 实 现 的 。 对 于 该 函 数 , A O _ R是 共 低 S 3 I E N M 。 t o ) s p M JR N 当今 嵌 入 式设 计 要 和 P 连接 . C 首选 U B接 口 。 S 主设 备 号 。 E I E N ME是 设 备 名 称 。 ts f1 则 是 e rd - D VC A & et o ' 3 3 h e
_
S N E R P 。 E I E N M 。 U L 内 核 函 数 实 现 。 其 中 A I T R U TD V C A E N L ) 设 计前 首 先 需要 了解 U B协 议 。 S R U S N E RU , 快 速 中 断 标 志 , r为 U B采用 树 形 拓扑 结构 。主机 侧 和设 备 侧 U B控 制 器分 别 I O N M 是 申 请 的 中 断 号 . A I T R P S S 称 为 主 机 控 制 器 ( ot o t l r U B设 备 控 制 器 ( D H s C nr l 和 S oe U C), D V C A E I E N ME是 设 备 名 。 q p 0 中断 处 理 函 数 指针 。 个 函 i 1 为 r 3 这
L U i X以 其 开 源 、 于 移 植 和 可 裁 剪 性 。 来 越 多 地 被 应 用 v e oeao s 构指 针 。这 样 .操 作 系 统 便 可 以通 过 crd n 易 越 i prtn 结 c i h_ e - 于嵌 入 式 系统 。Ln x内核 支 持 2种 主要 类 型 的 驱 动 程 序 : 机 v e o ea os 上层 操作 与驱 动 设 备 之 间 连接 起 来 。 i u 主 i p rt n 将 c i crdv eo eaos中提 供 了操作 与 驱动 函 数 的 接 1 。典 l ei pr i l c tn 3 端 和设 备 端 驱 动程 序 主 机端 驱动 程 序 控制 与其 连 接 的 U B设 S 备从 而使 用 设 备 的 功 能 : 备 端 U B驱 动程 序 控 制设 备 如 何 与 型 的 操 作 如 o e ( 开 设 备 ) r e s ( 闭设 备 ) i f 系 统 调 设 S pn打 , lae 关 e ,c( ol . d 读操 作 )w i ( 操作 ) 是 在该 结 构 中 与 具体 的驱 动 e 。re 写 t 都 主 机通 信 从 而 使 其 对 主 机 表 现 出 特定 的功 能 . 时 的 设 备 应 理 用 ) ra ( 此 解 为 运行 Un 】的嵌 入 式 系 统 。本 文 将 着 重 分 析 的 便 是 设 备 端 函数 挂 钩 。 u【 如果 没 有 上层 空 间 对 驱动 的操 作 。 结 构 中 可 以全 部 该 填入空指针。 U B驱动 程 序 的设 计 与 实 现 。 S 该 U B设 备 驱 动 都 是 基 于 中 断 实现 的 . 此 在 驱 动 中 必 须 S 因 2设 计 概 述 . 有 中 断 的 注册 。 中断 注 册 是 通 过 rq eti ( Q N M,q po e u s r I — U i _ r, 21协 议概 述 .. q R r
嵌入式LinuxUSB驱动程序

备 三部 分 组 成 的 ,其 结 构 如 图 1 示 。 在 编 写 U B设 备 驱 动 所 S 程 序 设 计 时 ,可 以分 为三 部 分 编 写 :主 机 端 设 备 驱 动 程 序 、主 机 控 制 器 驱 动程 序 设 计 和设 备 端 驱 动程 序 三 部 分 ,在 本 文 中重 点 介 绍 主 机 端 驱 动 程序 的设 计 。
编 写 驱 动 程 序 框 架 ,通 过 调 用 操 作 系统 提 供 的 A I 口函数 可 P接
以完 成 对 U B外 设 的 特 定 访 问 。 S 主 机 控 制 驱 动 主 要 是 对 U B主 机 控 制 器 的 驱 动 。在 大 多 S
双 向 同步 传 输 的支 持 热 插 拔 的数 据 传 输 总 线 ,其 目的是 为 了提 供 一种 兼 容 不 同速 度 的 、 可扩 充 的并 且 使 用 方 便 的外 围设 备接 口 , 同时 也 是 为 了解 决 计 算 机 接 口 的太 多 的弊 端 而设 计 的 。一
U B设备 驱 动 程 序 S
上层 A I函 数 P U B核 S 下 层 ^ I函 P
U B主机 控制器驱动 程序 S
U B主机控 制器驱动程序 S
图 2 U B主 机 端 驱 动 程 序 结 构 S
U B设 备 驱 动程 序 是 常说 的设 备 固 件 程 序 的 一 部 分 ,提 供 S 设 备 信 息 与 主 机 的 通 信 接 口 。设 备 端 U B驱 动 程 序 设 计 由 以 S 下 几 部 分 处 理 程 序 组 成 。 初 始 化 例 程 :完 成 描 述 符 指 针 、端 点 、配 置 改 变等 操 作 。数 据 传输 例 程 :完 成 控 制 传 输 、批 量 传 输 、中 断传 输 及 同 步 传输 等 传输 方 式 下 的 数 据 收 发 工 作 。标 准
嵌入式Linux下的USB设备驱动技术

嵌入式Linux下的USB设备驱动技术Linux以其稳定、高效、易定制、硬件支持广泛、源代码开放等特点,已在嵌入式领域迅速崛起,被国际上许多大型的跨国企业用作嵌入式产品的系统平台。
USB是Universal Serial Bus (通用串行总线)的缩写,是1995年由Microsoft、Compaq、IBM等公司联合制定的一种新的PC串行通信协议。
它是一种快速、灵活的总线接口。
与其它通信接口相比较,USB接口的最大特点是易于使用,这也是USB的主要设计目标。
USB的成功得益于在USB标准中除定义了通信的物理层和电器层标准外。
还定义了一套相对完整的软件协议堆栈。
这使得多数USB设备都很容易在各种平台上工作。
作为一种高速总线接口,USB适用于多种设备(如数码相机、MP3播放器、高速数据采集设备等)。
另外,USB接口还支持热插拔,而且所有的配置过程都由系统自动完成,无须用户干预。
1 Linux下的USB设备驱动在Linux内核的不断升级过程中,驱动程序的结构相对稳定。
由于USB设备也是外围设备的一种,因此,它的驱动程序结构与普通设备的驱动程序相同。
Linux系统的设备分为字符设备(CharDevice)和块设备(BlockDevice)。
字符设备支持面向块字符的I/O操作,它不通过系统的快速缓存,而只支持顺序存取。
块设备则支持面向块的I/O操作,所有块设备的I/O操作都通过在内核地址空间的I/O缓冲区进行,可以支持几乎任意长度和任意位置上的I/O请求。
块设备与字符设备还有一点不同,就是块设备必须能够随机存取(RandomAccess),字符设备则没有这个要求。
典型的字符设备包括鼠标、键盘、串行口等,而块设备主要包括硬盘软盘设备、CD-Rom等。
由于USB设备主要都是通过快速串行通讯来读写数据,因此一般都可作为字符设备来进行处理。
2 Linux下的USB core2.1 Linux中USB core与USB的结构关系Linux操作系统中有一个叫做“USB core”的子系统,可提供支持USB设备驱动程序的API和USB主机控制器的驱动程序。
嵌入式linux下usb驱动开发方法-

嵌入式linux下usb驱动开发方法--看完少走弯路嵌入式linux下的usb属于所有驱动中相当复杂的一个子系统,要想将她彻底征服,至少需要个把月的时间,不信?那是你没做过。
本人做过2年的嵌入式驱动开发,usb占了一大半的时间。
期间走了不少弯路,下面将我的血的经验教训总结下,为要从事和正在从事的战友们做一点点贡献吧:)首先,扫盲;要做的是阅读usb Spec(英文的哦,其实很多文章、书籍和资料真有水平的还是原创的好,就像食品往往经过加工就变了味,之前如果没有接触过的话可以先看看中文的,大概先有个印象),这个工作其实是很复杂很枯燥的一部分。
看Spec的同时可以到网上大概浏览下usb开发的相关知识,这个阶段就是扫盲,不求精进。
至少你得知道usb的四种传输类型吧,你得知道usb从上电开始的几个状态吧,你得知道usb设备都有哪些吧,等等。
第二步,窥全貌;usb设备是如何工作起来的?其实usb子系统是分层次工作的,他们配合默契,做好自己的份内之事,一切以大局为重。
usb驱动可以分为usb设备驱动,usb控制器驱动,hub驱动,总线驱动等等。
我建议你还是顺着设备驱动的这根主线往下走吧。
在真正开始分析usb驱动代码这之前,你需要了解linux模块机制,linux驱动的platform总线构架,之类。
一个模块被加载后,从driver的角度来说,真正将设备驱动起来是从probe开始的。
这个你该知道。
你得知道为什么usb可以即插即用,做软件的朋友该知道线程这个东西吧,和她有关系的。
usb系统里面一个最重要的角色该出场了,urb。
一切的一切都要围绕她进行。
pipe为她铺路,数据由她承载。
usb设备驱动的工作就是准备好这个urb后她的使命就基本完成了,那她把urb给了谁?这就是之前提到的usb控制器驱动,host。
至于host,现在市场上有很多款,如果你老板给你用的是市面上用的最成熟的像EHCI,那么你太幸运了。
这个基本不用你写,只要稍加修改,把她注册到总线上即可。
基于嵌入式Linux的USB字符设备驱动程序设计

(data一>dev,
”%s
ready\n’,dev一
char
>name):
)
fd一>private data=USB device:
): 与DR驱动相关部分主要是实现结构体USB—gadget _driver的初始化如下,只列出了其中最重要的三个函数。 static struct USB—gadget—driver USB_char—driver=request*req;
responses≮}
enum
USB—char—state state:
struct
USB—ep*in—ep,*out—ep:
USB——endpoint——descriptor
const struct
2.2与上层应用相关的字符设备驱动部分 与上层应用相关的字符设备驱动部分主要是完成字 符设备文件结构fi 1e operations中open、write和read 等函数。字符设备打开操作定义为USB open,首先判断USB 设备的当前工作状态,如果设备当前没有连接则返回,否 则将USB—bind中初始化分配的USB—char.dev指针赋值给 文件的私有数据结构,并完成字符设备的其他操作。
struct struct struct
USB—device=dev=(struct USB~char—dev USB—char—dev), GFP—KERNEL):
木)kmal 10C(Si zeof(struct if(dev==NULL)
return—ENOMEM:
INIT—LIST—HEAD(&dev一>tx—reqs):
static char ssize—t
USB—read(struct
嵌入式Linux系统下的USB驱动程序开发

程 中 的关键技 术 。
关键 词 : 嵌入 式 ; L i n u x ; U S B ; 驱动 开发 中图分 类号 : T P 3 1 6 文献标 识码 : A
De v e l o p me n t o f US B Dr i v e r Ba s e d o n Em b e d d e d Li n u x S y s t e m
L I C h u n - b o , C HE N We i - f e n g , L A I X u e - j i n
( C h e n g d u U n i v e r s i t y o f T e c h n o l o g y , C h e n g d u 6 1 0 0 5 9 , C h i n a )
Abs t r a c t : The a p pl i c a t i o n s o f Emb e d de d L i n ux s y s t e m a r e mo r e a n d mo r e wi de l y , i t s f u n c t i o ns a r e a l s o mo r e a n d mo r e
H O S T) 、 U S B设 备 ( U S B D E V I C E) 、 U S B 集 线 器
哑 I … ● I _ l C 【 l h 】 i n 国 a I n 集 t e g r 成 a t e d 电 C i r 路 c u i t
————— 珏 斗 。 ]I
嵌入式 L i n u x系统下的 US B驱动程序开发
基于嵌入式Linux的USB驱动程序的设计与实现
* 2011-03-01收到,2011-04-20改回** 赵 鹏,男,1973年生,讲师,研究方向:数字图书馆,数据仓库,软件工程和嵌入式系统。
文章编号:1003-5850(2011)06-0065-02基于嵌入式Linux 的USB 驱动程序的设计与实现Design and Implementation of USB Driver Based on Embedded Linux赵 鹏(太原师范学院计算机系 太原 030012)【摘 要】U SB 现在已经广泛应用到各种设备上,尤其是手持设备,几乎都采用了U SB 接口。
U SB 既可用来与其他设备连接后高速地传递数据,又可用来充电,使手持设备可以发挥U 盘、M ODEM 、无线网卡等作用。
详细介绍了嵌入式Linux 下USB 接口驱动的开发原理与设计实现。
【关键词】嵌入式,Linux ,驱动,U SB中图分类号:T P 319文献标识码:AABSTRACT U niv er sal Serial Bus U SB is an abbr ev iat ion in English,w hich mea ns U niv ersal Serial Bus.U SB is a fast ,bidirectional,sy nchr ono us,low -co st ,dy nam ically atta chable ser ial inter face.U SB is no w w idely applied to v ar ious dev ices,especially handheld devices ,almo st a ll using U SB inter face .N ow ,U SB and o ther devices can be connect ed to high speed tr ansmission of data,can be used to char g e,so that handsets can play a U disk,M OD EM ,w ir eless net wo rk card and so o n.T his ar ticle describes in detail under the U SB int erface driv er em bedded L inux development principle and Design .KEYWORDS em bedded,L inux,Dr iv er ,U SB U SB 是主机和外围设备之间连接的接口,是一种接口技术规范。
嵌入式Linux的USB驱动设计
嵌入式Linux的USB驱动设计李丽宏;郝志刚【期刊名称】《电子设计工程》【年(卷),期】2011(19)11【摘要】本文主要介绍了Linux平台的USB设备驱动开发的一般步骤方法和技巧,通过详细介绍USB的相关概念和Linux中USB设备驱动程序的数据结构,框架和步骤,并通过设计和实现一个驱动的实例,总结了USB驱动的一般方法和技巧.%This paper introduces the methods and steps of skills about USB device driver development on Linux platforms,it concluded general methods and skills in USB device drive through introduced concretely the related concepts of USB and the data structures ,framework and steps of USB device driver in the Linux and through designed and implemented a typical driver example.【总页数】4页(P170-173)【作者】李丽宏;郝志刚【作者单位】太原理工大学信息工程学院,山西太原030024;太原理工大学信息工程学院,山西太原030024【正文语种】中文【中图分类】TP3【相关文献】1.嵌入式Linux下USB主控制器驱动设计 [J], 杨磊;蒋念平2.嵌入式Linux的USB Chirp无线网卡驱动设计 [J], 叶学程;郑霖3.基于嵌入式linux的USB驱动设计 [J], 杨建华;黄字东;陈安;胡跃明4.嵌入式Linux下USB2.0海量存储设备驱动设计 [J], 冯韬;李广军5.基于嵌入式Linux的USB键盘驱动设计 [J], 李小琦;汪红因版权原因,仅展示原文概要,查看原文内容请购买。
基于嵌入式Linux的USB主控制器驱动设计
基于嵌入式Linux的USB主控制器驱动设计Design of USB Host Controller Driver Based on Embedded LinuxAbstract: This paper designs the USB host controller driver for the USB host controller of S3C2410. The driver is based on Linux, it followed USB 1.1 and OHCI 1.0 specification. This driver makes the embedded system with S3C2410 has USB host function and can communicate with USB devices.Key Word: USB host controller driver, Linux, S3C2410摘要:本文为S3C2410的USB主机控制器设计了基于Linux的USB主机控制器驱动程序。
该驱动程序遵循USB1.1版本协议和OHCI 1.0版本协议。
使具有S3C2410的嵌入式系统具备了USB主机功能,能够和各种USB设备进行通信。
关键词:USB主机控制器驱动,Linux,S3C24101 引言随着USB技术越来越多地被应用到嵌入式领域,人们对身边所使用的嵌入式系统提出了新的要求,希望在嵌入式系统中增加USB主机功能,使嵌入式系统具有移动存储功能,如挂接各种移动存储设备、直接与USB打印机连接打印数码相片等。
嵌入式USB主机系统的开发成为当前的一个热点。
嵌入式USB主机系统设计包括软件和硬件两个部分。
其中软件设计主要包括USB核心驱动程序和USB主机控制器驱动程序两个部分。
Linux操作系统是一个源码开放,资源丰富的操作系统。
Linux系统对USB主机协议提供了一定的支持,并提供了众多的USB类设备驱动程序,为应用开发提供了便捷。
嵌入式linux下基于libusb的USB驱动开发
技术与市场
1--= < ,,
!
技术研发 DA=E]^6^[_ :]3 H:P\AD
或者输入命令: !"#$%&% #’()’ $"$* + ,-". + (#’ + #’( 通过它可以查 #’()’ 动态跟踪总线上插入和移除的设备, 包括拓扑、 带宽、 设备描述符、 产品 看系统中 /01 的设备信息, 配置描述符、 接口描述符、 端点描述符等。 #’()’ 还允许用 23、 户空间的程序直接访问 /01 设备, 这使得许多内核驱动程序 可以迁移到用户空间, 从而更加容易维护和调试。 #’()’ 也支持各种 4".%5 的调用。有了这些 4".%5’ 我们就可 而 54(#’( 做的工作就是把这 以编写用户空间的 #’( 驱动程序, 些 4".)5 开发成一个库。 !" 64(#’( 实现驱动开发 7 8 9 64(#’( 简介 它封装了低级别的内核 与 64(#’( 是一种高级别的 :;2, 并提供了一系列适合在用户空间进行 /01 /01 模块的交互, 驱动开发的函数。 54(#’( 基于 /01 文件系统提供的 /01 接口、 端点等信息, 与 /01 设备进行通信。显然, 只要开发平台上的 我们就可以利用 54(#’( 进行 /01 驱动 内核支持 /01 文件系统, 开发。 开发的程序很容易在不同操作系 64(#’( 可以跨平台实现, 统平台上移植。对于 54$#< 操作系统, 也很容易在不同的 =;/ 架构间进行移植, 而且不必担心内核版本造成的种种问题。 相对与 54$#< 内核驱动开发, 省力而又 54(#’( 无疑是一种省时、 行之有效的开发工具。 64(#’( 定义了 ’%-#.% #’( > (#’, ’%-#.% #’( > ?*@4.* 和 #’( > <<< > 设备、 配置和端点等进行描述。 ?*’.-4,%"- 来对 #’( 总线、 一般可通过 54(#’( 提供的一些初始化函数, 在 #’( 文件系 统中查找相关的总线和设备, 并保存在几个对应的数据结构 中: () 函数检查环境变量 /01 > 3ABC0 > ;:DE, 目录 + #’( > 4$4% 若指定路径下含有 #’( 文件 ?*@ + (#’ + #’( 或目录 + ,-". + (#’ + #’(, [ ;:DE > H:I J 系统信息, 则将路径保存在全局变量 #’( > ,F%G 中。 9] () 函数会根据 #’( > ,F%G [] 找到系统中所有 #’( > )4$? > (#’’*’ 并组成链表, 由全局结构指针 #’( > (#’’*’ 指向。 的 /01 (#’, () 函数则遍历 #’( > (#’’*’ 指向的链表, 寻 #’( > )4$? > ?*@4.*’ 找所有 (#’ 上的所有 /01 设备。每个 (#’ 上的所有 ?*@4.*’ 列 表由 #’( > (#’ 结构成员 ’%-#.% #’( > ?*@4.* ! ?*@4.*’ 指向。 遍历 #’( > (#’’*’ 指向的链表, 找 我们可用两层的 )"- 循环, 到与指定描述符相符的 #’( > ?*@4.*。如通常是通过 4?B*$?*- 和 4?;-"?#.% 查找。 如果要对 #’( > ?*@ > GF$?5* 是一个十分重要的句柄结构, 接口、 端点等操作, 都离不开它, 结构表示如下: /01 设备、 ’%-#.% #’( > ?*@ > GF$?5* { 4$% )?; ’%-#.% #’( > (#’ ! (#’; ’%-#.% #’( > ?*@4.* ! ?*@4.*; 4$% ."$)4K; 4$% 4$%*-)F.*; 4$% F5%’*%%4$K; @"4? ! 4!,5 > 4$)"; } ; 与文件系统关联; 域 (#’ 和 ?*@4.* 则指向 域 )? 为文件描述符, } #" 总结 本文实现基础是 #’()’ 允许用户空间的程序直接访问 /01 设备, 这使得许多内核驱动程序可以迁移到用户空间, 通过 使 54(#’( 库提供的 :;2 函数实现嵌入式 54$#< 驱动开发的方法, 无需区分不同版本 得开发人员无需被底层的 /01 协议所困, 内核驱动开发, 从而使得 /01 的驱动开发更加容易维护和调 试, 从而可以提高开发效率并缩短开发周期。 参考文献: 李纪扣, 畅卫功 8 嵌入式 64$#< 下 /01 驱动的实现 [9] 肖刚, [ X] 微计算机信息, ,OU) 8 OSSY( 8 [O] 宋宝华 8 54$#< 设备驱动开发详解 [ H] 人民邮电出 8 北京: 版社, OSSZ 8 [7] X"$F%GF$ ="-(*%, :5*’’F$?-" P#(4$4,[-*K \-"FG&EF-%!F$8 54$& [ H] 中国电力出版社, #< 魏永明 8 设备驱动程序 8 北京: OSSU 8 要处理的 /01 设备。 () , 打 开 指 定 的 /01 设 备 开发 人 员 可 以 使 用 #’( > ",*$ 并返回相应的句柄结构: ?*@, ( ?*@) ; #’( > ?*@ > GF$?5* ! ?*@ > GF$?5* L #’( > ",*$ 之后, ?*@ > GF$?5* 便贯穿于对相应 /01 设备的操作过程 () 关闭指定的 /01 设备, 释放该句 中, 直至最后调用 #’( > .5"’* 柄。 () ,#’( > ’*%F5%4$%*-& 开发人员可使用 #’( > ’*% > ."$)4K#-F%4"$ () 等函数对 /01 设备的配置, 接口和端点等进行设定。然 )F.* () 进行控制传输, 或 #’( > (#5M > N-4%* () , 后调用 #’( > ."$%-"5 > !’K () 进行大批量的端点读写。 #’( > (#5M > -*F? 7 8 O 开发实例 先要在 ;= 机上进行交叉 64(#’( 要应用到嵌入式系统中, 编译。如我使用 :PHQ 系列的 07=OR9S 开发板, ;= 操作系统 为 P*?GF% 64$#< Q, 使用的交叉编译工具为 .-"’’ O 8 QT 8 7。 54(#’( 库以及开发代码都用 F-! > 54$#< > K.. 来编译。 开发代码中要包含 54(#’( 的头文件 #’(8 G, 并在 F-! > 54$#< 要使用 > 2 和 > 6 选项指定 54(#’( 的头文件和库 > K.. 编译时, 文件的路径, 和 > 5#’( 指定 54(#’(8 F 静态库文件。 下面的伪代码在系统中按厂商号和产品号找到 #’( 图像 因为 07=OR9S 只支持 /019 8 采集设备并读 (#5M 端点到缓冲中, 所以每次读 UR 字节。 S + 9 8 9, ( @"4?) 4$% !F4$ { + + …一些初始化工作 () ; ?*@ L #’(?*@ > ,-"(* + + 找到 #’( 设备 ( ?*@) ; ?*@ > GF$?5* L #’( > ",*$ + + 打开设备 请求传输 + + 发送控制信息, ( ?*@ > GF$?5*, #’( > ."$%-"5 > !’K S<RS, S<(U, O, S, ( (#))*-) , ; (#))*-, ’4V*") 9SSS) { 4)( ?*@ > GF$?5*) 从端点 U 传输数据到 4!FK* > (#))*- 中 + + 若请求成功, ( ?*@ > GF$?5*, #’( > (#5M > -*F? U, [UR] , ; W4!FK* > (#))*UR, 9SSS) } ( ?*@ > GF$?5*) ;+ + 关闭设备 #’( > .5"’*
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电子设计工程Electronic Design Engineering第19卷Vol.19第11期No.112011年6月Jun.2011收稿日期:2011-03-10稿件编号:201103053作者简介:李丽宏(1963—),男,山西太原人,博士研究生,副教授。
研究方向:检测技术、智能仪表。
嵌入式Linux 的USB 驱动设计李丽宏,郝志刚(太原理工大学信息工程学院,山西太原030024)摘要:本文主要介绍了Linux 平台的USB 设备驱动开发的一般步骤方法和技巧,通过详细介绍USB 的相关概念和Linux 中USB 设备驱动程序的数据结构,框架和步骤,并通过设计和实现一个驱动的实例,总结了USB 驱动的一般方法和技巧。
关键词:USB ;Linux ;设备驱动程序;嵌入式系统中图分类号:TP3文献标识码:A文章编号:1674-6236(2011)11-0170-04Design of USB driver based on embedded LinuxLI Li -hong ,HAO Zhi -gang(College of information engineering ,Taiy university of technology ,Taiyuan 030024,China )Abstract :This paper introduces the methods and steps of skills about USB device driver development on Linux platforms,it concluded general methods and skills in USB device drive through introduced concretely the related concepts of USB and the data structures ,framework and steps of USB device driver in the Linux and through designed and implemented a typical driver example.Key words :USB;Linux;device driver program ;embedded system随着计算机外围硬件的扩展,各种外围设备使用不同的总线接口,导致计算机外部各种总线繁多,管理困难,USB 总线可以解决这些问题,因此而诞生。
USB 总线提供统一的外没的接口方式,并且支持热插拔,方便了厂商开发设备和用户使用设备。
USB (通用串行总线)是由Microsoft,Compad ,Inter 和NEC 等推出的外围总线接口,目前已发展到2.0标准最高支持480Mb/s 的速率,最多可以支持127个外设。
嵌入式Linux 是一款源代码完全免费的新兴操作系统,用户可以用户可以通过网络等其他途径免费获得,并可以任意修改其源代码,这是其他的操作系统做不到的。
正是由于这一点,Linux 得到了广泛的应用。
1Linux 中USB 设备驱动程序框架及数据结构1.1USB 的体系结构USB 接口标准支持外部设备和主机之间进行数据传送。
在USB 结构中主机预设各种类型外设使用的总线宽度。
当外设和主机在运行时,USB 总线允许使用,设置,添加和拆除外设。
在USB 体系结构中一个USB 系统可以分成USB 设备、USB 主机和USB 互联3个部分。
USB 互联是USB 设备和USB 主机之间进行连接通信的操作[1],主要包括:1)总线拓扑结构:USB 主机和USB 设备之间的连接方式;2)数据流模式:描述USB 通信系统数据如何从产生方传递到使用方;3)USB 调度:USB 总线是一个共享连接,对可以使用的连按进行调度以支持同步数据传输,并避兔优先级判断的开销。
USB 的物理连接是有层次的星型结构,如图1所示。
从图中可以看出USB 集线器在一个节点上连接多个设备,每条线段都是点点连接,每个USB 集线器在星形的中心。
从主机到设备或者USB 集线器,或USB 集线器到设备都是点点连接。
1.2USB 驱动程序的结构USB 总线在技术层面上是非常简单的,它是一个单主方式实现的,主机轮询各种不同的外围设备,USB 另外一个重要的特性是它只担当设备和主控制器之间通讯通道的角色,对所发送的数据没有任何特殊的内容和结构上的要求。
Linux支持两种类型的USB驱动,宿主系统[2]上的驱动程序和设备上的驱动程序。
宿主USB驱动程序控制插入其中的USB设备,而USB设备的驱动程序控制设备如何作为一个USB设备和主机通讯。
这里主要讨论设备驱动。
USB的基本通信的形式基本通过端点的东西。
USB端点[3]只能往一个方向传输数据,从主机到设备或从设备到主机。
USB端点分别具有不同的传输数据的方式,他们有4种类型,分别是:1)控制端点用来控制对USB设备不同部分的访问。
他们用于配置设备,获取设备信息,获取设备的状态报告,发送命令到设备。
它是一种非周期性的可靠的传输。
2)中断端点就是设备传输数据时以一个固定的速率来传输少量的数据。
这些端点是鼠标和USB键盘所使用的主要传输方式。
它通常用于发送数据到USB设备以控制设备,一般不用来传输大量数据。
USB协议保证这些传输有足够的保留带宽来传输数据。
3)等时端点同样可以传输大批量的数据,但数据是否到达没有保障,这些端点用于可以应付数据丢失的情况,这类设备更注重于保持一定的恒定的数据流,实时的数据收集都使用这类端点。
4)批量端点传输大量的数据。
这些端点通常比中断端点大的多他们常用于需要确保没有数据丢失的传输设备。
USB协议不保证这些传输始终可以在特定的时间内完成。
如果总线上的空间不足以发送整个批量包。
它将被分割为多个包进行传输。
当一个USB设备连接到主机时,主机会给这个设备分配一个1~127之间的唯一的设备号同时读取该设备的描述符,该设备描述符是描述设备信息及其属性的数据结构,USB以一种层次化的结构定义设备的描述符,设备描述符给出了USB设备的一般信息,包括对设备及所有设备配置起全程作用的信息,一个USB设备只能有一个设备描述符,配置描述符中的信息与设备特定的配置相关,一个USB设备可以有一个或多个配置描述符,每个配置描述符又由一个或多个接口描述符组成,接口描述符的信息是与设备驱动程序的开发密切相关,可以一个接口对应一个设备驱动程序也可以多个接口对应一个设备驱动程序,接口描述符由零个或多个端点描述符组成,端点描述符定义了在一个给定的设备里实现的实际寄存器.这些描述符定义了每个寄存器的功能和特定的信息如端点要求的传输类型、传输方向、带宽要求、查询间隔等。
另外,还有一个可选的字符串描述符,它以UNCOND码的格式给出了一些可读的信息,这些信息通常是有关设备生产厂商、设备名设备序列号等,通过这些不同层次的描述符.主机设备驱动程序就可以知道具体设备的相关信息,从而对设备进行相应控制。
1.3USB驱动程序框架1.3.1基本数据结构usb-skel设备使用自定义结构usb_skel记录设备驱动用到的所有描述符,该结构定义如下:struct usb_skel{struct usb_device*udev;//USB设备描述符struct usb_interface*interface;//USB接口描述符struct semaphore limit_sem;//互斥信号量unsigned char*bulk_in_buffer;//数据接收缓冲区size_t bulk_in_size;//数据接收缓冲区大小_u8bulk_in_endpointAddr;//入端点地址_u8bulk_out_endpointAddr;//出端点地址struct kref kref;};1.3.2驱动程序初始化和注销同其他所有的Linux设备驱动程序一样,usb-skel驱动使用module_init()宏初始化函数,使用module_exit()宏注销函数。
usb-skel驱动的初始化函数usb_skel_init()函数,定义如下:static int_init usb_skel_init(void){int result;result-usb_register(&skel_driver);//注册USB设备驱动if(result)err(“usb_register failed.Error number%d”,result);return result;}sb_skel_init()函数调用内核提供的usb_register()函数注册了一个usb_driver类型的结构变量,该变量定义如下:static struct usb_driver skel_driver={.name=“skeleton”,//USB设备名称.probe=skel_probe,//USB设备初始化函数.disconnect=skel_disconnect,//USB设备注销函数.id_table=skel_table,//USB设备ID映射表};其中usb_skel设备的USB ID映射表定义如下:static struct usb_device_id skel_table[]={{USB_DEVICE(USB_SKEL_VENDOR_ID,USB_SKEL_PR-ODUCT_ID)};《电子设计工程》2011年第11期在USB驱动中调用usb_deregister()函数注销usb-skel设备驱动,函数定义如下:static void_exit usb_skel_exit(void)usb_deregister(&skel_driver);//注销USB设备};1.3.3初始化设备从skel_driver结构可以知道usb-skel设备的初始化函数是skel_probe()函数,设备初始化主要是探测设备类型,分配USB设备用到的urb资源[5],注册USB设备操作函数等。
skel_class结构变量记录了usb-skel设备信息,定义如下:static struct usb_class_driver skel_class={.name=“skel%d”,//设备名称.fops=&skel_fops,//设备操作函数.minor_base=USB_SKEL_MINOR_BASE,};name变量使用%d通配符表示一个整型变量,当一个usb-skel类型的设备连接到USB总先后会2按照子设备编号自动设置设备名称。
Fops设备操作函数结构变量,定义如下:static struct file_operations skel_fops={.owener=THIS_MODULE,.read=skel_read,//读操作.write=skel_write,//写操作.open=skel_open,//打开操作.release=skel_release,//关闭操作};1.3.4设备注销skel_disconnect()函数在注销设备时被调用,定义如下:static void skel_disconnect(struct usb_interface*interface){struct usb_skel*dev;int minor=interface->minor;lock_kernel();//在操作之前加锁dev=usb_get_intfdata(interface);//获得USB设备接口描述usb_set_intfdata(interface,NULL);//设置USB设备接口描述无效usb_deregister_dev(interface,&skel_class);//注销USB设备操作描述unlock kernel();//操作完毕解锁kref_put(&dev->kref,skel_delete);//减小引用计数info(“USB Skeleton#%d now disconnected”,minor);};2USB串口驱动2.1驱动初始化函数usb_serial_init()函数是一个典型的USB设备驱动初始化函数,定义如下:static int_int usb_setial_init(viod){int i;int result;usb_tty_driver=alloc_tty_driver(SERIAL_TTY_MINORS); //申请tty设备驱动描述if(!usb_tty_driver)return-ENOMEM;result=bus_reqister(&usb_serial_bus_type);//注册总线if(result){err(“Regist bus driver failed”);qoto exit_bus;}usb_tty_driver=>owener=THIS_MODULE;usb_tty_driver->driver_name=“usbserial”;//串口驱动名称usb_tty_driver->devfs_name=“usb/tts”;//设备文件系统存放路径usb_tty_driver->name=“ttyUSB”;//串口设备名称usb_tty_driver->major=SERIAL_TTY_MAJOR;//串口设备主设备号usb_tty_driver->minor_start=0;//串口设备从设备号起始IDusb_tty_driver->type=TTY_DRIVER_TYPE_SERIAL; //设备类型usb_tty_driver->subtype=SERIAL_TYPE_NORAML; //设备子类型usb_tty_driver->flags=TTY_DREVER_REAL_RAW| TTY_DRIVER_NO_DEVFS;//设备初始化标志usb_tty_driver->init_terminos=tty_stb_termios;//串口设备描述usb_tty_driver->init_termios.c_cflag=B9600|CSB| CREAD|HUPCL|CLOCAL;//串口设备初始化参数tty_set_operations(usb_tty_driver,&serial_ops);//串口设备操作函数result=tty_register_driver(usb_tty_driver);//注册串口驱动if(result){err(“Regist tty driver failed”);goto exit_reg_driver;}result=usb_register(&usb_serial_driver);//注册USB驱动if(result<0){err(“Register driver failed”);goto exit_tty;-172-}return result;exit_generic :usb_deregister(&usb_serial_driver);//注销串口设备exit_tty:tty_unregister_driver(usb_tty_driver);//注销USB 串口设备exit_reg_driver:bus_unregister(&usb_serial_bus_type);//注销总线exit_bus:err(“Error Code:%d ”,result);put_tty_driver(usb_tty_driver);return result;}函数首先调用alloc_tty_driver ()函数分配一个串口驱动描述符;然后设置串口驱动的属性,包括驱动的主从设备号、设备类型、串口初始化参数等;串口驱动描述符设置完毕后,调用usb_register ()函数注册USB 串口设备。