USB设备开发

2024-05-25

USB设备开发(精选9篇)

USB设备开发 篇1

USB设备的开发与编程比较繁杂, 因为它涉及的方面太多, 开发者对着厚厚的USB标准、复杂的WINDDK文档及术语、各种类型的USB控制芯片不知所措。大部分的开发文档往往偏重于某一方面而忽视了整体与系统。

1 让一个USB设备正常运转需要什么

一般来说, 主机中的应用程序要与外设通信, 在通信过程中, 应用程序实际打交道的是设备的驱动程序。驱动程序将用户的各类请求翻译为IRP (I/O Request Packet, I/O请求包) 发给USB总线驱动程序。在USB设备驱动程序与USB总线驱动程序间可能还有层层的中间驱动程序。USB设备的请求最终都要与USB总线驱动程序打交道。总线驱动程序根据请求的轻重缓急, 在一帧的时间内, 安排各设备的数据包, 放在总线上。信息被按帧发送, 帧包括帧头与数据包, 数据包中包括数据地址、包类型、数据以及CRC。设备驱动程序可由系统提供, 也可由开发者提供。

2 传输与枚举

传输与枚举是USB中非常重要的两个概念。在USB中, 所有设备都挂在一个总线上, 占用一个中断。因此, 必须有一个机制, 使得USB设备在实际工作前, 主机与设备能相互沟通, 主机可以查询设备, 设备可以表明自己的身份, 或者主机与设备就未来的工作进行协商。该步骤非常关键, 只有经过这一步, 主机才知道为该设备加载何种驱动程序。该过程称为枚举。枚举成功后, 与应用有关的通信才能进行。

在枚举过程中, 主机按规定程序给设备发命令, 并提取一系列描述符。这些描述符包括设备描述符、类描述符、接口描述符等等。主机提取这些描述符的目的是:根据描述符为设备加载合适的驱动程序;或取设备的配置, 如设备属于何类, 是低速、全速还是高速, 端点的配置等。在枚举过程的末期, 主机为设备分配一个地址。

无论是枚举还是具体应用, 主机与USB设备间的通信都通过传输完成。传输是USB中另一重要概念, 是通信的基石。传输分为四类:control, bulk, is ochronous, inte rrupt。正如其名称暗示的, control传输用来完成主机与设备间控制命令与数据的传输。Control传输是最重要的传输类型, 因为其传输的内容非常关键, 且所有的USB设备都要用到。Control传输具有最高优先级, 系统为其保留带宽, 且设备必须响应。Bulk传输为批量传输, 适合大批量数据的传输, 若USB总线被占据, 该类传输将不会被执行;但总线一旦空闲, Bulk传输使用剩余的所有带宽。Bulk传输用于移动存储设备、打印机等大容量设备。Is ochronous为同步传输, 适用于实时语音、视频传输, 该类传输在固定的时间内总会有数据到来或离去。因为实时性要求, 同步传输不提供差错校验以及重传。Interrupt传输用于传输发生时刻不可预见的应用, 如键盘、游戏棒等等。由于所有的传输都由主机发起, 因此对于键盘这样的设备, 主机对该类设备实际采取的是一种轮询机制。

每个传输包括一个或多个事务, 每个事务包括1, 2或3个包。控制传输包括三个阶段:Setup, Data和Status。事务分三类:In, Out和Setup。事务分三个阶段:Token, Data, Handshake。每个事务都应不被中断地完成, 一次事务中不能有其他的通信过程。

在USB设备中, 所有流量来自或终止于设备端点。端点是USB设备存储空间中一块固定的位置, 用于存放交换的数据。端点都有端点地址, 端点地址包括端点号和方向。端点号由0到15, 方向是从主机看的IN或OUT。控制传输端点号为0, 且必须可以双向通信。主机在枚举过程中收到配置端点的端点描述符, 端点描述符包括端点地址, 传输类型, 最大数据尺寸, 以及期望的传送间隔。根据端点描述符, 主机与USB设备可以建立通信的管道。

3 主机端的软件设计及工具

在主机端, 必须提供USB应用程序及设备驱动程序。USB应用程序的编程比较简单, 调用API函数即可。而设备驱动程序的开发与编程则比较复杂和危险, 因为该程序直接和硬件打交道, 在核心态运行, 调试、查错非常困难。Hhh为了克服这个困难, 某些软件可以在较高层次上帮助开发USB驱动程序。典型的包括Compu Ware公司的DriverStudio和J ungo公司的Win Drive r。前者可以进行完整、详细的驱动程序设计, 后者则简单灵活, 是建立在“万能”驱动程序的基础上。另外, 在购买USB控制芯片和开发板时, 也会提供针对特定芯片的驱动程序开发工具, 如Cypress公司的EZ-USB系列所带的驱动程序开发工具。

4 设备固件与硬件的开发

在USB设备中, 无论固件或硬件, 都可分为两个部分:与USB协议有关的部分以及与协议无关与应用有关的部分。当USB设备插入系统后, 与协议有关的部分首先工作, 建立一个数据传送的管道, 这样在后续工作中, 与应用有关的数据通过预先建立的管道传送。

在设备的基本概念和实现方式确定后, 一个重要的问题就是USB控制器芯片的选择。USB控制器芯片完成的最基本的工作就是底层的包收发工作。控制器芯片接收总线上的包并根据包的地址判断数据包是否是发给自己的, 如果是发给自己的则接受数据包, 保存在端点里;当达到预定的长度时, 控制器芯片产生一个中断。这是USB控制器完成的最基本的功能。只完成该功能的称为USB接口芯片。其他的USB控制器不仅包括接口芯片还包括微控制器, 可以更完善地完成USB协议的功能, 并与设备应用的硬件接口。目前有许多公司生产USB控制器芯片, 如Cypress, NXP等等。在选择这些芯片时, 重要的指标有:速度、端点的数量与性质、是否有微处理器、存储器的大小。

在进行USB设备开发时, 开发板是很好的帮手。开发板提供了成熟的硬件电路, 提供了各种例子和源代码, 只要作不大的改动就能应用到自己的工程中。参考成熟的工作比从头开始容易得多。选择电路成熟、代码丰富的开发板、熟悉的开发语言将为开发工作节省不少的时间。当硬件、固件都完成后, 设备将与主机相连, 进行调试和查错。调试和查错是开发中最艰苦的一环。调试的关键在于捕捉并破译主机与设备之间的通信内容。幸好这类调试工具已被设计出来。有硬件的USB协议分析仪, 但价格昂贵;对于一般设备的调试, 有Bushound及Bus Trace工具可用, 其功能非常完善。这些软件是作为一个虚拟设备存在于系统中, 监视总线上的所有流量。

在调试过程中, 建议首先调试枚举过程。枚举过程是设备正常工作的必经之路, 枚举过程调试通过后, USB协议、硬件、固件的大部分都已可正常工作, 调试后续的设备应用程序将会很顺利。

参考文献

[1]蔡锷, 钱志博.基于USB总线的虚拟仪器技术[J].电子设计应用, 2004.

[2]王省书, 秦石乔等.通用串行总线及其应用[J].计算机应用研究, 2000.

USB设备开发 篇2

电脑故障的解决办法我们一般是是先软件后硬件等排除法,排除法在电脑故障处理中非常常用,解决问题也是先从简单再到复杂一步步去排查。这里我们介绍的usb主要以电脑周边产品为介绍,如usb鼠标,键盘,音箱等。

usb无法识别我们主要是以下几个思路出发,首先如果您是初次在一台电脑上,当出现usb无法识别的时候,我们需要做的是分析清楚到底是usb设备产品的问题还是电脑或线路的问题以及是否存在驱动问题。当以前使用过该usb设备,现在不可以用的话,驱动问题就可以简单的排除掉。

