基于Linux的USB主从设备之间的三种通信方式

上传人:gg****m 文档编号:204991079 上传时间:2021-10-27 格式:DOC 页数:4 大小:66KB
返回 下载 相关 举报
基于Linux的USB主从设备之间的三种通信方式_第1页
第1页 / 共4页
基于Linux的USB主从设备之间的三种通信方式_第2页
第2页 / 共4页
基于Linux的USB主从设备之间的三种通信方式_第3页
第3页 / 共4页
基于Linux的USB主从设备之间的三种通信方式_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《基于Linux的USB主从设备之间的三种通信方式》由会员分享,可在线阅读,更多相关《基于Linux的USB主从设备之间的三种通信方式(4页珍藏版)》请在金锄头文库上搜索。

1、随着简单易用的USB接曰廿益流行,在嵌入式系统中添加对USB接曰的支持已成为大势 所趋。木文通过介绍Linux中支持USB的各种模块和库,分析了在Linux上利用USB实现 高速串曰和以太网连接等通信方式的具体方法。通用串行总(USB,Universal Serial Bus)是一种非常实用的通信接口,其应用日益广泛。有三种方法可 以使运行Linux操作系统的嵌入式系统支持USB接口,本文将对这三种方法逐一进行介绍。基于Linux的USB设备与USB主机一般有以下三种通信方式:1. 一些功能最完备结构也最复杂的设备采 用用户定制内核模块来实现在标准USB总线上运行复杂的高级协议,而由USB主机

2、上相应的用户驱动程 序和应用来完成连接。2.另一些基于Linux的USB设备则利用USB总线来实现与主机上所运行的某个应 用的简单的点对点串行连接。主机上的应用虽然利用了主操作系统所提供的USB编程接I I,但表面看来却 似乎是在通过一个典型的串口进行通信。3.最后,还有些设备以主计算机作为网关,将USB设备连接到 办公局域网或互联网上,从而使USB设备看起仿佛构成了一个以太网。这种方法专业性较强,但通常可行, 是主机驱动程序使该方法成为可能。在这三种方法中,您可以根据预留给开发的时间长短和期望USB接I I在嵌入式应用中所扮演的角色来决定 选用那一种方法比较恰当。为了帮助您做出正确的选择,下

3、一节将向您介绍这三种方法分别应用于基于 Linux的USB设备时的情况,但首先让我们对USB接口做一个大致介绍。USB概述USB是一种方便快捷的接I I,可用于为计算机工作站连接一些小配件。根据USB规范的定义,鼠标、键 盘、音频播放和录音设备、照相机、大容量存储设备以及许多其他设备均可以通过USB接口,以高达 480Mbps的速度迎接到一台主计算机。协议定制者对USB上运行的这种复杂的主从式协议做出了仔细的 说明,这就帮助保证了所有这些设备之间具备互操作性和兼容性。例如,该协议规定,USB设备只有在被 询问时才可以回答,并且USB主机会根据所连接的USB设备类型的不同,采用某些特定的格式,在

4、某些 特定的时间段从不同的设备获取数据。USB设备和主机之间通常通过专用的总线控制芯片建立连接。在USB主机上,名为UHCI或OHCI等的 控制芯片通过插卡形式加入主机或直接集成到工作站的主板上。在主机一端的总统控制驱动程序管理着主 机控制芯片,它同时还跟踪监视着主机目前连接的是哪些USB设备,从而决定应如何与它们通信。可-用于连接照相机和鼠标之类USB设备的总线控制器有很多种。其中的一种就在一块芯片上同时集成了 USB接I I以及另一端的串I I、FC接口或并口。USB控制器(包括主机上的和USB设备上的控制器)也可能 集成到英特尔StrongARM或Hitachi H8之类的微控制器中去。

