1 引言
計算機(jī)與外部設(shè)備進(jìn)行通訊可以采用不同的接口實現(xiàn),常用的是串行接口、網(wǎng)絡(luò)適配器和并行接口。其中串行通訊技術(shù)已經(jīng)很成熟,具有便利和低成本的特點(diǎn)。隨著計算機(jī)網(wǎng)絡(luò)的不斷發(fā)展,網(wǎng)絡(luò)作為獲取信息的便捷手段,已經(jīng)逐漸被人們所共識。帶有串口接入和網(wǎng)絡(luò)接入功能的嵌入式設(shè)備可以實現(xiàn)任何人在任何地方任何時間方便地獲取其運(yùn)行數(shù)據(jù),監(jiān)控其運(yùn)行狀況。嵌入式操作系統(tǒng)是嵌入式設(shè)備軟件的核心部分,由于它的存在,使得嵌入式設(shè)備的功能具有很大的擴(kuò)展空間和伸縮性能。
μCLinux是針對控制領(lǐng)域的嵌入式Linux操作系統(tǒng),它沿襲了主流Linux的絕大部分特性,適合不具備內(nèi)存管理單元MMU(Memory Management Unit)的微處理器/微控制器,支持多任務(wù),具有完備的傳輸通訊控制協(xié)議/網(wǎng)際協(xié)議(TCP/IP協(xié)議)和點(diǎn)對點(diǎn)協(xié)議PPP(Point to Point Protocol),并支持多種網(wǎng)絡(luò)協(xié)議和文件系統(tǒng)。μCLinux以其優(yōu)異的性能、免費(fèi)開放的代碼等優(yōu)點(diǎn),博得眾多嵌入式開發(fā)者的青睞,在低端網(wǎng)絡(luò)設(shè)備、工業(yè)控制領(lǐng)域、數(shù)據(jù)采集和傳輸?shù)确矫嬗兄絹碓綇V泛的應(yīng)用。利用這種成熟、高效、可靠、模塊化、易于配置的操作系統(tǒng)來開發(fā)應(yīng)用程序,無疑能進(jìn)一步提高效率,并具有很好的可移植性。
為此,利用TCP套接字方式、PPPd撥號方式以及高速串口通訊方式在嵌入式μCLinux系統(tǒng)間以及嵌入式μCLinux系統(tǒng)和Windows系統(tǒng)組成的通訊系統(tǒng)中,實現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)通訊方案,充分利用μCLinux系統(tǒng)對多種通訊協(xié)議的支持優(yōu)勢,實現(xiàn)多種通訊模式的自由選擇和通訊方式的轉(zhuǎn)換,完成傳遞數(shù)據(jù)信息、實時采集數(shù)據(jù)等功能。
2 通訊模塊的總體設(shè)計
2.1 通訊模塊的功能要求
近年來,隨著光纖技術(shù)的不斷發(fā)展和完善,以太網(wǎng)已經(jīng)成為人們進(jìn)行數(shù)據(jù)傳輸和信息交流的重要手段,然而傳統(tǒng)的串口通訊方式由于其低廉的硬件成本和簡單便利的連接方式在數(shù)據(jù)傳輸中仍然占有重要位置。本嵌入式系統(tǒng)的硬件設(shè)計充分考慮了上述兩種通訊方式的優(yōu)越性和提供設(shè)備的使用范圍的要求,提供了兩種通訊方式的硬件接口;通訊程序的設(shè)計充分考慮了對硬件資源的支持,并保證軟件具有良好的可靠性和維護(hù)方便性。
整個系統(tǒng)的開發(fā)和運(yùn)行過程中用到的通訊方式有Socket網(wǎng)絡(luò)通訊方式和COM口串行通訊方式兩類。其中串行通訊方式又可分為計算機(jī)與嵌入式設(shè)備直接通過串口連接的通訊方式和通過Modem撥號連接的通訊方式兩種。因此軟件要實現(xiàn)對上述三種通訊方式的支持,并保證通訊方式選擇的簡便性。
2.2 總體方案實現(xiàn)
圖1 通訊模塊工作流程
考慮到該模塊的功能要求,在通訊模塊的設(shè)計中將這三種通訊方式集成到一個通訊系統(tǒng)中,通過一個控制類實現(xiàn)對通訊方式的控制。采用配置文件的方式將通訊方式和通訊參數(shù)寫入到該配置文件,這樣在選擇通訊方式時只需要在配置文件中修改相應(yīng)的參數(shù)就可以實現(xiàn),滿足系統(tǒng)對不同通訊方式轉(zhuǎn)換的簡單操作要求。通訊模塊的總體設(shè)計流程如圖1所示。
嵌入式系統(tǒng)啟動后,軟件的運(yùn)行會調(diào)用讀配置文件程序?qū)ο到y(tǒng)的各種配置參數(shù)進(jìn)行檢查。對于通訊模塊,主要配置項目是設(shè)備的連接類型和對應(yīng)的基本參數(shù),程序讀到正確配置后記錄下這些參數(shù),進(jìn)入通訊控制類程序判斷設(shè)備的連接類型并調(diào)用相應(yīng)的連接程序。根據(jù)參數(shù)信息設(shè)置該連接所需要的配置,等待與外部設(shè)備的通訊。
3 Socket通訊程序設(shè)計
3.1 基本原理
數(shù)據(jù)在以太網(wǎng)上的傳輸和接收都必須遵循以太網(wǎng)絡(luò)的通訊協(xié)議,在一系列以太網(wǎng)絡(luò)通訊協(xié)議中,核心協(xié)議是傳輸層的TCP/IP協(xié)議。TCP協(xié)議是面向連接的,通訊雙方保持一條通道,為了保證網(wǎng)絡(luò)傳輸?shù)恼_性和有效性,必須進(jìn)行一系列復(fù)雜的糾錯和排序等處理[1]。網(wǎng)絡(luò)通訊中,基于TCP/IP協(xié)議的通訊方式有很多,根據(jù)應(yīng)用需要,選用最常用的套接字Socket實現(xiàn)服務(wù)器端和客戶端(C/S)的數(shù)據(jù)通訊。
μCLinux系統(tǒng)是嵌入式Linux的一個分支,帶有完整的TCP/IP協(xié)議,支持Socket規(guī)范。在實際應(yīng)用中,把μCLinux系統(tǒng)的嵌入式裝置作為服務(wù)器端,外部與它連接的裝置作為客戶端。μCLinux系統(tǒng)中的服務(wù)器端應(yīng)用程序,主要是用來接收客戶端的連接請求,接收和處理客戶端的信息,向客戶端發(fā)送計算結(jié)果和應(yīng)答信息等。在開發(fā)μCLinux系統(tǒng)下的Socket程序時,采用面向連接的TCP-Socket,它提供了一種可靠的面向連接的數(shù)據(jù)傳輸方法,有自己的檢錯和糾錯機(jī)制,并且不管是對單個數(shù)據(jù)報,還是對于數(shù)據(jù)包,它提供了一種流式數(shù)據(jù)傳輸方式。
3.2 程序設(shè)計與實現(xiàn)[2]
在μCLinux系統(tǒng)中用GNU C實現(xiàn)TCP套接字編程,關(guān)鍵是利用μCLinux系統(tǒng)的μClibc函數(shù)庫,服務(wù)器端程序就使用其通用接口函數(shù)(socket(), listen(), accept()等)完成[3]。服務(wù)器程序流程如圖2所示。
圖2 服務(wù)器端程序工作流程
(1) 服務(wù)器程序的第一個操作是創(chuàng)建一個套接字,這是通過調(diào)用函數(shù)socket()實現(xiàn)的。Sockfd=socket(AF_INET, SOCK_STREAM, 0);
(2) 調(diào)用bind()函數(shù)綁定服務(wù)器的地址和套接字,bind(sockfd, (struct sockaddr*)& seraddr, sizeof (struct sockaddr));
(3) 服務(wù)器需要將當(dāng)前與IP地址和端口號完成綁定的套接字轉(zhuǎn)換成偵聽套接字,調(diào)用listen()函數(shù)偵聽連接,listen(int sockfd, int backlog),其中sockfd是綁定后的文件描述符,backlog設(shè)置請求排隊的最大長度;
(4) 服務(wù)器程序進(jìn)入一個無條件循環(huán),監(jiān)聽來自客戶端的連接請求,在此過程中如果有客戶機(jī)請求連接,服務(wù)器程序就會調(diào)用accept()從偵聽套接字的連接隊列中接受一個連接請求,new_fd=accept(sockfd, (struct sockaddr*) &their_addr, &sin_size));
(5) 服務(wù)器程序接收請求后,由vfork()創(chuàng)建子進(jìn)程,子進(jìn)程通過由accept()建立的套接字描述符和客戶機(jī)通訊,符程序繼續(xù)監(jiān)聽來自客戶端的請求。需要注意的是μCLinux系統(tǒng)的API函數(shù)與標(biāo)志的Linux基本相同,但其μClibc函數(shù)庫中多進(jìn)程管理通過vfork()函數(shù)實現(xiàn),而不是通常的fork()函數(shù)[4]。
4 串口通訊程序設(shè)計
4.1 基本原理
串行口是計算機(jī)一種常用的接口,具有連接線少,通訊簡單,得到廣泛的使用。常用的串口是 RS-232-C 接口(又稱 EIA RS-232-C),它是在 1970 年由美國電子工業(yè)協(xié)會(EIA)聯(lián)合貝爾系統(tǒng)、 調(diào)制解調(diào)器廠家及計算機(jī)終端生產(chǎn)廠家共同制定的用于串行通訊的標(biāo)準(zhǔn)。
串行通信協(xié)議分為同步協(xié)議和異步協(xié)議。異步協(xié)議的特點(diǎn)是一個字符一個字符傳輸,并且傳送一個字符總是以起始位開始,以停止位結(jié)束,字符之間沒有固定的時間間隔要求。每一個字符的前面都有一位起始位,字符本身有5~7位數(shù)據(jù)位組成,接著字符后面是一位校驗位(也可以沒有校驗位),最后是一位或一位半或二位停止位,停止位后面是不定長度的空閑位。同步協(xié)議分為面向字符的同步協(xié)議和面向比特的同步協(xié)議。面向字符的同步協(xié)議一次傳送由若干個字符組成的數(shù)據(jù)塊,并規(guī)定了10個字符作為這個數(shù)據(jù)塊的開頭與結(jié)束標(biāo)志以及整個傳輸過程的控制信息,它們也叫做通信控制字;面向比特的同步協(xié)議特點(diǎn)是所傳輸?shù)囊粠瑪?shù)據(jù)可以是任意位,而且它是靠約定的位組合模式,而不是靠特定字符來標(biāo)志幀的開始和結(jié)束。
4.2 程序設(shè)計與實現(xiàn)
μCLinux對串口協(xié)議提供了完整的支持,由于Linux系統(tǒng)在處理任何設(shè)備時都把設(shè)備看作一個文件,因此對于串口設(shè)備,Linux系統(tǒng)也把對串口的操作看作對文件I/O的操作,調(diào)用系統(tǒng)庫函數(shù)open(), read(), write()等實現(xiàn)串口的創(chuàng)建和對串口數(shù)據(jù)的讀寫等操作[5]。程序流程如圖3所示。
圖3 串口程序工作流程
(1) 串口程序的第一個操作是創(chuàng)建一個串口文件,(Linux系統(tǒng)對串口設(shè)備有自己的定義方式,/dev/ttyS0為Windows中的COM0,/dev/ttyS1為Windows中的COM1,以此類推。)調(diào)用函數(shù)open()實現(xiàn),comfd=open("/dev/ttyS0", O_RDWD);
(2) 接下來就是設(shè)置串口參數(shù),包括波特率、數(shù)據(jù)位、流控制、開始位和停止位等,這些參數(shù)是保證串口能否正確通訊的條件;
(3) 正確設(shè)置了通訊參數(shù)后,就可以讀取該串口中的數(shù)據(jù),數(shù)據(jù)的讀取是調(diào)用read()函數(shù)實現(xiàn)的,readlen=read(comfd, char *buff, int bufflen);
(4) 如果系統(tǒng)需要向外界發(fā)送數(shù)據(jù),要調(diào)用write()函數(shù)實現(xiàn),writelen=write(comfd, char *buff, int bufflen)。
5 遠(yuǎn)程串口通訊的設(shè)計和實現(xiàn)
本系統(tǒng)要求實現(xiàn)在不具備以太網(wǎng)線路的條件下,通過電話線和Modem撥號方式實現(xiàn)該嵌入式設(shè)備與外部設(shè)備的連接通訊方式。Linux系統(tǒng)提供了PPP協(xié)議來實現(xiàn)Modem的撥出和撥入功能。PPP協(xié)議提供了一種通過串行點(diǎn)對點(diǎn)聯(lián)接傳輸數(shù)據(jù)報的方式。它由一種在串行封裝數(shù)據(jù)報的方式,擴(kuò)展聯(lián)接控制協(xié)議LCP和用來建立及配置不同網(wǎng)絡(luò)層協(xié)議的家族網(wǎng)絡(luò)控制協(xié)議NCP三部份組成。封裝方案由內(nèi)核驅(qū)動代碼來提供,pppd(ppp daemon)提供基本的LCP認(rèn)證支持,建立和配置IP的網(wǎng)絡(luò)控制協(xié)議NCP。一個PPP會話分為四個步驟:連接建立、連接質(zhì)量控制、網(wǎng)絡(luò)層協(xié)議配置、連接終止;提供了密碼認(rèn)證協(xié)議(PAP)或者邀請握手認(rèn)證協(xié)議(CHAP)來保證連接安全[6]。
在嵌入式系統(tǒng)中,只要安裝有pppd工具,配置該嵌入式系統(tǒng)作為PPP服務(wù)器端,就可以方便實現(xiàn)Modem的撥入及與外部設(shè)備的通訊。本部分程序的功能相對簡單,主要實現(xiàn)打開本地串口設(shè)置串口的通訊參數(shù)(與串口通訊的設(shè)置方法相同),初始化與串口連接的Modem,然后等待外部的撥入轉(zhuǎn)給pppd程序處理。
6 結(jié)語
工程應(yīng)用中,嵌入式設(shè)備能否對多種通訊方式提供支持,是衡量該設(shè)備是否具有廣泛使用性的關(guān)鍵指標(biāo)之一。不僅提供網(wǎng)絡(luò)接口,還提供了傳統(tǒng)的串行接口的嵌入式設(shè)備,本文提供了將多種通訊方式的通訊程序集成到一個通訊模塊中的一種方法,不僅可以實現(xiàn)系統(tǒng)對多重通訊方式的支持要求,同時實現(xiàn)了通訊方式選擇的簡便性和通訊參數(shù)配置的簡單性。