笔者公司最近有一台电脑出现了usb无法识别的故障,买的一个新的usb鼠标用了不到2个月,昨天突然在电脑中没放应了,鼠标指示灯一闪闪的,电脑桌面右小脚有提示:“无法识别的usb设备”,如下图:

无法识别的usb设备

经过检查发现usb设备接口没有问题,另外在我的电脑---属性--在设备管理发现驱动也没问题,于是编辑将usb鼠标拿到另外一台电脑中使用,发现问题依旧,由此可以大致的判断为是usb设备本身的问题,由于鼠标没使用多久,一般坏的可能性也不大,经常仔细观察鼠标线发现鼠标线中间一端有一很小部分被磨损,并且里面的线材的铜线都暴露出来了,之后笔者将磨烂的一段剪掉之后,重新接好线之后问题解决。

其实usb设备无法识别解决办法很简单,无非是围绕到底是usb设备还是电脑有问题,我们只需要使用排除法就可以简单的判断了,逐步缩小问题范围,问题就好解决的多了。

下面是保证USB设备可以正常工作的一些条件:(1)USB设备本身没有任何问题――可以通过在其它计算机上进行测试,保证能正常工作;(2)USB接口没有任何问题――可以通过连接其它的USB设备在此接口上进行测试;(3)USB设备的驱动程序已经正确安装,如果有详细说明书的USB设备,一定要仔细查看相应的说明文件,按照说明安装相应的驱动程序;目前的操作系统足以识别绝大部分的USB设备,如果是驱动问题,推荐大家使用驱动精灵去检测与安装。驱动精灵的使用方法大家可以参考下:显卡驱动怎么装? 或者 如何安装声卡驱动?里面都有比较类似的介绍。

当在别的电脑上可以用,在自己电脑上不可用也就是如果是电脑问题导致的usb无法识别,那么我们需要检测一下电脑设置等,如:

1.前置USB线接错。当主板上的USB线和机箱上的前置USB 接口对应相接时把正负接反就会发生这类故障,这也是相当危险的,因为正负接反很可能会使得USB设备烧毁。所以尽量采用机箱后置的USB接口,也少用延长线.也可能是断口有问题,换个USB端口看下.

2.USB接口电压不足,

当把移动硬盘接在前置USB口上时就有可能发生系统无法识别出设备的故障。原因是移动硬盘功率比较大要求电压相对比较严格,前置接口可能无法提供足够的电压,当然劣质的电源也可能会造成这个问题。解决方法是移动硬盘不要接在前置USB接口上,更换劣质低功率的电源或尽量使用外接电源的硬盘盒,假如有条件的话。

3.主板和系统的兼容性问题。呵呵这类故障中最著名的就是NF2主板与USB的兼容性问题。假如你是在NF2的主板上碰到这个问题的话,则可以先安装最新的nForce2专用USB2.0驱动和补丁、最新的主板补丁和操作系统补丁,还是不行的话尝试着刷新一下主板的BIOS一般都能解决。

4.系统或BIOS问题。当你在BIOS或操作系统中禁用了USB时就会发生USB设备无法在系统中识别。解决方法是开启与USB设备相关的选项。就是开机按F2或DEL键,进入BIOS,把enable usb device选择enable。

5.拔插要小心,读写时千万不可拔出,不然有可能烧毁芯片。XP中任务栏中多出USB设备的图标,打开该图标就会在列表中显示U盘设备,选择将该设备停用,然后你再拔出设备,这样会比较安全。

系统报错“无法识别的USB设备”

故障现象:使用U盘时电脑意外断电,重新开机后U盘无法正常使用,插上后系统就报错“无法识别的USB设备”。使用其他原来都能正常使用的USB接口设备,都会提示同样的错误信息。将USB设备插到电脑的其他USB接口上,都能正常工作。

分析故障:从现象上看,USB设备和主板的接口都没有损坏,怀疑是意外断电导致系统设置错误。

问题处理:从“控制面板”进入添加和删除硬件的窗口,将所有USB设备都删除,重新安装需要使用的USB设备驱动程序。重新启动电脑,U盘等USB设备插在原来的故障接口上能够正常工作。无法识别的USB设备- 笔记本硬盘故障和移动硬盘,插在前置USB接口,无法识别。

这种情况,很大原因是供电问题。由于USB硬盘在工作的时候也需要消耗一定的电能,如果直接通过USB接口来取电,很有可能出现供电不足。因此,几乎所有的移动硬盘都附带了单独的外接电源或者是通过键盘取电的PS2转接口,这时只要事先连接好外接电源或者通过PS2转接线与键盘连接好,确保给移动硬盘提供足够的电能之后再试试,这时应该可以正常使用了吧。需要特别提醒大家注意的是,建议使用移动硬盘之前都确保有足够的供电,否则很可能由于供电不足导致硬盘损坏。

对于从来没有使用过USB外接设备的朋友来说,即使正确安装了驱动程序也有可能出现系统无法检测USB硬盘的情况,这主要是由于主板默认的CMOS端口是关闭的,如果没有将其设置为开启状态,那么Windows自然无法检测到移动硬盘了。为了解决这个问题,我们可以重新开机,进入CMOS设置窗口,并且在 “PNP/PCI CONFIGURATION”栏目中将“Assign IRQ For USB”一项设置为“Enable”,这样系统就可以给USB端口分配可用的中断地址了。

USB设备接口驱动程序设计开发 篇3

1芯片概述

接口芯片与上位机通信并提供对外围CPU接口, 使得开发者无须去关心复杂的USB协议。 根据所设计产品的需求, 选择CYPRESS半导体公司的CY7C63001A USB控制器作为接口芯片。 CY7C63001A是符合低速USB低成本的一种解决方案, 它支持2个端点和1个设备地址。 CY7C63001A是一个高性能的8位RISC微控制器, 具有128字节的片内RAM, 4K字节的EPROM。 有12个通用I/O引脚[2]。

2硬件设计

该USB设备的硬件设计以CY7C63001A芯片为中心, 所连接的存储器是ATMEL公司的AT24C02, 接口兼容I2C总线规范, 通过一对串行时钟、 数据线对片内存储单元进行读写。 其电路原理图如图1所示。 按照USB规范的要求, 将微控制器第13引脚 (D-) 通过一个7.5K上拉电阻 连接到+5V的VBUS。 微控制器 第5引脚 ( P1.0) 连接24C02的第7脚 (WP, 写保护 ) , 控制24C02的写操作功能 。 WP为高电平读取24C02的内容; WP为低电平时可进行读、 写操作。 微控制器第1脚 (P0.0) 连接24C02的第6脚 (SCL, 串行时钟),为控制24C02的读写操 作提供时 钟 ; 微控制器 的第2脚 (P0.1) 接24C02的第5脚 (SDA, 串行数据 、 地址 ), 作为读写24C02的数据、 地址信号线。 微控制器通过这3根信号线完成对24C02的读写操作。

3编写驱动程序

系统内核与硬件之间设备通信要通过驱动程序, 它屏蔽了应用程序与硬件之间的细节。 Linux设备驱动分为3类: 字符设备、 网络设备与块设备。 USB设备一般都作为字符设备来进行处理, 这是是通过串行通信来读写数据, 在此所编写驱动即为字符设备驱动。 下面则结合该设备代码来介绍Linux下USB驱动的开发。

3.1注册与注销驱动

Linux下USB驱动程序在USB子系统里注册并提供一些信息。

