摘 要: 本文以套接字Socket 為基礎,提出并設計了一種跨平臺嵌入式實時系統(tǒng)的通信模型,并根據(jù)這種模型給出了示范。
關(guān)鍵詞: 跨平臺;嵌入式實時系統(tǒng);套接字
引言
當前嵌入式系統(tǒng)正以前所未有的速度發(fā)展,并廣泛應用到通信、軍事、航空、航天、工業(yè)控制等高精尖技術(shù)及實時性要求極高的領(lǐng)域中。在這些領(lǐng)域中,迫切需要一個能夠讓日益增多的嵌入式設備相互通信的解決方案。同時,由于嵌入式系統(tǒng)的專用性強,在不同領(lǐng)域的嵌入式設備往往使用不同的嵌入式實時操作系統(tǒng)。這樣就為構(gòu)建一個統(tǒng)一的通信平臺帶來了困難。當前微軟公司正大力開發(fā)用于工業(yè)領(lǐng)域的Windows CE 嵌入式平臺,作為工業(yè)控制領(lǐng)域的領(lǐng)導廠商,泓格積極倡導和順應這一趨勢,經(jīng)過兩年不懈地開發(fā)和測試,泓格于2003 年領(lǐng)先推出了基于Windows CE.NET 和RISC CPU 架構(gòu)的嵌入式控制系統(tǒng)WinCon-8000 系列,并于2003 年10 月與微軟WEP 部門(Microsoft Windows Embedded Partner Program)正式建立了合作關(guān)系。這一充滿活力的產(chǎn)品一經(jīng)推出,就獲得了國內(nèi)各界專家的好評,并被浙江大學、華東理工大學等知名高校選作自動化等相關(guān)專業(yè)的試驗平臺。
本文介紹一個采用泓格科技(ICP DAS)的全系列產(chǎn)品實現(xiàn)不同平臺下的嵌入式系統(tǒng)的通信方案。
設計目標
靈巧性
完備的嵌入式系統(tǒng)大都具備嵌入式實時操作系統(tǒng),絕大多數(shù)實時操作系統(tǒng)都帶有網(wǎng)絡協(xié)議棧,利用網(wǎng)絡協(xié)議就可以構(gòu)建通信平臺。TCP/IP 協(xié)議簇是目前使用最廣泛的一種網(wǎng)絡通信協(xié)議。當前,基于TCP/IP 的流行應用,存在功能單一、消耗系統(tǒng)資源等問題。而嵌入式設備一般通信量不大,同時系統(tǒng)資源有限,不能支持大型的應用。所以,嵌入式設備間的通信應當實現(xiàn)簡單、可靈活增減。
實時性
實時系統(tǒng)要求系統(tǒng)能夠在規(guī)定的時間內(nèi)對外部事件給予響應。但在不同應用中,通信的嵌入式設備間的物理距離不同,使用的通信方式也不盡相同。通信延遲是影響實時系統(tǒng)的主要因素之一。在近距離通信中,可以采用高速通信線路,但是在遠距離通信中,則通信線路的選擇余地較小。在低速通信線路中,為了提高系統(tǒng)的實時性能,嵌入式實時系統(tǒng)的通信需要設計成多線程多任務,確保每個通信請求都有單獨的線程來處理,這樣可以保證系統(tǒng)對通信的及時響應。
穩(wěn)定性
嵌入式實時系統(tǒng)大都具備繁重的測量和運算任務。嵌入式實時系統(tǒng)同時運行大量任務,不能保證系統(tǒng)永不出現(xiàn)問題,但通信任務不能受嵌入式設備本身任務的影響。因此,在設計中,需要把通信任務和實際的檢測控制任務分離。用一個專門的任務處理通信事件,同時設立一個緩沖區(qū)保證通信數(shù)據(jù)能夠被及時保存。
通用性
嵌入式實時操作系統(tǒng)種類繁多,目前尚無一種操作系統(tǒng)在嵌入式領(lǐng)域占絕對優(yōu)勢。嵌入式設備的跨平臺通信必須能夠適用于各種常見的實時操作系統(tǒng),能將不同實時操作系統(tǒng)的嵌入式設備聯(lián)網(wǎng)。
實現(xiàn)方案
根據(jù)嵌入式實時系統(tǒng)不同平臺通信的特點,可以采用如下方案設計:
跨平臺通信
通信部分采用大多數(shù)實時操作系統(tǒng)都支持的TCP/IP 協(xié)議簇作為系統(tǒng)的基本協(xié)議。為了方便使用,采用基于TCP/IP 的套接字。套接字是一種仿照電話系統(tǒng)設計,并在UNIX 上得到成功應用的進程通信機制,它提供進程間通信的端點。通信之前,進程雙方都創(chuàng)建一個端點,服務器端綁定一個固定的端口,客戶端則可以隨機的申請一個端口。客戶可以通過網(wǎng)絡向服務器的端口發(fā)送連接請求,服務器端接收到請求后允許客戶端的連接。這樣,服務器端和客戶端就建立了一個雙向的通信通道。
套接字分為三種類型:流套接字、數(shù)據(jù)包套接字、原始套接字。流套接字可以提供可靠的、面向連接的通信流,有固定的發(fā)送和接收順序,采用TCP 和IP 協(xié)議。數(shù)據(jù)包套接字是一種無連接的數(shù)據(jù)服務,數(shù)據(jù)通過相互獨立的報文進行無序傳輸,使用UDP 和IP 協(xié)議,它允許對底層協(xié)議如IP 或ICMP 直接訪問。原始套接字雖然功能強大,但是使用較復雜,主要用于一些協(xié)議的開發(fā)和測試工作。
通信處理程序設計成多線程方式。一旦其它嵌入式設備發(fā)起連接就啟動一個線程或任務專門處理對外部嵌入式設備發(fā)送過來的數(shù)據(jù),通過解析確定數(shù)據(jù)的類別并轉(zhuǎn)入相應的處理函數(shù)。處理函數(shù)的多少可以根據(jù)實際應用確定,這樣可以最大限度地利用有限的系統(tǒng)資源。
通信數(shù)據(jù)處理
利用命名管道或共享內(nèi)存技術(shù),建立一個介于嵌入式設備實際任務和通信處理任務間的緩沖區(qū)。
如果通信中嵌入式設備需要連續(xù)數(shù)據(jù)交換,可以使用管道技術(shù)。命名管道支持單向和雙向進程或任務間的通信。命名管道有兩種實現(xiàn)方式:字節(jié)模式和消息模式。在字節(jié)模式中,消息以一個連續(xù)的字節(jié)流的形式,在客戶機與服務器之間流動。這意味著,對進程雙方來說,在任何一個特定的時間段內(nèi),它們不能準確知道有多少字節(jié)從管道中讀入或者寫入管道。在消息模式中,客戶機和服務器則通過一系列不連續(xù)的數(shù)據(jù)單位,進行數(shù)據(jù)的收發(fā)。每次在管道上發(fā)出了一條消息后,它必須作為一條完整的消息讀入。因此,消息模式比較適合通信任務和實時任務的數(shù)據(jù)交換。
如果通信中嵌入式設備只要瞬時數(shù)據(jù)交換,則可以采用共享內(nèi)存方式構(gòu)造緩沖區(qū)。簡單說地共享內(nèi)存就是被多個進程共享的內(nèi)存。共享內(nèi)存方式是進程間通信方法中最快的一種,它可以將信息直接映射到內(nèi)存中,省去了許多中間步驟。利用共享內(nèi)存方式實現(xiàn)進程通信,需要注意進程間的同步問題。如果通信量不大的話,最簡單的方法就是對進程雙方給予不同權(quán)限(讀或?qū)懀?,這樣就可以省去復雜的同步機制。通信方案的結(jié)構(gòu)框圖如圖1 所示,嵌入式設備間的通信流程如圖2 所示。
[align=center]

