新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 基于Linux的USB主/从设备之间的三种通信方式

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

作者: 时间:2013-10-26 来源:网络 收藏

  在usb -char中,真正的操作开始于usbc_open()函数,列表1给出了函数的一部分代码。笔者由于临时的兴趣,对该代码做了一点修改,取消了错误和超时句柄。在此向代码的原作者Brad Parker、Nicolas Pitre 和Ward Willats致歉。

  twiddle_descriptors()函数用于设置设备的描述符。在描述符设置好之后,我们就可以开始进行设备查询,并从 主机接收一帧数据。kick_start_rx()函数段的代码主要用于调用sa1100_usb_recv(),建立回调。

  在主机发送一个数据包时,设备的内核模块会通过回调方式调用rx_done_callback_packet_buffer()函数,将数据包的内容送入一个FIFO队列,以便能通过read()函数将该数据包返回给usb-char设备节点。

2. USB主机端通信过程

  对于运行操作系统的USB 主机,与usb-char相应的USB 主机模块叫做usbserial。大多数版本中都包含了该模块,但它并不总能自动加载。通常应在主机与USB设备之间的连接建立之前利用 modprobe 或insmod加载该模块。

  USB设备查询完成之后,主机上的一项应用就会利用某个usbserial设备节点(字符型, major 为188, minor 大于等于0)与其通信。这些节点通常叫做/dev/ttyUSBn。Usbserial模块会报告它将哪一个节点分配给了哪一台USB设备,并将这一信息按如下方式记载在内核消息记录中: =================================== usbserial.c:检测到一般转换器 usbserial.c:将一般转换器加入ttyUSB0 ==================================

  这种连接一旦建立,USB 主机上的应用就可以通过向特定的节点读或写的方式与某USB设备通信。


  此时,笔者并未考虑在运行Win32或其他类型操作系统的主机上已有类似usbserial的模块。但用于这些主机上的任何USB驱动程序,只要能够进行bulk-in 和 bulk-out数据传输,就很可能是一个近乎完整的驱动程序,只需进行一定的产品调整,并添加与产品绑定的厂商ID。

   主机上还有另一种类似usbserial模块的库,叫做libusb (参见libusb.sourceforge.net)。该库通过低级的内核系统调用而不是通过usbserial模块来完成USB数据传输,因而在 Linux kernel版本上更容易设置和使用。同时,该库还能提供大量实用的调试功能,十分利于对USB链接上运行的复杂的通信协议进行调试。

  为了通过libusb与一个采用了usb-char模块的USB设备进行通信,Linux主机应用首先通过库中的usb_open()函数与设备建立连接,然后利用函数usb_bulk_read()和usb_bulk_write()与设备交换数据。Libusb中含有几个程序范例。

利用USB实现以太网连接

1. USB 设备端通信过程

  如果利用USB连接来实现高速串口并非您所希望,那么您还可以将所有USB连接用作一个以太网。不论在主机端还是在设备端,Linux均有模块能实现这一功能。iPAQ(掌上电脑)的Linux内核就独一无二地采用了这种通信策略,因为iPAQ硬件中既没有可访问的串口也没有专门的网络接口。

  StrongARM Linux内核中,有一个叫做usb-eth的模块(arch/arm/mach-sa1100/usb-eth.c),它利用USB作为物理媒介,模拟出一个虚构的以太网设备。一旦这种网络接口创建起来之后,就可以为它分配IP地址,并且外部环境均将其作为一个普通的以太网硬件对待。一旦USB 主机连接建立起来,usb-eth模块就允许USB设备“浏览”因特网,拼其他的IP地址,甚至通过DHCP、HTTP、NFS或者远程网“交谈”,以及收发电子邮件。简而言之,任何能够在真正的以太网接口上运行的应用都可以原封不动地在usb-eth 上运行,因为这些应用无法识别它们所使用的其实并非真正的以太网硬件。

2. USB 主机端通信过程

  相应的,在运行 Linux操作系统的主机一端,可用来在USB上实现以太网连接的内核模块叫做usbnet。安装了该模块之后,一旦主机与USB设备的连接建立起来,它就会创建一个虚拟的以太网接口,在主机一端的内核模块以及用户应用看来,这个虚拟的接口与真正的以太网接口别无二致。主机端的应用可以通过拼一个USB设备的IP地址来检查该设备是否已经连上,如果拼操作成功,那么就表示设备已经连接成功。

  最近出现了一种针对Win32主机的usbnet风格的驱动,叫做Bahia网络驱动,关于该驱动的详细信息请访问www.bahia21.com/download.htm。

USB通信的调试

  遗憾的是,在USB 主机与Linux USB设备之间进行通信时,能够帮助我们跟踪通信过程中出现的问题的工具实在不多。除了libusb所提供的调试功能以外(该功能十分强大,但对于内核的系统调用接口则无能为力),在一次失败的设备查询或数据传输的尝试过程中发生了什么问题?只有内核源代码和记录能够提供一些线索。笔者尝试在开发过程中向 USB 主机和设备代码中大量添加printk()函数调用,但这种方法会引入额外开销,从而改变USB代码自身的性能,这在有些情况下反而是事与愿违。

  对那些希望对 USB设备接口进行逆向工程处理,或者希望查找其产品缺陷的Linux开发者而言,一个叫做USB Snoopy (home.jps.net/~koma)的程序是个不错的选择。只是USB Snoopy仅能在Win32主机上运行。关于USB Snoopy的详细信息或关于常规的USB调试,请参看本文末给出的参考文献中Jan Axelson撰写的 “USB Debug Tips”。

Linux已成为通用型操作系统

  如今Linux已不再是USB 主机专用的操作系统了,USB设备也可以方便地选择它。而且Linux下的USB通信太灵活易用了,因而笔者采用其他易用型串口(RS-232)的日子很可能就此结束,对我而言,这是件好事。

参考文献:

[1].major datasheethttp://www.dzsc.com/datasheet/major+_2533383.html.

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

linux相关文章:linux教程



上一页 1 2 3 下一页

评论


相关推荐

技术专区

关闭