这是USB驱动框架数据结构。 name是驱动程序模块的名字。 probe函数是在驱动向USB系统注册后当插入一个USB设备时将自动处理的函数。 disconnect函数在拔掉设备后自动运行。 fops是驱动提供的文件操作的接口结构, 通过这样注册一个file_operations函数指针, 使得可与用户空间实现方便的交互。

USB驱动程序初始化模块函数中通过调用usb_register进行注册, 传入刚才定义的驱动框架结构。

相应地在卸载模块函数中通过调用usb_unregister函数注销USB子系统。

在probe函数中, 驱动程序通常首先确认插入的设备是否可被接受, 即USB硬件的厂商号和设备号是否和驱动相匹配, 若相符则在devfs子系统中注册设备, 允许devfs用户通过fops定义的文件操作接口来访问该设备。

当拔掉USB设备时, 会调用disconnect函数, 驱动程序需要从devfs上注销。

3.2数据处理函数

当USB驱动与设备绑定好后, 任何用户 通过file_operations结构所定义的函数即可操作此设备 。

首先, open设备后即可对设备进行操作。 MODULE_INC_ USE_COUNT宏在open函数中起到计数的作用 , 计数器在用户态程序打开一个设备后就加1。 若以模块方式加入一个驱动且计数器不为零, 则说明该驱动属于使用状态, 是不可以通过rmmod命令卸载驱动模块的。

当open完设备完成后, read、 write函数就可以发送和接收数据了。

在usb_read函数中 , 我们采用 中断方式 传输 , 用FILL_INT_URB宏建立一个urb, 调用usb_submit_urb函数来提交urb。

由于设备没有中断OUT端点, 因此需要采用Set_Repor标准请求来从主机接收数据。 所以write函数没有用urb传送数据, 而是用usb_set_report函数代替, 这个函数可以发送数据给设备, 并且不需要创建urb和操作urb函数。

4结语

USB设备由于其低价和高性能 , 在近几年内得到迅速的普及。 采用CY7C63001A开发出的低速通信设备, 满足了价格和性能这两方面的要求。 已投放市场经过了实际的 检验 , 证实了该系统设计方案的可行性。

参考文献

[1]杨辉,等.数字化教学资源保护系统的设计[J].山东水利职业学院院刊,2006,(3).

[2]徐增祥.USB软件狗的设计及反破解技术[J].电子技术应用,2012,(8).

[3]罗予东.一种USB软件狗的设计及防解密研究[J].计算机时代,2009,(8).

USB设备自动移除问题 篇4

问:新买了一款MP3播放器,将MP3播放器插入电脑的USB接口后,可以正常看到一个新的移动磁盘,当我想把歌曲复制进MP3播放器时,系统提示USB设备被移除,反复换了多个USB接口、MP3播放器也更换过两个后问题依旧,但将MP3播放器插入朋友的电脑中却没有此现象,请问这是什么问题,我该怎么解决?

答:解决方法如下:首先,新安装一遍操作系统,正确安装MP3播放器的驱动程序与管理程序,如果问题依旧就不是软件故障所导致,

那么就耍考虑是否为硬件故障,很可能是由于你机器的USB接口供电不足所导致,建议购买一块PCI-USB接口卡,这样就可以直接用PCI接口取电。最后提醒一点,不要使用USB延长线或者前置USB接口,那样也很容易出现数据传输不稳定和供电不足等问题。

USB设备开发 篇5

通用串行总线(USB)是主机和外围设备之间的一种连接,它定义了一套任何特定类型的设备都可以遵循的标准,加之它具有良好的热插拔能力和较快的传输速度,因此,有越来越多的厂商的产品和设备都开始支持USB技术,使USB技术获得了广泛的应用。但Linux在硬件配置上还不能全部很好地支持USB设备,尤其是在嵌入式开发中,因此,研究USB驱动程序的结构和设备驱动程序的开发有着重要的现实意义。

1 USB接口规范及其设备驱动基础

1.1 USB总线简介

通用串行总线(USB)是主机和外围设备之间的一种连接方式,最初是为了代替一些低速总线而设计的,它以单一类型的总线连接许多不同类型的设备。它包括USB主控制器和根集线器,其中USB主控制器(host control)负责询问每一个USB设备是否有数据需要进行发送,同时提供主机与USB设备间的电气与协议互联,而根集线器则负责提供USB设备的连接点。USB接口有低速、全速和高速的数据传输三种方式。其中,前两种在USB1.1标准中予以定义,后面一种是在USB2.0中新引入的一种传输速率。

Linux内核支持两种类型的USB驱动程序:USB主机端驱动程序和USB设备端驱动程序。USB主机端驱动程序主要控制插入其中的USB设备,对其进行管理,而USB设备端驱动程序主要控制该设备如何作为一个USB设备来和主机通信。本文主要研究USB主机端驱动程序。

1.2 Linux下的设备表示和USB接口规范

1.2.1 Linux下的设备表示

Linux与windows不同,它把所有的设备都分为字符设备、块设备和网络设备等三种。确切的说,Linux操作系统是将所有的设备(而不仅是磁盘上的文件)全都都看成文件,都纳入文件系统的范畴,然后通过文件操作的界面进行操作。字符设备是指存取时没有利用缓存的设备(如鼠标、声卡等),其以字节为单位进行数据处理,通常只允许顺序访问,一般不利用缓存技术。块设备的读写则需要缓存技术来支持,它将块设备数据按可寻址的块为单位来进行处理,大多数块设备允许随机访问(如硬盘、光盘等)。传统方式的设备管理中,除了设备类型以外,Linux内核还需要一对主次设备号来唯一标示设备,主设备号(Major Number)相同的设备使用相同的驱动程序,而次设备号(Minor Number)则用来区分具体设备的实例。网络设备在Linux系统里需要做专门的处理。Linux网络系统主要是基于BSDunix的socket通信机制,Linux内核为所有与socket相关的操作提供一个统一的系统调用入口,内核中为socket设置的总入口为sys_socketcall(),其代码在net/socket.c中。

1.1.2 USB接口规范

从1994年USB实施者论坛(USB-IF)发布的USB0.7版本到现在的USB2.0和USB OTG(On-The-Go)规范,USB接口从功能上得到了不断的发展和完善。1995年底,Microsoft、Compaq等多家公司联合推出了USB OHCI(OPEN HOST CONTROL INTERFACE)标准。这是一个完全开放的规范标准,它定义了一系列的寄存器与许多相关的数据结构,用来统一USB主控制器和驱动程序接口。简单的说,操作系统只要具有USB OHCI标准规范的驱动程序,按照OHCI规范的USB主机控制器就可以应用在系统上。OHCI规范适用于USB1.1,其定义了两个主机控制器(HC)与主机控制器驱动(HCD)的通信通道,支持USB四种数据传输方式,并且根据数据传输的特点,将终端数据传输和等时数据传输归为同一类的周期性数据传输方式。

1.3 USB设备驱动基础

设备驱动程序是操作系统内核和机器硬件之间进行交互的接口,它为应用程序屏蔽了底层硬件的具体实现细节,我们开发的各种应用程序会把所有的硬件设备当作普通文件进行处理和相关操作。用户的操作通过一组标准化的调用执行,驱动程序则将这些调用映射到作用于实际硬件的设备的特有操作上,这个接口能够使驱动程序独立于内核的其他部分而建立,在必要的情况下可以在运行时“插入”内核,这种模块化的思想使我们编写Linux驱动程序时非常方便。设备驱动作为内核的一部分,它有非常重要的作用,主要完成下面一些功能:初始化系统设备;使设备进入运行状态和退出系统服务;在内核和具体设备间互相传送数据;实时检测和处理设备可能出现的各种错误。

