焦新泉 袁小康 儲(chǔ)成群
關(guān)鍵詞: USB; 數(shù)據(jù)存儲(chǔ); ARM?Linux; Libusb庫(kù); CY7C68013; 接口函數(shù)
中圖分類(lèi)號(hào): TN919?34; TP273 ? ? ? ? ? ? ? ? 文獻(xiàn)標(biāo)識(shí)碼: A ? ? ? ? ? ? ? ? ? ?文章編號(hào): 1004?373X(2019)06?0006?04
Abstract: The ARM microcontroller carried with the embedded Linux system can be taken as a handheld terminal to complete some complicated interaction functions on the personnel computer. The basic methods of data storage are implemented by driving the USB control chip CY7C68013 based on the Libusb library under the ARM?Linux platform. The direct access to the USB device CY7C68013 in the user space is realized based on the Libusb library under the ARM?Linux platform. The USB device development without any driver under the Linux can be realized by recalling the interface function provided by the Libusb library, during which the development personnel do not need to understand the complex USB protocol and Linux kernel mechanism.
Keywords: USB; data storage; ARM?Linux; Libusb library; CY7C68013; interface function
USB控制器在數(shù)據(jù)采集系統(tǒng)具有廣泛的應(yīng)用,通常將獲取到的數(shù)據(jù)保存至PC機(jī)進(jìn)行處理。隨著嵌入式設(shè)備的日趨成熟,應(yīng)用更加便攜、靈活的嵌入式平臺(tái)代替PC平臺(tái)接收數(shù)據(jù)并進(jìn)行分析成為可能。為此,以USB控制芯片CY7C68013為例,介紹了一種在嵌入式ARM?Linux平臺(tái)的USB數(shù)據(jù)存儲(chǔ)方法。
一個(gè)數(shù)據(jù)采集系統(tǒng)可以由如圖1所示的系統(tǒng)組成。該系統(tǒng)主要是由FPGA和USB 2.0控制器CY7C68013組成,可以根據(jù)實(shí)際系統(tǒng)的需要,用FPGA實(shí)現(xiàn)預(yù)定功能,如數(shù)據(jù)采集卡、控制硬盤(pán)讀寫(xiě)等[1]。采用嵌入式ARM平臺(tái)代替PC機(jī),將采集的數(shù)據(jù)通過(guò)USB傳遞給由ARM構(gòu)成的上位機(jī)系統(tǒng)并顯示到觸摸屏上,實(shí)現(xiàn)數(shù)據(jù)采集處理與顯示功能。本文使用的嵌入式ARM?Linux系統(tǒng)的硬件平臺(tái)是深圳市英蓓特科技有限公司推出的基于德州儀器(TI)AM1808處理器的評(píng)估套件。AM1808處理器擁有豐富的外設(shè)資源,也是功耗最低的ARM9處理器之一,同時(shí)也是TI首批集成SATA的器件。這些特點(diǎn)使其非常適合在數(shù)據(jù)采集領(lǐng)域的應(yīng)用。
CY7C68013是Cypress公司的一種單芯片集成USB 2.0收發(fā)器、能串行接口引擎(SIE)和增強(qiáng)型8051微處理器的功能強(qiáng)大的接口芯片,圖2是它的結(jié)構(gòu)框圖。CY7C68013符合USB 2.0協(xié)議規(guī)范,可以按照USB設(shè)備進(jìn)行開(kāi)發(fā)。
2.1 ?USB簡(jiǎn)介
通用串行總線(Universal Serial Bus,USB)是一種用于規(guī)范電腦與外部設(shè)備的連接和通信的外部總線標(biāo)準(zhǔn)。USB設(shè)備邏輯上劃分為設(shè)備(device)、配置(config)、接口(interface)和端點(diǎn)(endpoint)四個(gè)層次,并具有以下關(guān)系:設(shè)備可以有一個(gè)或多個(gè)配置;配置可以有一個(gè)或多個(gè)接口;接口可以有一個(gè)或多個(gè)設(shè)置;接口可以有一個(gè)或多個(gè)端點(diǎn)。
USB通信最基本的形式是通過(guò)端點(diǎn)(USB端點(diǎn)分中斷、批量、等時(shí)、控制4種,每種功能不同),主機(jī)通過(guò)端點(diǎn)與設(shè)備進(jìn)行通信[2]。
2.2 Libusb簡(jiǎn)介
USB協(xié)議是目前使用最廣泛的外部總線協(xié)議,目前Linux對(duì)USB有了比較完善的支持。但由于USB所支持的設(shè)備的多樣性,一些特殊的USB設(shè)備的驅(qū)動(dòng)還需要開(kāi)發(fā)人員自行編寫(xiě)。
在Linux平臺(tái),USB驅(qū)動(dòng)開(kāi)發(fā)主要有兩種方式:一種是基于Linux內(nèi)核編譯驅(qū)動(dòng),需要在內(nèi)核空間完成,通常是參考內(nèi)核中USB_skeleton修改[3?4];另一種是基于Libusb庫(kù)在用戶(hù)空間實(shí)現(xiàn)(也稱(chēng)作“免驅(qū)”或者“無(wú)驅(qū)”設(shè)計(jì))。本文主要介紹基于Libusb的USB驗(yàn)證性應(yīng)用設(shè)計(jì)。
Libusb是一種高級(jí)別的API,它封裝了低級(jí)別的內(nèi)核與USB模塊的交互,并提供了一系列適合在用戶(hù)空間進(jìn)行USB驅(qū)動(dòng)開(kāi)發(fā)的函數(shù)[5]。基于Libusb庫(kù)的驅(qū)動(dòng)設(shè)計(jì)具有與內(nèi)核版本無(wú)關(guān)、跨平臺(tái)的優(yōu)點(diǎn),無(wú)需對(duì)內(nèi)核重新編譯,也不用考慮內(nèi)核版本兼容性,相對(duì)于內(nèi)核編譯大大降低了開(kāi)發(fā)門(mén)檻,是一種高效的開(kāi)發(fā)方式。Libusb提供了用戶(hù)空間的結(jié)構(gòu)體struct Libusb_XXX_descriptor描述設(shè)備、配置、接口和端點(diǎn)??梢园凑彰枋龈鶕?jù)Libusb_open(),Libusb_XXX_transfer();Libusb_close()等函數(shù)編寫(xiě)針對(duì)CY7C68013的特定功能的應(yīng)用程序。
針對(duì)數(shù)據(jù)存取的基本功能,本文實(shí)現(xiàn)在ARM?Linux 2.6.33系統(tǒng)下基于Libusb設(shè)計(jì)CY7C68013驅(qū)動(dòng)。應(yīng)用針對(duì)Cypress官方提供的測(cè)試用固件例程bulkloop驗(yàn)證功能如
圖3所示。圖形用戶(hù)界面使用Qt實(shí)現(xiàn)。整個(gè)
工作在圖形編程工具Qt 4.5環(huán)境完成。
3.1 ?CY7C68013功能實(shí)現(xiàn)
CY7C68013的固件下載通過(guò)調(diào)用Cypress公司提供的對(duì)應(yīng)Linux平臺(tái)的函數(shù)cyUSB_download_fx2( ) 實(shí)現(xiàn),函數(shù)依托于Cypress官網(wǎng)提供的Linux平臺(tái)的cyUSB庫(kù),因此使用前需要將該庫(kù)交叉編譯到ARM?Linux平臺(tái)編寫(xiě)的應(yīng)用要先調(diào)用USB_init()函數(shù)進(jìn)行初始化,初始化之后才能按照Libusb庫(kù)進(jìn)行操作。
Linux的宗旨是一切皆文件,而文件操作首先要打開(kāi)設(shè)備。對(duì)USB設(shè)備操作也一樣,開(kāi)發(fā)人員可以使用Libusb_open(Libusb_device*dev,Libusb_device_handle **
handle);打開(kāi)由VID/PID指定的USB設(shè)備。handle句柄作為對(duì)應(yīng)USB的唯一標(biāo)識(shí),貫穿于設(shè)備的整個(gè)操作過(guò)程,直至最后調(diào)用Libusb_close(handle)關(guān)閉指定的USB設(shè)備,釋放該句柄。
打開(kāi)設(shè)備后通過(guò)四個(gè)層次的描述符struct Libusb_XXX_descriptor進(jìn)行描述。USB設(shè)備將端點(diǎn)封裝到接口,操作端點(diǎn)必須先要聲明接口:Libusb_claim_interface(Libusb_device_handle *handle,int interface_number)。其中interface_number是所要聲明的接口號(hào)碼。Libusb完成的是用戶(hù)層的操作,操作前必須解除內(nèi)核對(duì)接口的占用:
Libusb_kernel_driver_active(Libusb_device_handle*dev,int interface_number); ? ? ? ? ? //該函數(shù)判斷內(nèi)核是否占用這個(gè)接口
Libusb_detach_kernel_driver(Libusb_device_handle *dev,int interface_number); ? ? ? ? ? //該函數(shù)解除內(nèi)核對(duì)這個(gè)接口的占用
聲明接口后利用結(jié)構(gòu)體端點(diǎn)描述符該接口的端點(diǎn)及其他信息:
struct Libusb_endpoint_descriptor {uint8_t ?bLength;
//端點(diǎn)長(zhǎng)度
uint8_t ?bDescriptorType;
uint8_t ?bEndpointAddress;
//端點(diǎn)地址,可以用來(lái)確定端點(diǎn)傳輸?shù)姆较?/p>
uint8_t ?bmAttributes; ? ? ? ? ? ? ? ? ? ? ? ? //端點(diǎn)類(lèi)型(四種)
uint16_t wMaxPacketSize; ? ? ? ? ? ? ? ? ? ? ? //最大數(shù)據(jù)尺寸
uint8_t ?bInterval;
uint8_t ?bRefresh;
uint8_t ?bSynchAddress;
};
之后可以根據(jù)端點(diǎn)的屬性通過(guò)操作函數(shù)Libusb_
XXX_transfer()結(jié)合文件操作函數(shù)實(shí)現(xiàn)數(shù)據(jù)傳輸存儲(chǔ)功能。
根據(jù)固件功能使用端點(diǎn)塊傳輸函數(shù)實(shí)現(xiàn)數(shù)據(jù)回環(huán):
Libusb_bulk_transfer(dev_handle,out_endpoint,data,length,actual_length, timeout);
Libusb_bulk_transfer(dev_handle,in_endpoint,data,length,actual_length, timeout);
之后根據(jù)Linux文件操作將數(shù)據(jù)進(jìn)行保存:
/*將data緩沖區(qū)數(shù)據(jù)寫(xiě)入句柄fp指向的文件當(dāng)中,返回寫(xiě)入字節(jié)數(shù)*/
sum=write(fp, data, actual_length);
完成操作后調(diào)用Libusb_close()函數(shù)關(guān)閉指定的USB設(shè)備,釋放句柄。
3.2 ?SATA硬盤(pán)存儲(chǔ)功能實(shí)現(xiàn)
Linux 2.6系統(tǒng)內(nèi)核已經(jīng)支持了SATA的讀/寫(xiě),只需在內(nèi)核編譯時(shí)勾選即可。Linux 2.6系統(tǒng)對(duì)ntfs格式寫(xiě)支持不很完善,把第三方庫(kù)ntfs?3g交叉編譯到ARM?Linux,完善對(duì)SATA硬盤(pán)的讀/寫(xiě)功能。在PC?linux端執(zhí)行:
# ./configure CC=arm?none?linux?gnueabi?gcc ??host=arm?linux ??prefix=/home/ntfs/ ??exec?prefix=/home/ntfs/target
# make
# make install
把生成的動(dòng)態(tài)庫(kù)復(fù)制到開(kāi)發(fā)板的/usr/local目錄下。
3.3 ?程序移植
把在PC?Linux端編寫(xiě)好的數(shù)據(jù)傳輸應(yīng)用程序以及CY7C68013需要的cyUSB庫(kù),觸摸屏需要的QT庫(kù)、tslib庫(kù)用ARM?none?linux?gnueabi?gcc編譯,并把編譯生成的庫(kù)文件復(fù)制到ARM?Linux的/usr/local目錄下。之后添加環(huán)境變量,再修改系統(tǒng)啟動(dòng)時(shí)的等級(jí),添加啟動(dòng)后執(zhí)行的腳本使應(yīng)用程序開(kāi)機(jī)自啟,即完成了專(zhuān)用設(shè)備的搭建。
本文用到的硬件有SBC8018開(kāi)發(fā)板、基于CY7C68013和FPGA的讀數(shù)盒、金士頓60 GB SATA固態(tài)硬盤(pán)、PC機(jī)及硬盤(pán)供電電源,如圖4所示。
如圖5所示,scan按鈕實(shí)現(xiàn)USB硬件探測(cè)功能,設(shè)備信息顯示在文本框當(dāng)中;claim_iface按鈕實(shí)現(xiàn)接口選擇功能,USB協(xié)議邏輯上支持多接口,所以對(duì)于特殊功能的設(shè)備提供接口選擇是值得的;in_ep,out_ep實(shí)現(xiàn)端點(diǎn)選擇功能,根據(jù)CY7C68013固件,測(cè)試選擇86端點(diǎn)入,2端點(diǎn)配套;rcv按鈕實(shí)現(xiàn)數(shù)據(jù)接收功能,在文本框顯示接收的數(shù)據(jù)及其ASCII碼(字符B對(duì)應(yīng)ASCII碼值42)。save_as按鈕實(shí)現(xiàn)將數(shù)據(jù)保存功能,保存操作如圖6所示;reset按鈕是硬件復(fù)位,兩個(gè)clear按鈕實(shí)現(xiàn)清屏功能。
嵌入式設(shè)備可以為數(shù)據(jù)采集系統(tǒng)設(shè)計(jì)驗(yàn)證帶來(lái)方便。本文實(shí)現(xiàn)了在ARM?Linux平臺(tái)下基于Libusb 庫(kù)在用戶(hù)空間直接訪問(wèn)USB設(shè)備CY7C68013。開(kāi)發(fā)人員無(wú)需了解復(fù)雜的USB協(xié)議與Linux內(nèi)核機(jī)制,通過(guò)Libusb 庫(kù)提供的接口函數(shù)調(diào)用可以實(shí)現(xiàn)Linux下USB設(shè)備“無(wú)驅(qū)”開(kāi)發(fā)。本文在AM1808開(kāi)發(fā)平臺(tái)上實(shí)現(xiàn)數(shù)據(jù)采集顯示,為目前主流的嵌入式Linux平臺(tái)的USB驅(qū)動(dòng)開(kāi)發(fā)提供參考,開(kāi)發(fā)人員可以據(jù)此模型開(kāi)發(fā)工程上的特定功能,提高開(kāi)發(fā)效率縮短開(kāi)發(fā)周期。
參考文獻(xiàn)
[1] 譚安菊,龔彬.USB 2.0控制器CY7C68013與FPGA接口的Verilog HDL實(shí)現(xiàn)[J].電子工程師,2007,33(7):52?55.
TAN Anju, GONG Bin. Implementation of USB2.0 controller CY7C68013 and FPGA′s interface in Verilog HDL [J]. Electronic engineer, 2007, 33(7):52?55.
[2] 薛園園,趙建領(lǐng).USB 應(yīng)用開(kāi)發(fā)實(shí)例詳解[M].北京:人民教育出版社,2009.
XUE Yuanyuan, ZHAO Jianling. Detailed explanation of USB application development examples [M]. Beijing: People′s Education Press, 2009.
[3] 彭定軍,陳安,高健華.嵌入式Linux下基于Libusb的USB驅(qū)動(dòng)開(kāi)發(fā)[J].技術(shù)與市場(chǎng),2008(11):4?5.
PENG Dingjun, CHEN An, GAO Jianhua. Development of USB driver based on Libusb under embedded Linux [J]. Technology and market, 2008(11): 4?5.
[4] 楊強(qiáng),王志斌,李曉,等.Linux中USB設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì)及其應(yīng)用[J].濟(jì)南大學(xué)學(xué)報(bào)(自然科學(xué)版),2014,28(3):224?229.
YANG Qiang, WANG Zhibin, LI Xiao, et al. Design of USB device driver in Linux and its applications [J]. Journal of University of Jinan (Science and technology), 2014, 28(3): 224?229.
[5] 杜敏杰,馬彥恒,劉利民.Linux下基于CY7C68013芯片的USB設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā)[J].科學(xué)技術(shù)與工程,2008,8(21):5933?5937.
DU Minjie, MA Yanheng, LIU Limin. USB device driver development of CY7C68013 chip under Linux [J]. Science technology and engineering, 2008, 8(21): 5933?5937.
[6] XU Z, LIU Z, ZHANG H, et al. Development of Linux based USB device driver for portable spectrometer [C]// Proceedings of 20st Annual International Conference on Chinese Control and Decision Conference. Guilin: IEEE, 2009: 5161?5164.
[7] 馬宗驥,李佩玥,章明朝,等.基于FPGA+ARM的數(shù)據(jù)采集系統(tǒng)設(shè)計(jì)[J].化工自動(dòng)化及儀表,2012,39(9):1187?1189.
MA Zongji, LI Peiyue, ZHANG Mingchao, et al.Design of data acquisition system based on FPGA and ARM [J]. Control and instruments in chemical industry, 2012, 39(9): 1187?1189.
[8] QI Guangping, SUN Peng. The embedded system design for military or industry personal data assistant [C]// Proceedings of IEEE International Conference on Computer Science and Automation Engineering. Zhangjiajie: IEEE, 2012: 521?525.
[9] 曾希強(qiáng).Linux下基于Libusb的USB設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)與實(shí)現(xiàn)[J].信息與電腦,2009(7):101.
ZENG Xiqiang. Design and implementation of USB device driver in Linux based on Libusb [J]. China computer & communication, 2009(7): 101.
[10] 朱恩亮,趙臘才,茹偉,等.Linux環(huán)境下USB設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)[J].電子科技,2016,29(1):108?110.
ZHU Enliang, ZHAO Lacai, RU Wei, et al. Development of USB device drivers of Linux [J]. Electronic science and technology, 2016, 29(1): 108?110.