5、这些芯片及其外围部件有点类似以太网和 CAN控制器,不同的是他们用于连接USB设备,并运行USB协议。很多人都知道Linux操作系统中包含了 USB主机控制器的驱动程序,因而USB键盘、数码相机以及其他 一些USB设 备都可以在一个运行Linux操作系统的桌面工作站上使用。但很少有人知道Linux中还包含 了一组USB设备控制器的驱动程序,尤其是集成到StrongARM SA1110处理器中的控制器。有了这些控 制器驱动程序,基于Linux的嵌入式系统就能利用USB接曰来与主计算机(运行Linux或其他操作系统)通 信。大多数USB通信的实现过程都是双端的。主机利用一个内核模块或驭动程序来与U

6、SB设备通信,而 USB设备则通过其自身的驱动程序来与主机通信。根据主机和USB设备所采用的通信风格的不同,骚动 程序可以很简单明白,也可以很复杂,很具挑战性。本文主要关注USB设备端的通信过程,但也在适当的 地方包含了关于主机端通信过程实现的信息。以下讨论的技术应当引起读者的注意。本文的H的是介绍如何在数码相机和PDA等基于Linux的USB设 备上使用Linux.此处所指的USB设备是严格意义上的USB设备,即带正方形连接器的完整的设备,而 不是哪些连接器形状为扁平矩形的设备。此外,USB连接的另一端(通常是一台PCT作站),应该是一台 USB主机。关于USB信息包的格式和通信参数的详细信

7、息,见本文的参考文献。通过编写内核模块添加USB接口1. USB设备端通信过程向一个基于Linux的设备中添加USB接口的第一种方法是编写一个用户定制的Linux内核模块,这也是可 实现最完备功能的一种做法。采用这种方法时通常需要针对主机的操作系统(Windows, Linux等)开发相应 的驱动程序。一旦在设备中实现了用户定制的内核模块,就可以使该设备完成相当复杂的功能,例如仿真一个文件系统, 从而允许嵌入式应用将其USB主机当作一个远程存储设备。除此以外,采用这种方法之后,设备还可以具 备存储转发(store-and-forward)的功能,因而能够在与USB主机的连接建立之前对来自嵌入式

8、应用的数据 流进行缓冲。在基于StrongARM的Linux设备中,内核代码用于管理芯片所携带的USB设备控制器外设,通过调用函 数sa1100_usb_open()来初始化。在初始化之后,内核模块还会调用函数sal 100_usb_get_descriptor_ptr() 和sal 100_usb_set_string_descriptor()来设置在设备查洵期间传送给USB主机的描述符,其中包含设备 的数字厂商号和产品标识符,以及可以让主机用来识别设备的字符串,甚至还有一个序列号域,以便主机 可以唯一地识别一个连接在USB接口上的设备,或者在同种型号的多个设备中进行区分。设备查询过程是山U

9、SB设备控制器驭动的,并且一旦和USB主机连上之后会自动执行,所以内核模块必 须在USB通信开始之前设置好每个设备的描述符。当准备工作就绪之后,USB设备模块就会调用函数 sa1100_usb_start()来通知内核接收主机发来的USB连接请求。如果设备模块在连上USB主机之前调用 了函数sal 100_set_configured_callback(),那么接若内核模块就会在查询过程结束时调用p调函数。Pl调 函数很适合用来在设备上发出警告或给出一些形象的暗示,说明连接已经建立。如果不再需要进行USB通信,那么设备的内核模块就会先调用函数sa1100_usb_stop(),然后调用sal

10、100_usb_close(),来关闭 SA1100 上的 USB 控制器。StrongARM的USB控制器支持bulk-in和bulk-out两种数据传送方式。当接收来自USB主机的数据包时, 内核模块会调用sa1100_usb_recv(),将一个数据缓冲区的地址和一个Pl调函数送给它。然后内核中的USB 设备控制代码会从主机取回一个bulk-out数据包,将其内容存入制定的缓冲区,接着调用回调函数。下一步,回调函数从接收缓冲区中提取出数据,将其存放到其他地方,或者将缓冲区空间添加到一个队列 中,然后分配一个新的缓冲区来接收卜一个数据包。然后,如果还有数据需要接收,那么FI调函数会重新 调