2 USB设备驱动机制分析

在Linux环境下设计开发设备驱动程序,借助于Linux的强大功能、简单的操作和开放式源代码,可以很方便的编写设备驱动程序,但是这种驱动只能调用Linux内核所提供的函数来进行,而且涉及到和底层硬件进行交互,这样就会使系统容易崩溃,在工程实现上有很多弊端。一个完整的USB驱动程序必须要完成四方面工作:识别驱动程序所要支持的硬件设备、对USB驱动程序进行注册和注销、探测和断开及传输数据。

2.1 识别驱动程序所要支持的硬件设备

USB核心会借助一个列表来判断系统上的相关硬件设备应该使用哪一个驱动程序。这个列表是以一个结构体的形式存在的,它包含制造商的ID和设备号的ID。当我们安装硬件的制造商ID和设备号ID与所给列表信息相匹配时,硬件就可以使用这个驱动程序了。

2.2 对USB驱动程序进行注册和注销

所有的USB驱动程序在装载时都必须向USB系统进行注册,一个USB驱动程序由结构体usb_driver来描述,它会向USB核心来描述USB驱动程序,一般具有name、id_table、probe、disconnect等几个成员,来通知内核驱动程序的名称、硬件的匹配信息、标示列表以及当一个已有的匹配硬件进行连接或被移除时,应该调用系统的哪些函数。在USB驱动程序初始化和注销时,分别调用usb_register函数、usb_deregister函数来对USB驱动程序进行注册和注销。

2.3 探测和断开

当有一个USB设备连上总线时,usb_get_device_deseriptor函数会自动进行执行探测,从中取出该设备的描述符,并用结构体usb_device来保存配置和接口的相关信息。当USB系统核心确定有接口可以被该驱动程序处理时,探测函数probe会被调用。在探测函数中,USB驱动程序会调用函数usb_set_intfdata在接口中保存相应设备信息,然后再通过函数usb_register_dev在USB核心中注册硬件设备。当然,当一个USB接口从系统中被移除或者驱动程序将要从USB核心中卸载时,USB核心同样会通过断开函数disconnec来进行操作,然后,调用usb_deregister_dev函数来注销硬件设备。

2.4 传输数据

当驱动程序需要发送数据到USB设备或者要接收从USB设备发送来的数据时,通常情况下需要分配提交一个urb(Universa Request Block)来实现与设备间的数据传输。一个urb包括:USB设备信息、数据传输管道、数据传输缓冲区、数据传输缓冲区长度、回调函数、不同类型数据传输必需参数、数据传输过程控制参数等。在对urb初始化时可以指定回调函数,来报告urb传输的状态信息。考虑到内核空间与用户空间不能进行直接通信,而驱动程序和应用程序在分别从属于内核空间及用户空间,所以驱动程序就必须在内核空间分配一个缓冲区来作为中介以实现USB设备数据的读写,通过这个缓冲区,它一方面与硬件实现交互,另一方面利用函数copy_to_user或copy_from_user来实现与用户层的数据传递。

3 USB主设备驱动实现

3.1 USB驱动开发的一般流程

在嵌入式Linux系统中要实现USB主机接口,接口驱动程序需要完成三方面功能:USB主机控制器的初始化、配置USB设备并读取其信息然后给出判断、完成特定类USB类设备的操作命令。在操作系统环境下,驱动的开发相对简单一些,只需要通过对USB设备进行必要的配置,然后通过一个USB骨架就可以完成对USB驱动的开发。在Linux内核源代码driversusbusb-skeleton.c中提供了一个最为基础的USB驱动程序,我们称之为USB骨架。通过修改usb-skeleton.c,我们就可以方便地完成一个USB设备驱动的开发。Linux本身并不能支持生产厂商生产的各种各样的USB产品设备,我们要想这些USB设备正常的在Linux下工作,我们就需要为这些设备开发特定的驱动程序。开发USB驱动首先要在USB子系统中注册相关信息,然后把这些信息通过一个结构体传给USB子系统,这个结构体叫file_operations结构指针。它是设备驱动程序所提供的入口节点位置,其主要代码如下:

用户对设备进行访问时主要是通过这些函数来操作的,其含义如下:

open:打开USB设备,典型的用法为:open("devabc",flag);flag用来指定打开的参数,如可读写属性等;open函数会返回一个整数fd句柄,根据fad的值,来表示打开文件的正确与否,如果fad小于0,则表示打开错误。

read,write:设备读写函数,用法如下:read(int fd,char*bur,char lengh,……)。

ioctrl:设备控制函数,通过此函数用户可以对各类设备进行特殊控制。

一个设备驱动程序的设计开发实际上就是实现上述这四个函数和一个设备的初始化函数。这些函数在USB设备驱动程序中可以用usb_init(),usb_open(),usb_read(),usb_write(),usb_ioctrl()等来表示。最后用file_operations的结构体把用户级的open、read等函数与设备的usb_open(),usb_read()等函数联系起来,就可以实现USB设备驱动的开发。

3.2 USB驱动程序的注册和注销

一个USB设备驱动模块必须在USB子系统中注册两个入口点和名字,而对于那些特殊的USB设备则需要注册file_operations的结构体和一些次设备号。USB驱动程序首先需要向USB子系统进行登记注册,其注册结构为:

当USB设备连接到总线上被检测到时,就调用probe入口点。而设备驱动则需要为这个新的设备重新创建一个数据结构:void*probe(struct usb_device*dev,unsigned interface);当USB设备驱动程序被从USB核心移除或者设备从总线上取下时,程序需要调用另一个入口点:static void dabusb_disconnect(struct usb_device*usbdev.void*drv_context)

在probe函数里,需要找出中断读端点与中断写端点从而来建立它们之间的通信管道,并初始化dev的各成员变量,然后向系统内核注册硬件设备生成设备文件。其中需要动态分配两块内存来分别作为读操作和写操作时urb用的缓冲区:int_in_buffer及int_out_buffer,在硬件被移除或者设备驱动程序被卸载时可以调用delete函数来释放这两块缓冲区。根据设备制造商和设备号定义变量skel_table来创建匹配USB设备硬件的信息列表;定义usb_driver结构体变量skel_driver来描述设备驱动程序,并初始化其内相关成员name、id_tabe、probe、disconnect等。然后在初始化和退出函数usb_skel_init和usb_skel_exit中,通过分别调用函数usb_register和usb_deregister来实现设备注册和注销设备。

3.3 USB设备的打开和释放

当USB设备连上总线时,设备驱动程序需要调用文件操作集中的open()函数来打开设备,源代码见Linux内核目录driversusbusb-skeleton.c,主要代码如下:

当USB设备从总线上移除或设备驱动被卸载时,通过调用释放设备函数skel_release,其主要代码如下:

3.4 USB设备读数据函数

从USB设备上读取数据主要是靠读数据函数skel_read来实现,通过在内存中开辟一个缓冲区来保存设备数据,然后再把缓冲区中的数据拷贝到用户空间,从而实现设备数据读取。主要代码如下:

3.5 USB驱动程序的验证

Linux有一个很好的特性,其内核可以在运行时扩展,这就使得我们既可以把USB设备驱动直接编译到内核代码中,也可以用模块方式加载。考虑到我们调试的需要,可采用在驱动目录下,编写Make_file文件,通过make命令生成驱动模块,用insmod命令加载驱动模块的方式进行测试。以常见的USB设备u盘为例,配置好Linux内核,使其支持各种USB设备,然后通过mount命令挂载u盘,观察U盘能否成功挂接,从而判断开发的驱动正确与否。

4 结束语

