<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          基于Linux的USB設(shè)備

          作者:Bill 時(shí)間:2003-07-16 來(lái)源:電子設(shè)計(jì)應(yīng)用 收藏

          引言
          通用串行總線()是一種快速而靈活地連接配件與計(jì)算機(jī)工作站的接口,其應(yīng)用非常廣泛。Linux中除了包含對(duì)主機(jī)控制器的驅(qū)動(dòng),還含有設(shè)備控制器,尤其是集成在StrongARM SA1110處理器上的控制器的驅(qū)動(dòng)。這些控制器驅(qū)動(dòng)通過(guò)使用USB可使基于Linux的嵌入式系統(tǒng)與主機(jī) (運(yùn)行的可以是Linux,或不是)進(jìn)行通信。這里提供三種方法給運(yùn)行Linux操作系統(tǒng)的嵌入式系統(tǒng)增加USB支持,可采用其中一種與USB主機(jī)展開(kāi)通信。
          第一種,最復(fù)雜的設(shè)備采用專門編寫的內(nèi)核模塊解析標(biāo)準(zhǔn)USB總線上通行的錯(cuò)綜復(fù)雜的高層協(xié)議;相應(yīng)的USB主機(jī)定制驅(qū)動(dòng)和應(yīng)用程序來(lái)完成連接。第二種,有些基于Linux的設(shè)備把總線當(dāng)作一種簡(jiǎn)單的運(yùn)行在主機(jī)上的點(diǎn)對(duì)點(diǎn)串行連接使用;主機(jī)應(yīng)用程序采用主機(jī)操作系統(tǒng)提供的USB編程界面,而其外在表現(xiàn)則仿佛是在通過(guò)一種典型的串行端口進(jìn)行通信。第三種,另有一些設(shè)備把USB看作一種以太網(wǎng)絡(luò),它們用主機(jī)作網(wǎng)關(guān),把USB設(shè)備與辦公LAN或Internet相連接。通常的做法是使用專門的主機(jī)驅(qū)動(dòng)實(shí)現(xiàn)它。
          最佳方案的選擇取決于研發(fā)所需時(shí)間,以及針對(duì)具體嵌入式應(yīng)用,要把USB接口作成什么樣。以下對(duì)這三種方法如何在基于Linux的USB設(shè)備上的應(yīng)用逐一進(jìn)行描述。本文是關(guān)于如何在基于Linux的照相機(jī)和PDA之類的USB設(shè)備上使用Linux的論述,在此,USB是指由方形連接器而非扁平矩形連接器構(gòu)成的USB設(shè)備。

          本文引用地址:http://www.ex-cimer.com/article/1924.htm

          內(nèi)核模塊
          把USB加到基于Linux的設(shè)備上的第一種方法是編寫一個(gè)定制的Linux內(nèi)核模塊。這種方法通常要求相應(yīng)開(kāi)發(fā)主機(jī)操作系統(tǒng)(Windows、Linux以及其它OS)的驅(qū)動(dòng)。
          借助定制內(nèi)核模塊在設(shè)備中的安裝,可以進(jìn)行文件系統(tǒng)仿真等,使嵌入式應(yīng)用將其USB主機(jī)當(dāng)作遠(yuǎn)程存儲(chǔ)設(shè)備對(duì)待。這一方法的另一潛在用途是構(gòu)成一種存儲(chǔ)轉(zhuǎn)發(fā)字符設(shè)備,從嵌入式應(yīng)用程序中緩沖數(shù)據(jù)流,直到USB主機(jī)連接完成建立為止。
          對(duì)于基于StrongARM的Linux設(shè)備,其USB應(yīng)用內(nèi)核模塊調(diào)用sa1100_usb_open(),對(duì)管理芯片的板上USB設(shè)備控制器外設(shè)的內(nèi)核代碼進(jìn)行初始化。然后該模塊調(diào)用sa1100_usb_get_descriptor_ptr()和sa1100_usb_set_string_descriptor(),通過(guò)枚舉過(guò)程對(duì)USB主機(jī)的給定USB描述符進(jìn)行設(shè)置。這些描述符包括設(shè)備供貨商及產(chǎn)品的數(shù)字標(biāo)識(shí)符、正文字符串等主機(jī)可用來(lái)對(duì)設(shè)備進(jìn)行識(shí)別的信息。甚至有一個(gè)序列號(hào)域,以便主機(jī)唯一地識(shí)別設(shè)備或?qū)SB上相同設(shè)備的多個(gè)實(shí)例加以區(qū)分。
          內(nèi)核模塊必須在開(kāi)始USB通信前完成USB描述符的建立,這是因?yàn)槊杜e過(guò)程由USB設(shè)備控制器驅(qū)動(dòng),一旦USB主機(jī)連上后會(huì)自動(dòng)執(zhí)行。一切準(zhǔn)備就緒后,USB設(shè)備模塊便調(diào)用sa1100_usb_start(),告訴內(nèi)核接受來(lái)自主機(jī)的USB連接請(qǐng)求。如果模塊在USB主機(jī)連上前調(diào)用sa1100_set_configured_ callback(),那么內(nèi)核將會(huì)在枚舉過(guò)程結(jié)束時(shí)調(diào)用所提供的回調(diào)函數(shù)?;卣{(diào)函數(shù)能很好地對(duì)設(shè)備完成連接狀態(tài)進(jìn)行可視化指示。
          如果USB通信不再需要,那么設(shè)備的內(nèi)核模塊便調(diào)用sa1100_usb_stop(),然后是 sa1100_usb_close(),關(guān)閉SA1100的USB控制器。
          StrongARM USB控制器支持?jǐn)?shù)據(jù)傳輸作業(yè)的bulk-in 和bulk-out。在從USB主機(jī)接收數(shù)據(jù)包時(shí),內(nèi)核模塊調(diào)用sa1100_usb_recv(),把數(shù)據(jù)緩沖區(qū)和回調(diào)函數(shù)地址傳遞給它。然后內(nèi)核的底層USB設(shè)備控制代碼對(duì)來(lái)自主機(jī)的bulk-out包進(jìn)行檢索,把內(nèi)容放于緩沖區(qū)中,并調(diào)用回調(diào)函數(shù)。
          回調(diào)函數(shù)必須從接收緩沖區(qū)提取數(shù)據(jù)并保存于其它位置或者把緩沖區(qū)空間加到一個(gè)隊(duì)列中,為下一個(gè)數(shù)據(jù)包的接收分配新的緩沖區(qū)。而后回調(diào)函數(shù)二次調(diào)用sa1100_usb_recv(),在需要時(shí)進(jìn)行下一個(gè)數(shù)據(jù)包的接收。過(guò)程與對(duì)USB主機(jī)的數(shù)據(jù)傳輸相類似。在聚集起一幀的數(shù)據(jù)量后,內(nèi)核模塊將數(shù)據(jù)的地址、長(zhǎng)度和回調(diào)地址傳遞給sa1100_usb_send()。傳輸完成時(shí),內(nèi)核調(diào)用回調(diào)函數(shù)。
          主機(jī)
          主機(jī)端USB驅(qū)動(dòng)的幾個(gè)例子在主流的Linux版本以及Linux內(nèi)核檔案組織分配的原始內(nèi)核源中都有提供。用于Handspring Visor(drivers/usb/serial/visor.c)的模塊是編寫較為簡(jiǎn)潔易懂的模塊之一,作為USB主機(jī)端模塊的模板(drivers/usb/usb-skeleton.c)使用。

          高速串行
          對(duì)于大多數(shù)實(shí)際應(yīng)用來(lái)說(shuō), 可以把USB總線當(dāng)作一種高速串行端口考慮。如此在某些類型的嵌入式設(shè)備和應(yīng)用中對(duì)它進(jìn)行原型模擬是有意義的。StrongARM處理器的Linux內(nèi)核提供現(xiàn)成的USB設(shè)備驅(qū)動(dòng)專工于此,稱作usb-char。
          在希望與USB主機(jī)通信時(shí),Linux USB設(shè)備應(yīng)用程序只是打開(kāi)對(duì)其usb-char設(shè)備節(jié)點(diǎn)(字符型,最大10,最小240)的連接,然后開(kāi)始讀寫數(shù)據(jù)即可。read()和 write()操作將一直返回錯(cuò)誤值直到USB主機(jī)連上為止。一旦連接建立和枚舉完成,便開(kāi)始通信,就像USB是一種點(diǎn)對(duì)點(diǎn)串行端口一樣。
          由于這種USB數(shù)據(jù)傳遞方法十分直接且實(shí)用,因此usb-char設(shè)備得到高效使用。它還為其它USB通信方法的實(shí)現(xiàn)提供了重要的參照基準(zhǔn)。
          usb-char的實(shí)際動(dòng)作從usbc_open()功能開(kāi)始,部分內(nèi)容示于列表1中。
          列表1:打開(kāi)USB上的串行連接
          static int usbc_open(struct inode *pInode, struct file *pFile)
          {
          int retval = 0;
          /* start usb core */
          sa1100_usb_open(_sb-char?;
          /* allocate memory for in-transit USB packets */
          tx_buf = (char*) kmalloc(TX_PACKET_SIZE, GFP_KERNEL | GFP_DMA);
          packet_buffer = (char*) kmalloc(RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA);
          /* allocate memory for the receive buffer; the contents of this
          buffer are provided during read() */
          rx_ring.buf = (char*) kmalloc(RBUF_SIZE, GFP_KERNEL);
          /* set up USB descriptors */
          twiddle_descriptors();
          /* enable USB i/o */
          sa1100_usb_start();
          /* set up to receive a packet */
          kick_start_rx();
          return 0;
          twiddle_descriptors()功能建立起設(shè)備的USB描述符。在描述符全部建起后,準(zhǔn)備從USB主機(jī)枚舉并接收一個(gè)數(shù)據(jù)幀。kick_start_rx()所需的代碼大多數(shù)情況下只是一種對(duì)sa1100_usb_recv() 的調(diào)用以建立回調(diào)而已。當(dāng)USB主機(jī)發(fā)送數(shù)據(jù)包時(shí),設(shè)備的內(nèi)核通過(guò)回調(diào)調(diào)用rx_done_callback_packet_buffer()函數(shù),把數(shù)據(jù)包的內(nèi)容移入usb-char 設(shè)備點(diǎn)上由read()返回的FIFO隊(duì)列。
          主機(jī)
          對(duì)于運(yùn)行Linux的USB主機(jī),usb-char相應(yīng)的USB主機(jī)模塊稱為usbserial模塊。大多數(shù)Linux版本都包括Usbserial模塊,盡管通常不是自動(dòng)裝入。在USB與設(shè)備的連接建立之前,usbserial 由modprobe 或 insmod載入。
          一旦USB設(shè)備開(kāi)始枚舉,主機(jī)上的應(yīng)用程序便用usbserial設(shè)備點(diǎn)(字符型,最大188,最小0以上)之一與設(shè)備進(jìn)行通信。這些節(jié)點(diǎn)通常命名為/dev/ttyUSBn。Usbserial模塊在內(nèi)核報(bào)文日志記錄中報(bào)告它把哪個(gè)節(jié)點(diǎn)指定給USB設(shè)備使用:
          usbserial.c: 通用轉(zhuǎn)換器刪除
          usbserial.c: 通用轉(zhuǎn)換器當(dāng)前連到ttyUSB0上。連接建立后,USB主機(jī)上的應(yīng)用程序便通過(guò)讀寫指定的節(jié)點(diǎn)與USB設(shè)備進(jìn)行通信。
          Linux主機(jī)上usbserial模塊的一種替代選擇是一種稱作libusb(libusb.sourceforge.net)的庫(kù)。這種庫(kù)使用低層內(nèi)核系統(tǒng)調(diào)用進(jìn)行USB數(shù)據(jù)傳輸,而不是通過(guò)usbserial模塊,在某種程度上跨Linux內(nèi)核版本建立和使用時(shí)更方便。Libusb庫(kù)還提供大量有用的調(diào)試功能,這一點(diǎn)在對(duì)運(yùn)行在USB鏈路上的復(fù)雜通信協(xié)議進(jìn)行除錯(cuò)時(shí)有幫助。用libusb與采用usb-char的USB設(shè)備進(jìn)行通信時(shí),Linux主機(jī)應(yīng)用程序使用usb_open()函數(shù)建立與該設(shè)備的連接。然后應(yīng)用程序使用usb_bulk_read()和usb_bulk_write()與設(shè)備交換數(shù)據(jù)。

          USB上的以太網(wǎng)
          另一種選擇是把USB作為一種以太網(wǎng)絡(luò)來(lái)對(duì)待。Linux具有在主機(jī)和設(shè)備端均可實(shí)現(xiàn)這種功能的模塊。由于iPAQ硬件既沒(méi)有可接入的串行端口也沒(méi)有一種專用的網(wǎng)絡(luò)接口,因此,iPAQ 的Linux內(nèi)核專門采用這種通信策略,在StrongARM的Linux內(nèi)核中,usb-eth模塊(arch/arm/mach-sa1100/usb-eth.c)對(duì)用USB作物理媒介的虛構(gòu)以太網(wǎng)設(shè)備進(jìn)行仿真。一旦創(chuàng)建后,這一網(wǎng)絡(luò)界面便被指定一個(gè)IP地址,否則作為通常的以太網(wǎng)硬件對(duì)待。一旦USB主機(jī)連上后,usb-eth模塊便能使USB設(shè)備“看到” Internet(如果存在Internet的話),ping測(cè)其它IP地址,甚至“談?wù)摗盌HCP, HTTP, NFS, telnet, 和e-mail。簡(jiǎn)言之,任何在實(shí)際的以太網(wǎng)界面上運(yùn)行的應(yīng)用將不折不扣地在usb-eth接口上得到實(shí)現(xiàn),因?yàn)樗鼈儾荒芊直娉銎湔谑褂玫牟皇菍?shí)在的以太網(wǎng)硬件。
          主機(jī)
          在Linux主機(jī)上,相應(yīng)的Ethernet-over-USB內(nèi)核模塊稱為usbnet。當(dāng)usbnet模塊得到安裝且設(shè)備的USB連接建立完成時(shí),usbnet模塊便針對(duì)主機(jī)端內(nèi)核及用戶應(yīng)用創(chuàng)建一個(gè)與實(shí)際硬件酷似的虛構(gòu)以太網(wǎng)界面,主機(jī)端應(yīng)用程序通過(guò)運(yùn)行設(shè)備IP地址ping測(cè),可以檢查USB設(shè)備的存在。如果ping測(cè)成功,設(shè)備便加上了。

          結(jié)語(yǔ)
          Linux不再只是USB主機(jī)使用,當(dāng)今它也是USB設(shè)備的合適選擇,Linux 下的USB通信是非常靈活和易用的。(鋤禾譯)

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



          關(guān)鍵詞: USB

          評(píng)論


          相關(guān)推薦

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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();