新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 基于Linux的USB主/從設(shè)備之間的三種通信方式

基于Linux的USB主/從設(shè)備之間的三種通信方式

作者: 時間:2013-10-26 來源:網(wǎng)絡(luò) 收藏

  在usb -char中,真正的操作開始于usbc_open()函數(shù),列表1給出了函數(shù)的一部分代碼。筆者由于臨時的興趣,對該代碼做了一點修改,取消了錯誤和超時句柄。在此向代碼的原作者Brad Parker、Nicolas Pitre 和Ward Willats致歉。

  twiddle_descriptors()函數(shù)用于設(shè)置設(shè)備的描述符。在描述符設(shè)置好之后,我們就可以開始進行設(shè)備查詢,并從 主機接收一幀數(shù)據(jù)。kick_start_rx()函數(shù)段的代碼主要用于調(diào)用sa1100_usb_recv(),建立回調(diào)。

  在主機發(fā)送一個數(shù)據(jù)包時,設(shè)備的內(nèi)核模塊會通過回調(diào)方式調(diào)用rx_done_callback_packet_buffer()函數(shù),將數(shù)據(jù)包的內(nèi)容送入一個FIFO隊列,以便能通過read()函數(shù)將該數(shù)據(jù)包返回給usb-char設(shè)備節(jié)點。

2. USB主機端通信過程

  對于運行操作系統(tǒng)的USB 主機,與usb-char相應(yīng)的USB 主機模塊叫做usbserial。大多數(shù)版本中都包含了該模塊,但它并不總能自動加載。通常應(yīng)在主機與USB設(shè)備之間的連接建立之前利用 modprobe 或insmod加載該模塊。

  USB設(shè)備查詢完成之后,主機上的一項應(yīng)用就會利用某個usbserial設(shè)備節(jié)點(字符型, major 為188, minor 大于等于0)與其通信。這些節(jié)點通常叫做/dev/ttyUSBn。Usbserial模塊會報告它將哪一個節(jié)點分配給了哪一臺USB設(shè)備,并將這一信息按如下方式記載在內(nèi)核消息記錄中: =================================== usbserial.c:檢測到一般轉(zhuǎn)換器 usbserial.c:將一般轉(zhuǎn)換器加入ttyUSB0 ==================================

  這種連接一旦建立,USB 主機上的應(yīng)用就可以通過向特定的節(jié)點讀或?qū)懙姆绞脚c某USB設(shè)備通信。


  此時,筆者并未考慮在運行Win32或其他類型操作系統(tǒng)的主機上已有類似usbserial的模塊。但用于這些主機上的任何USB驅(qū)動程序,只要能夠進行bulk-in 和 bulk-out數(shù)據(jù)傳輸,就很可能是一個近乎完整的驅(qū)動程序,只需進行一定的產(chǎn)品調(diào)整,并添加與產(chǎn)品綁定的廠商ID。

   主機上還有另一種類似usbserial模塊的庫,叫做libusb (參見libusb.sourceforge.net)。該庫通過低級的內(nèi)核系統(tǒng)調(diào)用而不是通過usbserial模塊來完成USB數(shù)據(jù)傳輸,因而在 Linux kernel版本上更容易設(shè)置和使用。同時,該庫還能提供大量實用的調(diào)試功能,十分利于對USB鏈接上運行的復(fù)雜的通信協(xié)議進行調(diào)試。

  為了通過libusb與一個采用了usb-char模塊的USB設(shè)備進行通信,Linux主機應(yīng)用首先通過庫中的usb_open()函數(shù)與設(shè)備建立連接,然后利用函數(shù)usb_bulk_read()和usb_bulk_write()與設(shè)備交換數(shù)據(jù)。Libusb中含有幾個程序范例。

利用USB實現(xiàn)以太網(wǎng)連接