功能完善的驱动是设备正常工作的前提,随着USB规范的普及和技术的提高,其传输速率越来越快,各个厂家生成的USB设备迅速增多,因此研究USB设备驱动的开发有着积极的意义。

参考文献

[1]毛德操,胡希明.Linux内核源代码情景分析[M].杭州:浙江大学出版社,2001.

[2]Jonathan Corbet,Alessandro Rubini,Greg Kroah-Hartman.Linux设备驱动程序[M].3版.魏永明,译.北京:中国电力出版社,2006.

[3]孙天泽,袁文菊,张海峰.嵌入式设计及Linux驱动开发指南——基于ARM9处理器[M].北京:电子工业出版社,2005.

[4]唐六华,王瑛.嵌入式Linux下USB主机设备驱动开发[J].计算机技术与发展,2009,19(9):182-184.

USB设备开发 篇6

USB是英文"Universal Serial Bus"的缩写,意为"通用串行总线"。是由Compaq(康柏)、DEC、IBM、Intel、NEC、微软以及Northern Telecom(北方电讯)等公司于1994年11月共同提出的,主要目的就是为了解决接口标准太多的弊端。U S B使用一个4针插头作为标准插头,并通过这个标准接头,采用菊花瓣形式把所有外设连接起来,它采用串行方式传输数据,目前最大数据传输速率为480Mbps(USB2.0标准),支持多数据流和多个设备并行操作,允许外设热插拔。

Linux以其特有的开放性、与生俱来的网络特性成为嵌入式操作系统的主流之一。它与U N I X系统兼容,开放源代码。它原本被设计为桌面系统,现在广泛应用于服务器领域。而更大的影响在于它正逐渐的应用于嵌入式设备。uClinux正是在这种氛围下产生的。

uClinux是专门针对微控制领域而设计的Linux系统,它继承了标准Linux的特点如稳定性、优异的网络性能以及众多的文件系统支持,不但如此,他还有着标准Linux不具备的特点,如完备的工具集、极小的内核、对没有M M U模块的嵌入式微处理器的支持等。[1]

本文结合基于S3C4510B的开发平台,开发并实现uClinux下的USB设备驱动。

2 开发平台简介

2.1 本文应用中所用硬件结构介绍如下

●Samsung Electronics的S3C4510B网络处理器是基于以太网应用系统的高性价比16/32位RISC微控制器,工作频率为50MHZ,最适合用于对价格及功耗敏感的应用场合。[2]

●2MB FLASH(1M X 16位);

●16MB SDRAM(2 X 4M X 16位);

●128 X 8位IIC存储器借口;

●9针D型RS-232C串行接口;

●RJ-45 10/100M以太网接口;

●2个可编程的LED指示灯;

●20针标准JTAG接口;

●系统数据总线、地址总线、控制总线扩展;

其中JTAG接口连接并口,RS-232C连接串口,RJ-45连接以太网接口。

2.2 开发平台上与S3C4510B相关部分功能框图

如图1所示:

3 uClinux的设备驱动

3.1 设备驱动程序的概念

系统调用是操作系统内核和应用程序之间的接口。驱动程序是一层抽象。它屏蔽了具体的硬件结构,把设备当作了系统中的文件,在虚拟文件系统中,甚至屏蔽掉了设备与文件的区别,这样就使得对硬件的操作与对普通文件的操作一样。设备驱动程序是构成Linux内核的主要部分,它在高特权的内核环境下运行,如果他们出错将会导致灾难性的后果。因为它们设计不合理会直接影响内核本身的稳定,一旦系统内核出现了紊乱,整个系统就可能崩溃,所以设备驱动程序的开发是设备开发的重点和难点之一。[3]

3.2 uClinux设备驱动分析

uClinux驱动程序的基本结构和标准Linux驱动程序的结构类似,但标准的Linux支持模块化(module),所以大部分的设备驱动都写成模块的形式,而且要求可以在不同的体系结构上安装。uClinux是可以支持模块功能的,在编译内核的时候可以选择支持或不支持模块功能;但嵌入式系统是针对具体应用的,一般都不需要这一功能,而且嵌入式系统中内存空间资源比较紧张,所以在编译内核的时候,一般选择不支持模块功能。这样,uClinux的驱动程序都是直接编译到内核中的。

3.3 设备驱动程序的开发思路

在系统初启或者模块加载的时候,必须将设备登记到相应的设备数组,并返回设备的主设备号,例如:对块设备来说,调用register_blkdev()函数将设备添加到数组blkdev中,并且获得该设备号,并利用这些设备号对此数组进行索引。对于字符驱动设备来说,要使用register_chrdev()函数来获得各设备的主设备号,然后对这个设备的所有调用都用这个设备号来实现。

在uClinux源代码uClinux-dist/linux-2.4.x/include/linux/fs.h中,定义了uClinux驱动程序中必须使用file_openrations结构。[4]

该结构包含一系列函数指针,这些函数指针指向对设备的各种操作。常用的操作包括以下几种:

lseek:改变当前的读写指针。

read:从设备中读取数据。

write:向设备中写数据。

readdir:读目录,一般用于文件系统的操作。

select:用于查询设备是否可读、可写或处于特殊的状态。

ioctl:执行设备专有的命令。

mmap:将设备内存映射到应用程序的进程地址空间。

open:打开设备。

release:关闭设备。

对于每一个驱动函数来说,都有一些和设备密切相关的功能函数,都存在着诸如open()、read()、write()这一类的操作。用户进程是通过设备文件同硬件打交道,对设备文件的操作方式也就是一些系统调用。而这个结构的每一个成员的名字都对应着一个系统调用,用户进程利用系统调用在对设备文件进行诸如读/写操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。正是基于这样的原理,该数据结构将系统调用和驱动程序紧密地关联在了一起。

因此我们所要做的开发设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。

开发过程中需要注意的几个问题:

(1)该结构和源代码版本是相关的。新的版本可能包含更多的项,所以在初始化自己的file_operations结构的时候,要注意查看自己所使用的源代码,按照源代码中的定义对该结构的定义来初始化。

(2)和硬件打交道离不开I/O Port,在linux下操作系统没有对I/O口屏蔽,也就是说,任何驱动程序都可对任意的I/O口操作,这样就很容易引起混乱,每个驱动程序应该自己避免误用端口。在Samsung S3C4510B中,寄存器与内存一起编址,I/O端口被映射到一段内存中,要访问这些端口就相当于访问一段内存。

(3)中断处理同处理I/O端口一样,要使用一个中断,必须先向系统登记。如果登记成功,返回0,这时在/proc/interrupts文件中可以看请求的中断。

3.4 将设备驱动添加到uClinux内核中

设备驱动程序开发完后,下面就该将设备驱动程序添加到uClinux内核中。这需要修改uClinux内核的源代码,然后重新编译uClinux内核。

(1)将设备驱动程序文件(比如adddriver.c)复制到/u Clinux-dist/linux-2.4.x/drivers/char目录下。该目录保存了uClinux字符设备的驱动程序。

修改该目录下的mem.c文件,在int chr_dev_init()函数中增加如下代码:

其中CONFIG_MYDRIVER是在配置uClinux内核时赋值的。

(2)在/uClinux-2.4.x/drivers/char目录下Makefile中增加如下代码:

如果在配置uClinux内核的时候选择了支持我们定义的设备,则在编译内核的时候会编译adddriver.c,生成adddriver.o文件。

(3)修改/uClinux-dist/linux-2.4.x/arch/m68knommu目录下config.in文件。在c o m m e n t‘Character devices’语句下面加上

这样,在编译内核过程中运行make config、make menuconfig或make xconfig的时候,在配置字符设备时就会有选项