11、用sa1100_usb_recv(),准备接收另一个数据包。向USB主机发送数据的过程与此类似。内核模块收集了一帧数据之后,将数据的存放地址、数据长度和 叵I调函数的地址送给sa1100_usb_send()函数。接着,在数据传送结束之后,内核模块会调用叵I调函数。 在 uf 以找到一个叫做 usb-char 的模 块,这是一个很好的设备端SA1110 Linux USB模块的例子。该模块将USB设备与USB主机之间的连接 变成一种高速串行链接。此外,usb-eth(arch/arm/mach-sa1100/usb-eth.c)模块也是个不错的例,该模 块将USB变成了一种虚拟的以太型网络。后

12、面会深入探讨这两种模块。2. USB主机端通信过程有些很好的主机端USB驭动程序的例子是随主流Linux操作系统的发布而提供的,位于The Linux Kernel Archives (kernel.org)发布的原始内核源代码中。其中,Handspring Visor 模块(drivers/usb/serial/visor.c) 是一个编写得更清晰,也更易理解的模块,它同时也是USB主机端模块(drivers/usb/usb-skeleton.c)的模 板。利用USB实现高速串行通信1. USB设备端通信过程为了达到最实用的效果,我们可以将USB总线简单地看作一个高速串口,然后,在一些嵌入式

13、设备和应用 中,我们就可以用USB接I I来模拟串口。StrongARM处理器的Linux内核就提供了一个名为usb-char的 USB设备驱动程序,它所完成的恰好就是用USB模拟串口的功能。当需要与USB主机通信时,Linux操作系统中的USB设备应用只是简单地打开一个与其usb-char设备节 点的连接(连接类型为字符型,major number为10, minor为240),然后就开始读写数据。在与USB主 机的连接建立之前,read。和write。操作均返个错误信息。一旦连接建立好,并且设备查询完成之后, USB接口就开始象一个点对点的串口一样与主机进行通信。这种进行USB数据传送的方

14、法非常简单有效,因而usb-char设备模块发布之后一直很受欢迎。而且,该 模块还为通过其他方法进行USB通信提供了一个参考。在usb-char中,真正的操作开始于usbc_open()函数,列表1给出了函数的一部分代码。笔者由于临时的 兴趣,对该代码做了一点修改,取消了错误和超时句柄。在此向代码的原作者Brad Parker、Nicolas Pitre 和 Ward Willats 致歉。twiddle_descriptors()函数用于设置设备的USB描述符。在描述符设置好之后,我们就可以开始进行设备 查询,并从USB主机接收一帧数据。kick_start_rx()g数段的代码主要用于调用

15、sal 100_usb_recv(),建 立回调。在USB主机发送一个数据包时,设备的内核模块会通过同调方式调用rx_done_callback_packet_buffer() 函数,将数据包的内容送入个FIFO队列,以便能通过read。函数将该数据包返同给usb-char设备节点。2. USB主机端通信过程对于运行Linux操作系统的USB主机,与usb-char相应的USB主机模块叫做usbseriaL大多数Linux 版本中都包含了该模块,但它并不总能自动加载。通常应在主机与USB设备之间的连接建立之前利用 modprobe或insmod加载该模块。USB设备查询完成之后,主机上的一项应

16、用就会利用某个usbserial设备节点(字符型,major为188, minor 大于等于0)与其通信。这些节点通常叫做/dev/ttyUSBn。Usbserial模块会报告它将哪一个节点分配给了哪 一台USB设备,并将这一信息按如下方式记载在内核消息记录中:usbserial.c:检测到一般转换器usbserial.c:将般转换器加入ttyUSBO这种连接一旦建立,USB主机上的应用就可以通过向特定的节点读或写的方式与某USB设备通信。 此时,笔者并未考虑在运行Win32或其他类型操作系统的主机上已有类似usbserial的模块。但用于这些 主机上的任何USB驱动程序,只要能够进行bulk-in和bulk-out数据传输,就很可能是一个近乎完整的驱 动程序,只需进行一定的产品调整,并添加与产品绑定的

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号