圖1 通信方案的結(jié)構(gòu)框圖

圖2 嵌入式設備的通信流程[/align]
部分代碼示例
下面給出在兩個常見的嵌入式設備操作系統(tǒng)下通信的實現(xiàn)代碼:
主動通信方代碼
主動通信方選擇WinCE 為操作系統(tǒng)。WinCE 與Windows2000 都是使用WinSocket,因此編程方法基本相同。
#include "Winsock2.h"
#include "Windows.h"
WSADATA wsaData;//使用的WinSocket 版本
//使用的通信協(xié)議標志
struct protoent *ppe;
//待通信Socket 的地址
struct sockaddr_in daddr;
//讀寫數(shù)據(jù)長度
DWORD cbRead=0,cbWritten=0;
BOOL fSuccess=false;//通信標志
//通信程序
DWORD HostConnect(void)
{
//確定使用WinSocket 的版本
WSAStartup(MAKEWORD (2,2),&wsaData );
//創(chuàng)建一個基于TCP 的套接字
ppe=getprotobyname("tcp");
SOCKETClientSocket=socket (PF_INET,SOCK_STREAM,ppe->p_proto);
//連接一個套接字
//使用TCP 協(xié)議
daddr.sin_family=AF_INET;
//設定待連接的端口
daddr.sin_port=htons(TargetPort); daddr.sin_addr.s_addr=inet_addr
(TargetIPAddress);//設定待連接設備的IP 地址
//連接目的嵌入式設備
if(connect(ClientSocket,(struct sockaddr *)&daddr,sizeof(daddr)))
{closesocket(ClientSocket);}
else
{
//發(fā)送消息
......//準備發(fā)送的數(shù)據(jù)
cbWritten=send(ClientSocket,SData,strlen(SD ata)),MSG_DONTROUTE);
//接收消息
do
{
cbRead=recv(ClientSocket,RData,50,MSG_PEEK);
if(cbRead>0) {fSuccess=true;}
}while(!fSuccess);
...... //數(shù)據(jù)處理
//關(guān)閉Socket
closesocket(ClientSocket)
}
return(0);
}
被動通信方代碼
被動通信方選擇VxWorks 為操作系統(tǒng)。Linux 與VxWorks 都可以使用BSD Socket,因此編程方法基本相同。通信任務和實時任務的數(shù)據(jù)交換以管道方式為例。
#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "taskLib.h"
//本機Socket 地址
struct sockaddr_in serverAddr;
//目標通信機Socket 地址
struct sockaddr_in clientAddr;
int sFd; //監(jiān)聽Socket 描述苻
int newFd; //被連接Socket 描述苻
int ix=0;//被連接的Socket 數(shù)目
//啟動管道函數(shù)
void SetupPipe(void)
{
pipeDrv();//管道驅(qū)動
//管道建立
pipeDevCreate(“\pipe\ mypipe”,20,40);
}
//主通信函數(shù)
void Server(void)
{
//使用TCP/IP 協(xié)議
serverAddr.sin_family = AF_INET;
serverAddr.sin_len = sizeof (struct sockaddr_in);
//本機提供通信的端口
serverAddr.sin_port = htons(HostPort);
serverAddr.sin_addr.s_addr = htonl (HostIP);//本機IP 地址
//創(chuàng)建Socket
sFd = socket (AF_INET, SOCK_STREAM, 0);
//綁定Socket
bind (sFd, (struct sockaddr *) &serverAddr, sockAddrSize);
//監(jiān)聽Socket
listen (sFd, SERVER_MAX_CONNECTIONS);
//等待通信事件發(fā)生
FOREVER
{
newFd = accept (sFd, (struct sockaddr *) &clientAddr,&sockAddrSize);
sprintf (workName, "tTcpWork%d", ix++);
taskSpawn(workName, NORMAL_PRIORITY, 0,
NORMAL_STACK_SIZE,(FUNCPTR) tcpCommunicateTask, newFd,(int) 0,
0,0, 0, 0, 0, 0, 0, 0);
}
}
//已連接的通信的處理函數(shù)
void tcpCommunicateTask(int sFd,)
{
do
{
//讀取數(shù)據(jù)
ReadBytes=recv(sFd,chRequest, sizeof(chRequest),MSG_PEEK);
if(ReadBytes == 0) break;
else RSuccess=true;
GetAnswerToRequest(chRequest, chReply,&ReplyBytes);//數(shù)據(jù)處理
//返回數(shù)據(jù)
WriteBytes = send (sFd, chReply, ReplyBytes ,MSG_DONTROUTE);
if ( WriteBytes!= ReplyBytes) break;
else WSuccess=true;
}while(!(RSuccess && WSuccess));
//關(guān)閉Socket
close (sFd);
}
//處理數(shù)據(jù)函數(shù)
void GetAnswerToRequest(char * Request, char * Reply, int * ReplyBytes)
{
//打開管道(每個任務有不同的管道)
int fd=open("\pipe\mypipe", O_RDWR,0);
......//相應的數(shù)據(jù)交換
}
結(jié)語
使用這種嵌入式實時系統(tǒng)的跨平臺通信方案,不但可以實現(xiàn)嵌入式設備異平臺的互聯(lián)互通,而且給系統(tǒng)靈活組織帶來方便。多任務的處理方式以及通信任務的分離大大提高了系統(tǒng)的實時性和穩(wěn)定性。作者據(jù)此方案采用泓格科技(ICP DAS)的全系列產(chǎn)品包括PCI 和ISA 接口工業(yè)數(shù)據(jù)采集卡和嵌入式控制系統(tǒng)WinCon-8000 系列等產(chǎn)品建立的基于嵌入式設備的遠程數(shù)據(jù)采集系統(tǒng)運行穩(wěn)定,取得了良好的效果,當然這以泓格科技在中國提供及時、到位的服務及技術(shù)支持和質(zhì)量過硬的系列產(chǎn)品是分不開的。
參考文獻
1 VxWorks(r) 5.4 Programmer‘s Guide. Wind River Inc, 1999.6
2 Anthony Jones. Network Programming for Microsoft Windows. Microsoft Press,1999
3 李卓桓等. Linux 網(wǎng)絡編程. 北京:機械工業(yè)出版社. 2000.1
4 李朝青.PC 機及單片機數(shù)據(jù)通信技術(shù).北京:北京航空航天出版社.2000
5 原嵩,林滸.通用串行總線的原理及實現(xiàn). 小型微行計算機系統(tǒng).1999(5)
6 張洪潤,藍清華.單片機應用技術(shù)教程. 北京:清華大學出版社.1997