support for adddriver

当选中这个选项的时候,设备驱动就加到内核中去了。

(4)在romfs中加上设备驱动程序对应的设备文件。设备文件都被包含在/dev目录下。uClinux内核中使用的根文件系统是romfs文件系统。这个文件系统是一个只读文件系统,所以设备文件必须在编译内核的时候加到romfs文件系统的image中。

不同的硬件文件系统对应不同的设备文件,在/uClinux-dist/vendors目录下,分别定义了它们的Makefile文件。以本开发平台为例,使用基于S3C4510B的硬件环境,在uClinux-dist/vendors/SamSung/4510B目录下找到它的Makefile文件,并找到

再加上设备项就行了。其中每一项第一个参数为设备名字,第二个参数为设备类型(c表示字符设备,b表示块设备),第三和第四个参数分别是主设备号和次设备号。

(5)重新编译内核,在shell中将当前目录cp到uClinux-dist目录下,然后:

在配置选项的时候,要注意选择支持添加的设备。这样得到的内核就包括设备驱动程序了。

3.5 在应用程序中使用设备

uClinux通过设备文件来提供应用程序和设备驱动的接口。应用程序通过调用标准的文件操作函数来打开、关闭、读取和控制设备。查看uClinux文件系统下的/proc/devices,可以看到当前的设备信息。如果设备驱动程序被成功地加进来,这里应该有设备对应的项:/proc/interrupts记录了当时中断情况,可以用来查看中断申请是否正常;DMA、I/O口的使用,在/proc下都有相应的文件做记录;还可以在设备驱动程序中申请在/proc文件系统下创建一个文件,该文件用来存放设备相关的信息,这样通过查看该文件就可以了解设备的使用情况。总之,/proc文件系统为我们提供了查看设备状况的途径。

4 结束语

本文深入探讨了开发驱动程序中所必须使用的file_openrations结构,实现了uClinux下USB设备驱动的添加与使用。目前U S B接口虽然只发展了2代(USB1.0/1.1,USB2.0),但是USB综合了一个多平台标准的所有优点,包括降低成本,增加兼容性,可连接大量的外部设备,融合先进的功能和品质。使其逐步成为P C接口标准,进入了高速发展期。今后对U S B设备驱动的需求也必将越来越多。

摘要:本文以USB总线的通用性及Linux的开放性为背景,结合特定的基于S3C4510B的硬件开发平台,介绍了设备驱动的概念,提出了uClinux下设备驱动程序开发的主要思路,以解决uClinux下的USB设备驱动的实现问题。

关键词:USB,uClinux,设备驱动

参考文献

[1]罗嘉等.uClinux上的应用程序设计[J].单片机与嵌入式系统应用.2002,(12):26-28.

[2]SAMSUNG ELECTRONICS.Samsung s3c4510x16/32bit risc microcontroller reference[Z].1999,6

[3]林鸿骥.基于uClinux的USB主机端设计与实现[D].2004.

如何检测USB设备 篇7

关键词:USB设备,U盘,WndProcHooker,WndProc

我们在工作生活中常常会用到USB设备,常见的比如说U盘,移动硬盘,数码像机,MP3等等。那如何在程序中知道,这些USB设备是否下在与本地计算机相连接呢?能不能捕捉到USB设备在本地计算机上拔插的消息呢?

众所周知,Windows操作系统是消息驱动的,例如用户移动一个窗体,Windows操作系统会生成一个消息,移动的窗体则会在消息队列中取出这则消息,触发Move事件。

我们在NET环境里编写程序时,也是基于消息驱动,即所说的事件驱动。比如我们在编程一个按钮的代码,常常用到就是生成它的单击事件,在单击事件函数内编写按钮的代码。同理,当一个USB设备在本地计算机上拔插的时候,Windows操作系统也会生成一个消息,只要我们能够捕捉到这则消息,就可以获得拔插的USB设备消息。

在NET环境里可以使用Wnd Proc Hooker类来获得Windows的消息。在通过Pre Process Message方法筛选之后,所有消息都发送到窗体的Wnd Proc方法。

Wnd Proc的方法在系统中定义如下:

上面用到的“WM_DEVICECHANGE”变量,是根据“winuser.h”的内容定义的一个消息返回值,定义内容如下:

internal const int WM_DEVICECHANGE=0x0219;

这个十六进制的数值对应的就是本地计算机上拔插USB设备时产生的消息返回值。

参数“ref Message m”的Message结构包装Windows发送的消息。可使用该结构包装消息,并将其分配给窗口过程以进行调度。还可使用该结构获取系统向应用程序或控件发送的关于某个消息的信息。

但不能直接创建Message。而应该使用Create方法。为提高效率,Message尽量使用其

Message池中的结构,而不是实例化新的结构。但是,如果池中没有任何Message,则会实例化一个新的结构。

“_loading”是设定的一个布尔变量,只是为了在执行Load Items()后,不再重复此动作,它的初始值为“False”,在函数Load Items()中设置成“True”。

函数“Load Items”函数的作用是检查所接设备是不是U盘,如果是的话在文本框内显示出它的盘符。其内容如下:

在上述的函数中,m.WParam此字段的值取决于消息。使用WParam字段可获取消息处理所需的重要信息。此字段通常用于存储小段信息,如标志。重写Wnd Proc方法以处理Message中标识的操作系统消息。该示例处理WM_ACTIVATEAPP操作系统消息以了解另一个应用程序什么时候激活。若要了解可用的Message Msg、Message LParam和Message WParam值,请参见位于MSDN Library中的Platform SDK文档参考。在Platform SDK(“Core SDK”部分)下载中包含的windows.h头文件中,可以找到实际常数值,该文件也可在MSDN上找到。(我是在本地文件的dbt.h文件中找到的这些消息返回值的定义,这个文件在Windows.h中用引用)。

USB设备开发 篇8

目前,随着我国老龄化程度加深,听力损伤呈多发态势,听力障碍人群不断扩大[1]。在我国已经开展了新生儿的听力筛查[2],但对于成年人和老年人的听力筛查还处于空白阶段,致使很多听障人群不能够及时发觉听力损伤,得不到行之有效的干预措施。

听力障碍评价系统是利用计算机广为普及的优势而开发的集筛查、诊断、验配及康复训练于一体的大型软硬件系统。

听力筛查设备是为这个系统开发的一个具备USB总线接口的音频发声设备。相较于其他音频设备[3],这个设备具有更大的驱动能力、更精细的声压级控制精度和更宽的动态范围。

2 总体结构介绍

上位机应用软件能够通过本设备驱动程序提供的函数接口将左右声道的24位音频数据通过USB电缆发送到设备中的接口芯片,然后被FPGA读取并在FPGA内部将24位数据转换为音频DAC所支持的IIS数据格式。同时,上位机应用软件还能够通过USB总线向设备发送声压级调整等指令,设备中的DSP对指令进行解析,然后将相关调整数据和寄存器地址写入SPI接口模块的寄存器中,进而由SPI模块配置进DAC中,完成对输出声压级的调整[4],如图1。

DAC转换输出的是电流信号,经过I/V变换电路转变成电压信号,然后送入调理电路进行滤波和平衡转非平衡变换,最后对信号进行功率放大推动耳机。本设备还具备多种接口,既能够通过立体声接口推动普通耳机也能够通过专用接口推动听力计专用耳机HDA200R,这两种情况应用于听力的筛查诊断;还能够通过RCA连接线与功率放大器相连,进而推动高品质的无源音箱,这种情况应用在康复训练当中,如图1。