1. USB 設(shè)備端通信過程

  如果利用USB連接來實現(xiàn)高速串口并非您所希望,那么您還可以將所有USB連接用作一個以太網(wǎng)。不論在主機端還是在設(shè)備端,Linux均有模塊能實現(xiàn)這一功能。iPAQ(掌上電腦)的Linux內(nèi)核就獨一無二地采用了這種通信策略,因為iPAQ硬件中既沒有可訪問的串口也沒有專門的網(wǎng)絡(luò)接口。

  StrongARM Linux內(nèi)核中,有一個叫做usb-eth的模塊(arch/arm/mach-sa1100/usb-eth.c),它利用USB作為物理媒介,模擬出一個虛構(gòu)的以太網(wǎng)設(shè)備。一旦這種網(wǎng)絡(luò)接口創(chuàng)建起來之后,就可以為它分配IP地址,并且外部環(huán)境均將其作為一個普通的以太網(wǎng)硬件對待。一旦USB 主機連接建立起來,usb-eth模塊就允許USB設(shè)備“瀏覽”因特網(wǎng),拼其他的IP地址,甚至通過DHCP、HTTP、NFS或者遠程網(wǎng)“交談”,以及收發(fā)電子郵件。簡而言之,任何能夠在真正的以太網(wǎng)接口上運行的應(yīng)用都可以原封不動地在usb-eth 上運行,因為這些應(yīng)用無法識別它們所使用的其實并非真正的以太網(wǎng)硬件。

2. USB 主機端通信過程

  相應(yīng)的,在運行 Linux操作系統(tǒng)的主機一端,可用來在USB上實現(xiàn)以太網(wǎng)連接的內(nèi)核模塊叫做usbnet。安裝了該模塊之后,一旦主機與USB設(shè)備的連接建立起來,它就會創(chuàng)建一個虛擬的以太網(wǎng)接口,在主機一端的內(nèi)核模塊以及用戶應(yīng)用看來,這個虛擬的接口與真正的以太網(wǎng)接口別無二致。主機端的應(yīng)用可以通過拼一個USB設(shè)備的IP地址來檢查該設(shè)備是否已經(jīng)連上,如果拼操作成功,那么就表示設(shè)備已經(jīng)連接成功。

  最近出現(xiàn)了一種針對Win32主機的usbnet風(fēng)格的驅(qū)動,叫做Bahia網(wǎng)絡(luò)驅(qū)動,關(guān)于該驅(qū)動的詳細信息請訪問www.bahia21.com/download.htm。

USB通信的調(diào)試

  遺憾的是,在USB 主機與Linux USB設(shè)備之間進行通信時,能夠幫助我們跟蹤通信過程中出現(xiàn)的問題的工具實在不多。除了libusb所提供的調(diào)試功能以外(該功能十分強大,但對于內(nèi)核的系統(tǒng)調(diào)用接口則無能為力),在一次失敗的設(shè)備查詢或數(shù)據(jù)傳輸?shù)膰L試過程中發(fā)生了什么問題?只有內(nèi)核源代碼和記錄能夠提供一些線索。筆者嘗試在開發(fā)過程中向 USB 主機和設(shè)備代碼中大量添加printk()函數(shù)調(diào)用,但這種方法會引入額外開銷,從而改變USB代碼自身的性能,這在有些情況下反而是事與愿違。

  對那些希望對 USB設(shè)備接口進行逆向工程處理,或者希望查找其產(chǎn)品缺陷的Linux開發(fā)者而言,一個叫做USB Snoopy (home.jps.net/~koma)的程序是個不錯的選擇。只是USB Snoopy僅能在Win32主機上運行。關(guān)于USB Snoopy的詳細信息或關(guān)于常規(guī)的USB調(diào)試,請參看本文末給出的參考文獻中Jan Axelson撰寫的 “USB Debug Tips”。

Linux已成為通用型操作系統(tǒng)

  如今Linux已不再是USB 主機專用的操作系統(tǒng)了,USB設(shè)備也可以方便地選擇它。而且Linux下的USB通信太靈活易用了,因而筆者采用其他易用型串口(RS-232)的日子很可能就此結(jié)束,對我而言,這是件好事。

參考文獻:

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

linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

linux相關(guān)文章:linux教程



上一頁 1 2 3 下一頁

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