劉 輝,向 濤,張 杰
(1.重慶郵電大學(xué)重慶信科設(shè)計(jì)有限公司,重慶 400065;2.重慶郵電大學(xué)通信新技術(shù)應(yīng)用研究所,重慶 400065)
責(zé)任編輯:孫 卓
TDM330是重郵信科通信技術(shù)有限公司研發(fā)的TDSCDMA無線模塊。模塊提供了100PIN或者M(jìn)INIPCI接口,為語音傳輸、短消息和數(shù)據(jù)業(yè)務(wù)的開發(fā)提供了接口,支持2.8 Mbit/s的HSDPA數(shù)據(jù)和2.2 Mbit/s的HSUPA傳輸速率。TDM330在硬件上不僅提供了RS-232串口,也提供一種易于使用的高速率數(shù)據(jù)傳輸?shù)腢SB接口。全速USB的速率理論值能達(dá)到12 Mbit/s,而RS-232串口速率的理論值只能達(dá)到幾百kbit/s。相對(duì)于 USB而言,RS-232串口傳輸?shù)乃俣仁艿胶艽蟮南拗?,?huì)導(dǎo)致在傳輸過程出現(xiàn)嚴(yán)重的數(shù)據(jù)丟包現(xiàn)象,因此本文通過開發(fā)USB的主機(jī)端驅(qū)動(dòng)來使之開發(fā)板子DM6467與TD無線上網(wǎng)TDM330之間通過USB接口進(jìn)行傳輸數(shù)據(jù)。同時(shí),TDM芯片主機(jī)端的USB驅(qū)動(dòng)將成為TD無線傳輸項(xiàng)目開發(fā)的必要環(huán)節(jié)。
TDM330設(shè)備支持USB接口連接,應(yīng)用層的數(shù)據(jù)需要通過USB接口與TDM330模塊設(shè)備進(jìn)行交互。根據(jù)USB主機(jī)端驅(qū)動(dòng)[1-2]結(jié)構(gòu)圖(見圖1)可以了解到用戶只能和TTY層、字符設(shè)備等層之間進(jìn)行數(shù)據(jù)的交流,而不能直接與USB驅(qū)動(dòng)層進(jìn)行數(shù)據(jù)的交流。由于TDM330在開發(fā)中僅僅用于數(shù)據(jù)業(yè)務(wù)通信,因此可以把USB設(shè)備驅(qū)動(dòng)的上層看成TTY層。用戶可以通過TTY層與USB設(shè)備驅(qū)動(dòng)層進(jìn)行通信。所以Linux的用戶需要針對(duì)TDM330模塊開發(fā)USB主機(jī)端驅(qū)動(dòng),使之能夠枚舉多個(gè)ttyUSB串口(至少2個(gè)),使其在使用TDM330模塊設(shè)備時(shí),1個(gè)串口用于數(shù)據(jù)的傳輸,1個(gè)串口用于命令的傳輸。例如1個(gè)C口,可以用來進(jìn)行AT命令交互,如啟動(dòng)協(xié)議棧(AT^SPSS=0)。C口一般對(duì)應(yīng)設(shè)備描述名為/dev/ttyUSB1。1個(gè)是D口,用來?yè)芴?hào)。D口一般對(duì)應(yīng)設(shè)備描述名為/dev/ttyUSB0。
圖1 Linux主機(jī)端的驅(qū)動(dòng)
由于USB驅(qū)動(dòng)程序綁定在USB接口而不是USB設(shè)備,所以TDM330模塊USB驅(qū)動(dòng)只需要實(shí)現(xiàn)接口驅(qū)動(dòng)。其針對(duì)TDM330模塊開發(fā)USB接口驅(qū)動(dòng),至少要滿足能夠枚舉出用于命令和數(shù)據(jù)傳輸?shù)?個(gè)tty串口的需要,所以TDM330模塊USB主機(jī)端的驅(qū)動(dòng)還要負(fù)責(zé)將USB轉(zhuǎn)成串口,生成tty串口。
對(duì)于本次開發(fā),由于USB設(shè)備驅(qū)動(dòng)上層可看成tty設(shè)備,不屬于任何USB設(shè)備類型,一般USB都可以使用這個(gè)usbserial模塊驅(qū)動(dòng)來作為主機(jī)端USB設(shè)備驅(qū)動(dòng)。因此,TDM330的主機(jī)端驅(qū)動(dòng)就以u(píng)sbserial模塊作為設(shè)備驅(qū)動(dòng)程序。根據(jù)圖1可知,由于和應(yīng)用層交互數(shù)據(jù)的是TTY層,因此,必須用usbserial模塊把USB設(shè)備映射成一個(gè)tty設(shè)備(即在/dev/目錄下為該USB設(shè)備創(chuàng)建一個(gè)tty設(shè)備文件),然后才能用串口與tty設(shè)備交互數(shù)據(jù)[3],并通過USB接口與設(shè)備端的設(shè)備(TDM330)通信。
分析內(nèi)核 Linux 2.6.10 的./drivers/usb/serial/makefile為:
通過以上的makefile可以得出usbserial模塊主要由usb -serial.c,generic.c 和 bus.c 三部分組成:
1)usb-serial.c就是usbserial模塊的核心,主要用來接收設(shè)備端發(fā)來的數(shù)據(jù)并傳送到上層,同時(shí)也是接收來自上層應(yīng)用的數(shù)據(jù),并組裝成urb包發(fā)送發(fā)給設(shè)備。
2)generic.c是對(duì)某一設(shè)備的單獨(dú)操作,相當(dāng)于設(shè)備自己的驅(qū)動(dòng)程序,由于很多設(shè)備具有通用性,所以對(duì)于沒有特殊要求的設(shè)備都可以使用這個(gè)驅(qū)動(dòng)作為自己的設(shè)備驅(qū)動(dòng)程序。
3)bus.c每個(gè)USB驅(qū)動(dòng)和設(shè)備都必須要?dú)w入某一條總線上,即都是歸屬于某條總線的,只有這樣系統(tǒng)才能從特定的某一條總線開始找每個(gè)驅(qū)動(dòng)和設(shè)備并為之匹配,這個(gè)文件是用來模擬一條總線,而usbserial的每個(gè)驅(qū)動(dòng)和總線都會(huì)注冊(cè)到這條總線上來。
對(duì)于發(fā)送過程。tty設(shè)備文件在獲取了用戶數(shù)據(jù)要求之后傳遞到下層usbserial模塊的核心層,而該模塊核心層就是將數(shù)據(jù)打包成USB格式的數(shù)據(jù),并通過USB主機(jī)控制器發(fā)送到USB設(shè)備端去。
對(duì)于接收過程。usbserial模塊會(huì)在該設(shè)備打開時(shí)啟動(dòng)一個(gè)URB等待設(shè)備發(fā)送數(shù)據(jù)過來,收到數(shù)據(jù)后就調(diào)用push函數(shù)把數(shù)據(jù)推到上層的tty設(shè)備的緩沖區(qū)去,tty設(shè)備收到數(shù)據(jù)以后就直接發(fā)給用戶,或者直接顯示在串口工具上。
Linux操作系統(tǒng)為了擴(kuò)展其功能,使用可動(dòng)態(tài)加載和卸載的內(nèi)核模塊LKM[5]。Linux 使用insmod/modprobe 來加載內(nèi)核模塊,使用rmmod命令來卸載內(nèi)核模塊。LKM的優(yōu)點(diǎn)是可以通過動(dòng)態(tài)加載和卸載內(nèi)核模塊來使內(nèi)核保持很小的尺寸并非常靈活,無須重構(gòu)整個(gè)內(nèi)核來運(yùn)行新的內(nèi)核代碼。
根據(jù)Linux 2.6的makefile寫法[6]寫 USB轉(zhuǎn) serial的usbserial內(nèi)核模塊的makefile,再進(jìn)行make編譯生成usbserial.ko,由于開發(fā)板上的usb轉(zhuǎn)serial芯片被該內(nèi)核識(shí)別為通用芯片,即該內(nèi)核下的Documentationusbusb-serial文檔沒有提到的一些USB轉(zhuǎn)串口芯片,并且由于TDM330的vendorID為0x1234,productID為0X0033,因此只需用命令modprobe usbserial vendor=0x1234 product=0x0033動(dòng)態(tài)加載usbserial.ko時(shí)即可,不用加載USB轉(zhuǎn)serial具體芯片的驅(qū)動(dòng),卸載模塊命令為rmmod usbserial。
開發(fā)板子上電并通過USB接口插上TDM330模塊,運(yùn)行加載usbserial模塊命令,命令為modprobe usbserial vendor=0x1234 product=0x0033,加載這個(gè)模塊以后,詳細(xì)信息如圖2所示。
圖2 加載模塊后的詳細(xì)信息(截圖)
根據(jù)此結(jié)果可以得出,generic converter芯片被檢測(cè)到,并且該芯片的驅(qū)動(dòng)掛載到ttyUSB的3個(gè)設(shè)備文件上,然后用戶就可以像操作tty串口文件一樣的操作該設(shè)備文件。運(yùn)行查看USB設(shè)備所映射的串口ttyUSB設(shè)備文件的命令ls/dev/ttyUSB*[7],具體如圖3所示。
圖3 運(yùn)行命令圖(截圖)
根據(jù)以上結(jié)果可以得出USB設(shè)備映射成ttyUSB0,tty-USB1,ttyUSB2三個(gè)設(shè)備文件。應(yīng)用程序通過這些文件可對(duì)實(shí)際的USB進(jìn)行操作。用串行通信調(diào)試工具(SCT)進(jìn)行串口通信調(diào)試。調(diào)試步驟為:1)運(yùn)行命令sct啟動(dòng)協(xié)議棧;2)通過命令setbuf 1 hex設(shè)置buf1的數(shù)據(jù);3)通過命令port/dev/ttyUSB0指定使用的端口;4)通過命令open打開指定的端口;5)通過命令sendrecv 10向打開的端口發(fā)送buf 1的數(shù)據(jù),并把接收的數(shù)據(jù)存到buf 0,同時(shí)在終端顯示接收到的數(shù)據(jù)。如圖4所示。
圖4 顯示結(jié)果(截圖)
根據(jù)以上結(jié)果的分析得出,已經(jīng)把USB設(shè)備映射為串口設(shè)備,相應(yīng)的驅(qū)動(dòng)已經(jīng)掛載在相應(yīng)的接口上,并且可以通過串口ttyUSB*來操作USB設(shè)備。這樣就可以通過PPP撥號(hào)與無線網(wǎng)絡(luò)連接在一起,然后應(yīng)用于TD網(wǎng)絡(luò)的無線傳輸。
[1]夏傳凱,吳乃陵.基于AT91RM9200的USB主機(jī)端的linux驅(qū)動(dòng)[J].現(xiàn)代電子技術(shù),2008(12):49-50.
[2]孫天澤,袁文菊,張海峰,等.嵌入式設(shè)計(jì)及Linux驅(qū)動(dòng)開發(fā)指南-基于ARM9處理器[M].北京:電子工業(yè)出版社,2007.
[3]宋寶華.Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解[M].北京:人民郵電出版社,2008.
[4]徐維迪,石紹應(yīng),喬建軍.Linux環(huán)境USB轉(zhuǎn)串口設(shè)備的驅(qū)動(dòng)程序開發(fā)[J].空軍雷達(dá)學(xué)院學(xué)報(bào),2008,22(1):65 -67.
[5]羅苑棠.嵌入式Linux驅(qū)動(dòng)程序和系統(tǒng)開發(fā)實(shí)例講解[M].北京:電子工業(yè)出版社,2009.
[6]陳剛,盧顯斌.基于linux-2.6內(nèi)核模塊程序設(shè)計(jì)[J].福建電腦,2004(6):15-16.
[7]周金和,劉泉華.基于ISP1161的USB攝像頭嵌入式Linux設(shè)備驅(qū)動(dòng)[J].電視技術(shù),2006,30(3):81 -84.