设备中,模拟电路中的音频DAC转换芯片选用TI的PCM1792;I/V变换电路和平衡转非平衡电路中的运放选用了TI的NE5534音频运放;功率放大电路选用TI的A类电流型功率放大器TPA6120A2。在数字电路部分,FPGA选用EP2C8Q208;DSP选用TMS320LF2407;U S B接口芯片选用C Y 7 C 6 8 0 1 3;E E P R O M选用AT24C08;时钟芯片选用PLL1700等。下面按照先模拟后数字再软件的顺序介绍整个设计过程。

3 模拟电路设计

模拟电路驱动耳机时能够产生高达120dB、小到接近于0dB的声压级动态范围[5],并且具有0.5dB调整步长。

本设计中模拟电路分为三级,如图2。在第一级(转换级),DAC输出的电流信号经过两个电阻转变为电压信号。在第二级(调理级),通过一个差分比例运算电路将平衡输入信号转换成非平衡输出信号,同时加入的电容构成了低通滤波器,用于滤除高频噪声。在第三级(功率级),由于要尽量减少纯音信号谐波分量,采用A类放大器,同时考虑较大的功率需求所以采用了电流型功放。

作为听力筛查使用的音频设备与普通音频设备相比要求具有更大的动态范围和更小的噪声级别。参照如下经验公式:

其中,L0为耳机的灵敏度,P为输入功率,Lx为产生的声压级,结合HDA200R参数可推出输出声压级为120dB时P=100mW。而功放芯片TPA6120A2具有左右声道各750mW的输出功率,满足驱动该耳机的需求。同时,根据NE5534和TPA6120A2参数,输出频率为1KHz时输出噪声功率为

产生的噪声声压级为2dB,几乎达到人耳可闻最小声音的极限。所以本设计方案可以达到很宽的输出声压级动态范围,可以满足听力筛查的应用要求。

4 数字逻辑设计

4.1 USB固件及其接口逻辑设计

上位机向设备发送的数据是通过USB接口进行传输的。设计中使用的EZ-USB接口芯片内部集成了增强型8051,需要编写相应的固件程序并加载才可运行[4]。为简化固件程序设计,设计中采用了Slave FIFO接口模式,这就要求在FPGA内要编写相应接口逻辑。

4.1.1 EZ-USB固件程序设计

固件程序中,端点2用于传输24位音频数据流,配置为同步传输(Iso)、自动输出方式,以满足对数据传输同步性的要求。端点8用于传输声压级调整等指令,配置为块传输(Bulk)、自动输出方式,通过对所传数据进行校验来保证指令传输的准确性。

4.1.2 USB接口逻辑设计

对于端点2,由于D A C的转换位数为2 4位,E Z-USB接口FIFO的数据宽度设为8位,同时为协调左右声道,定义了如图3的数据帧格式。接收从帧头(Header)开始,连续8个字节。帧头(Header)定义为0x55,用于当发生数据丢失、错位等情况时自动恢复正确数据格式。设计中提供一个稳定同步时钟(SYNC)实现同步数据传输,其上升沿触发一次数据帧读取操作。

对于端点8,在读取两个字节长的指令后,接口逻辑会产生一个中断提供给内嵌的mc8051处理器进行分析和处理。为防止与端点2冲突,该端点数据只能在同步时钟下降沿处读取。

4.2 WishBone总线设计

在本设计中,为了降低片上系统各功能模块的耦合性,采用了以开源组织OpenCores维护的WishBone接口协议为基础的总线结构。为每一个功能模块都编写一个WishBone接口逻辑,这样不同的模块具有了相同的接口都可以挂接在总线上,如图1。DSP要想控制相关功能模块,就可以通过WishBone总线的主接口来读写地址线指定模块的控制寄存器来实现对功能模块的控制,而不影响其他模块,如图5。

4.3 功能模块设计

这些功能模块都是在FPGA中设计实现的,主要用于完成各种接口时序的转换。

IIC模块。该模块主要用于配置EZ-USB工作所需要的EEPROM中的内容,将VID、PID等USB枚举所要用到的信息写入EEPROM中。

SPI模块。该模块主要用于对PCM1792中的寄存器进行配置,可以实现对声压级衰减量值、音频数据格式、静音等的设置。

IIS模块。该模块用于将传入的24位音频数据转换成符合I I S片上音频数据格式的串行数据并送入PCM1792中。

5 软件设计

5.1 DSP程序设计

DSP中运行的程序主要用于设备上电时所有寄存器的初始化,使设备进入正常工作状态;在设备与上位机通过USB相连时建立有效的数据传输通道;对上位机传入的指令进行解析并配置相关寄存器,执行相应操作,如图6:

5.2 驱动程序设计

本设计的驱动程序以EZ-USB提供的驱动程序为基础,根据设计需求对inf文件进行了修改。驱动程序分为固件下载驱动程序和固件运行驱动程序。固件下载驱动程序负责加载编写的EZ-USB片上固件程序;固件运行驱动程序为上位机的系统软件提供了应用程序接口,主要包括端点2同步传输接口函数和端点8批量传输接口函数。

6 结束语

本文介绍了一种基于USB总线的听力障碍筛查设备的设计方法。在硬件方面,实现了音频数据和控制指令的USB传输以及相应指令的解析和处理;采用总线形式的片上组织方式,结构清晰,耦合性低。在软件方面,设计了固件加载驱动程序和固件运行驱动程序,完成了固件加载和提供函数接口的功能;设计了mc8051程序用于命令的解析和执行。目前该设备已调试成功工作稳定。

参考文献

[1]于丽玫等.全国老年听力残疾人群现状调查研究[J].中国听力语言康复科学杂志,2008,(3):63-65.

[2]陈贤明,新生儿听力筛查[J].福州总医院学报,2004(11):301-303.

[3]吴君钦,USB音频设备的设计与实现[G].PLC技术应用200例,2007:308-309.

[4]李莹.纯音听力计的设计与实现[D].北京交通大学硕士学位论文,2007,12:4-30.

[5]章句才,邱建华.GB/T 7341.1听力计第一部分:纯音听力计[G].中国计量科学院,1998:4-16.

USB设备开发 篇9

任何一个嵌入式系统的正常运行都需要软件和硬件协作,设备驱动就是连接它们的纽带,它的作用是驱动底层硬件工作。USB: 通用串行总线,是一种外部总线的标准,用于规范主机与外设之间的连接与通讯,其数据传输速度快,支持热插拔,并具有兼容性和透明性,已成为当今个人电脑和大量智能设备必配的接口。但在桌面云系统中,由于受限于现有的共享技术对于操作系统上层抽象接口的共享, 云端虚拟桌面无法识别插在云客户端的USB设备, 或即使可以识别也只能进行简单读写操作,而无法对其完成格式化或者重新分区等更底层的操作,给用户的工作和生活带来不便。所以文中提出了一种基于IP虚拟网络扩展外围总线的USB设备重定向方案。

1云端虚拟桌面

云计算代表了以虚拟化技术为核心、以低成本为目标的动态可扩展网络应用基础设施,是近年来最有代表性的网络计算技术与模式[1]。云端虚拟桌面是云计算的一种典型应用。用户只需要一个瘦客户端或者一个浏览器,与网络相连就可以访问跨平台的应用程序[2]。整个桌面,运行的桌面环境和相关数据、运算都由云端资源虚拟实现,用户体验和人们使用传统的个人电脑是一模一样的。

虽然基于云的虚拟桌面系统发展十分迅速,国内外各大公司的产品也相继面世,但是,云端桌面在识别和使用插在云客户端的USB设备时还存在明显的不足。受限于局域网的设备共享技术是对操作系统上层抽象接口的共享,云端桌面只能通过调用这些上层抽象接口访问云终端的USB设备,而无法共享更底层的操作,导致云端桌面无法访问许多USB设备的特性。

2USB设备驱动模型

2.1设备驱动模型的变迁

随着新特性外围设备的 不断出现,如USB、 IEEE1394这样的智能外围总线,使得传统设备共享机制无法共享新设备的特性。现在的设备驱动主要用于实现操作系统与本地设备之间的数据传输和通信,其中操作系统负责设备的动态配置。图1为设备驱动框架演变过程的示意图( 左: 传统的设备驱动,中: 现在的驱动框架,右: 虚拟的设备驱动框架)[3]。

文中提出的USB设备重定向机制是通过在IP网络中拓展外围总线驱动为虚拟总线驱动来实现的。虚拟总线驱动提供访问远程重定向设备的接口,它封装外围总线请求命令为IP包并且通过网络传输。

2.2USB设备驱动模型

USB作为当前最流行的一种外围接口,提供了串行I/O,热插拔和通用连接等特性。USB设备驱动模型主要包括USB对应设备驱动、USB核心驱动、USB主控制器驱动。最底层的操作粒度最小,底层每一个 操作的数 据大小和 时间限制 都小于上层[4]。

( 1) USB对应设备驱动( USB PDD) ,用于控制单个的USB设备。当应用程序或者别的设备驱动向USB设备发出I/O请求时,USB PDDs将I/O请求转换成一系列URB命令,并将它们以URBs的形式提交给USB核心驱动。一个USB PDD仅使用一个设备地址、一个结点地址、一个I/O缓冲器和一些在设备交互中对于转化类型所必需的额外信息。 USB PDDs不需要与硬件接口和主控制器寄存器交互,也不需要修改IRQ( Interrupt Request) 表。

( 2) USB核心驱动( USB Core Driver) ,用于动态配置和管理USB设备。当一个新的USB设备插入总线后,USB核心驱动将这些设备列举出来,并给设备配置合适的USB PPD。USB核心驱动还给上层USB PDDs和下层的USB HCD提供一组通用接口。

( 3) USB主控制器驱动( USB HCD) ,管理主机与USB设备间的数据传输。USB HCD接收USB核心驱动传来的URB请求包,然后将其分解为更小的请求包,我们称之为传输描述符号( Transfer Descriptors,TDs) ,用于与USB微帧( 同步传输机制中,最短的I/O处理间隔是125μs,称其为微帧) 之间进行通信。TDs的调度依赖于它们的传输类型,通过与USB HCD中合适的帧列表连接进行传输,在同步或者中断传输类型下与周期帧列表连接,在块和控制传输类型下与异步帧列表连接。

3USB设备重定向的设计及实现

3.1桌面云USB设备重定向的设计与实现

USB设备重定向方案主要分为两部分: 云端虚拟桌面和云客户端。只要系统权限允许,云端虚拟桌面就可以访问和控制插在云客户端上的USB设备。 图2为云端虚拟桌面和云客户端连接过程示意图。

图3为USB重定向的实现原理图。在云端桌面增加了与USB HCD功能类似的虚拟主控制接口驱动( VHCI) ,VHCI将URBs转换为USB设备重定向请求块,并且传给远程的云终端。云终端增加了与USB PDDs功能类似的虚拟设备驱动( Stub Driver) ,Stub Driver用于解码从远程机器传进来的USB设备重定向包,从中提取URBs,然后将其提交给本地USB设备。

当插有USB设备的云终端通过IP网络与云端桌面主机相连时,云端桌面的VHCI驱动通知USB Core Driver相关端口的变化,USB Core Driver根据接收到的USB设备信息在USB PDDs上映射出一个相应的USB设备,并加载对应的设备驱动。

云端桌面应用程序对USB设备进行访问操作时,USB PDDs将应用程序发来的I/O操作请求封装成URBs,通过调用函数usb_submit_urb( struct * urb,. . ) 向底层传 递URBs。 usb _ submit _ urb ( struct * urb,. . ) 调用VHCI Driver的urb_enqueue ( struct * urb,. . ) 将URBs转换成Submit PDU( Protocol Data Unit) ( 如表1所示) ,并通过IP网络发送到云终端[5]。云终端上的Stub Driver接收云端桌面发送来的Submit PDU,并从此数据包中解析出新的URBs,通过调用usb_submit_urb( ) 函数将这些URBs传递给USB HCD,USB HCD将URBs转换成一系列具体的传输描述符( TDs) ,这些TDs对应于实际的USB处理帧,最后由主机控制器芯片完成USB设备的I / O操作。

云终端USB设备的I/O操作完成之后,USB HCD将返回的URBs数据包通过USB Core Driver传输给Stub Driver,Stub Driver分析URBs数据包并建立一个相应的Return PDU( 见表1) ,它包含设备的I/O状态和输入数据,然后通过IP网络将其传输给VHCI。 VHCI将接收到Return PDU转换成URBs,通过USB Core Driver传给USB PDDs,这样云端桌面应用程序完成了对重定向USB设备的访问。

系统使用TCP协议在IP网络中传输PDUs包, TCP / IP的建立在用户空间应用程序中实现,传输给VHCI和Stub Driver的socket描述符通过 / proc文件系统的接口实现。USB设备重定向机制中网络通信的实现不采用UDP,因为USB和UDP/IP传输错误的特性不同。

3.2实验方案的验证

将具体通过实验来描述USB设备重定向方案。 图4为一个简单的桌面云系统架构图。通过瘦客户机、普通PC或者其它与网络连接的移动设备,访问跨平台的应用程序或者虚拟机桌面,得到与传统个人PC机相同的用户体验。实验基于VDI来构建桌面架构。主要由三类核心组件构成,虚拟化服务器、 虚拟桌面实例和connection Broker组件构成。其中,Hypervisor是所有主流虚拟化技术的核心,利用它可以在云端服务器侧为每个用户准备其专用的虚拟桌面,云端管理员为每个用户部署所需的操作系统和各种应用。用户通过桌面显示协议访问完整的虚拟桌面。

图5搭建了USB设备重定向方案的实验环境, 云终端和云端桌面的机器配置如下: 云终端采用主频为600MHz - 1GHz,内存为312M的处理器三星S5PV210 ( ARM Cortex - A8 ) ,操作系统为Debian ( kernel linux 2. 6. 35. 7) ; 实验中的虚拟桌面系统有两种,一种主频为2. 26GHz,内存为1G,处理器为QEMU Virtual CPU ( cpu64 - rhel6) 的Linux操作系统,另一种为相同配置的Windows 7系统。云终端访问云端桌面的桌面显示协议采用开源的spice[6]。云终端待测试的USB设备选用台电骑士U盘,容量为8G,接口标准为USB3. 0,同时兼容USB2. 0,测试结果如图6所示。

3.3结果及讨论

实验表明,在基于云的虚拟桌面系统中,通过IP网络拓展外围总线的USB设备重定向的方案是可行的。实验中,重定向USB设备的所有功能支持不同的操作系统,如Linux操作系统和Windows 7操作系统可以通过该机制实现USB设备的重定向,重定向之后的设备I/O访问稳定。

当然,这一方案仍然存在一些不足。第一,重定向之后的设备不允许同步访问,因为设备的重定向是在操作系统底层完成的,设备的原始功能被重定向了。第二,USB设备重定向方案受网络干扰严重, 诸如网络延迟或者不稳定等因素会显著影响重定向设备的使用。第三,目前该方案仅仅在局域网络中取得了不错的用户体验。

4结束语

上一篇:深度模式下一篇:支架冲压工艺