嵌入式實(shí)時(shí)系統中跨平臺通信的實(shí)現
關(guān)鍵詞: 跨平臺;嵌入式實(shí)時(shí)系統;套接字
引言
當前嵌入式系統正以前所未有的速度發(fā)展,并廣泛應用到通信、軍事、航空、航天、工業(yè)控制等高精尖技術(shù)及實(shí)時(shí)性要求極高的領(lǐng)域中。在這些領(lǐng)域中,迫切需要一個(gè)能夠讓日益增多的嵌入式設備相互通信的解決方案。同時(shí),由于嵌入式系統的專(zhuān)用性強,在不同領(lǐng)域的嵌入式設備往往使用不同的嵌入式實(shí)時(shí)操作系統。這樣就為構建一個(gè)統一的通信平臺帶來(lái)了困難。本文介紹一個(gè)不同平臺下的嵌入式系統的通信實(shí)現方案。
設計目標
靈巧性
完備的嵌入式系統大都具備嵌入式實(shí)時(shí)操作系統,絕大多數實(shí)時(shí)操作系統都帶有網(wǎng)絡(luò )協(xié)議棧,利用網(wǎng)絡(luò )協(xié)議就可以構建通信平臺。TCP/IP協(xié)議簇是目前使用最廣泛的一種網(wǎng)絡(luò )通信協(xié)議。當前,基于TCP/IP的流行應用,存在功能單一、消耗系統資源等問(wèn)題。而嵌入式設備一般通信量不大,同時(shí)系統資源有限,不能支持大型的應用。所以,嵌入式設備間的通信應當實(shí)現簡(jiǎn)單、可靈活增減。
實(shí)時(shí)性
實(shí)時(shí)系統要求系統能夠在規定的時(shí)間內對外部事件給予響應。但在不同應用中,通信的嵌入式設備間的物理距離不同,使用的通信方式也不盡相同。通信延遲是影響實(shí)時(shí)系統的主要因素之一。在近距離通信中,可以采用高速通信線(xiàn)路,但是在遠距離通信中,則通信線(xiàn)路的選擇余地較小。在低速通信線(xiàn)路中,為了提高系統的實(shí)時(shí)性能,嵌入式實(shí)時(shí)系統的通信需要設計成多線(xiàn)程多任務(wù),確保每個(gè)通信請求都有單獨的線(xiàn)程來(lái)處理,這樣可以保證系統對通信的及時(shí)響應。
穩定性
嵌入式實(shí)時(shí)系統大都具備繁重的測量和運算任務(wù)。嵌入式實(shí)時(shí)系統同時(shí)運行大量任務(wù),不能保證系統永不出現問(wèn)題,但通信任務(wù)不能受嵌入式設備本身任務(wù)的影響。因此,在設計中,需要把通信任務(wù)和實(shí)際的檢測控制任務(wù)分離。用一個(gè)專(zhuān)門(mén)的任務(wù)處理通信事件,同時(shí)設立一個(gè)緩沖區保證通信數據能夠被及時(shí)保存。
通用性
嵌入式實(shí)時(shí)操作系統種類(lèi)繁多,目前尚無(wú)一種操作系統在嵌入式領(lǐng)域占絕對優(yōu)勢。嵌入式設備的跨平臺通信必須能夠適用于各種常見(jiàn)的實(shí)時(shí)操作系統,能將不同實(shí)時(shí)操作系統的嵌入式設備聯(lián)網(wǎng)。
圖1 通信方案的結構框圖
圖2 嵌入式設備的通信流程
實(shí)現方案
根據嵌入式實(shí)時(shí)系統不同平臺通信的特點(diǎn),可以采用如下方案設計:
跨平臺通信
通信部分采用大多數實(shí)時(shí)操作系統都支持的TCP/IP協(xié)議簇作為系統的基本協(xié)議。為了方便使用,采用基于TCP/IP的套接字。套接字是一種仿照電話(huà)系統設計,并在UNIX上得到成功應用的進(jìn)程通信機制,它提供進(jìn)程間通信的端點(diǎn)。通信之前,進(jìn)程雙方都創(chuàng )建一個(gè)端點(diǎn),服務(wù)器端綁定一個(gè)固定的端口,客戶(hù)端則可以隨機的申請一個(gè)端口??蛻?hù)可以通過(guò)網(wǎng)絡(luò )向服務(wù)器的端口發(fā)送連接請求,服務(wù)器端接收到請求后允許客戶(hù)端的連接。這樣,服務(wù)器端和客戶(hù)端就建立了一個(gè)雙向的通信通道。
套接字分為三種類(lèi)型:流套接字、數據包套接字、原始套接字。流套接字可以提供可靠的、面向連接的通信流,有固定的發(fā)送和接收順序,采用TCP和IP協(xié)議。數據包套接字是一種無(wú)連接的數據服務(wù),數據通過(guò)相互獨立的報文進(jìn)行無(wú)序傳輸,使用UDP和IP協(xié)議,它允許對底層協(xié)議如IP或ICMP直接訪(fǎng)問(wèn)。原始套接字雖然功能強大,但是使用較復雜,主要用于一些協(xié)議的開(kāi)發(fā)和測試工作。
通信處理程序設計成多線(xiàn)程方式。一旦其它嵌入式設備發(fā)起連接就啟動(dòng)一個(gè)線(xiàn)程或任務(wù)專(zhuān)門(mén)處理對外部嵌入式設備發(fā)送過(guò)來(lái)的數據,通過(guò)解析確定數據的類(lèi)別并轉入相應的處理函數。處理函數的多少可以根據實(shí)際應用確定,這樣可以最大限度地利用有限的系統資源。
通信數據處理
利用命名管道或共享內存技術(shù),建立一個(gè)介于嵌入式設備實(shí)際任務(wù)和通信處理任務(wù)間的緩沖區。
如果通信中嵌入式設備需要連續數據交換,可以使用管道技術(shù)。命名管道支持單向和雙向進(jìn)程或任務(wù)間的通信。命名管道有兩種實(shí)現方式:字節模式和消息模式。在字節模式中,消息以一個(gè)連續的字節流的形式,在客戶(hù)機與服務(wù)器之間流動(dòng)。這意味著(zhù),對進(jìn)程雙方來(lái)說(shuō),在任何一個(gè)特定的時(shí)間段內,它們不能準確知道有多少字節從管道中讀入或者寫(xiě)入管道。在消息模式中,客戶(hù)機和服務(wù)器則通過(guò)一系列不連續的數據單位,進(jìn)行數據的收發(fā)。每次在管道上發(fā)出了一條消息后,它必須作為一條完整的消息讀入。因此,消息模式比較適合通信任務(wù)和實(shí)時(shí)任務(wù)的數據交換。
如果通信中嵌入式設備只要瞬時(shí)數據交換,則可以采用共享內存方式構造緩沖區。簡(jiǎn)單說(shuō)地共享內存就是被多個(gè)進(jìn)程共享的內存。共享內存方式是進(jìn)程間通信方法中最快的一種,它可以將信息直接映射到內存中,省去了許多中間步驟。利用共享內存方式實(shí)現進(jìn)程通信,需要注意進(jìn)程間的同步問(wèn)題。如果通信量不大的話(huà),最簡(jiǎn)單的方法就是對進(jìn)程雙方給予不同權限(讀或寫(xiě)),這樣就可以省去復雜的同步機制。通信方案的結構框圖如圖1所示,嵌入式設備間的通信流程如圖2所示。
部分代碼示例
下面給出在兩個(gè)常見(jiàn)的嵌入式設備操作系統下通信的實(shí)現代碼:
主動(dòng)通信方代碼
主動(dòng)通信方選擇WinCE為操作系統。WinCE與Windows2000都是使用WinSocket,因此編程方法基本相同。
#include "Winsock2.h"
#include "Windows.h"
WSADATA wsaData;//使用的WinSocket版本
//使用的通信協(xié)議標志
struct protoent *ppe;
//待通信Socket的地址
struct sockaddr_in daddr;
//讀寫(xiě)數據長(cháng)度
DWORD cbRead=0,cbWritten=0;
BOOL fSuccess=false;//通信標志
//通信程序
DWORD HostConnect(void)
{
//確定使用WinSocket的版本
WSAStartup(MAKEWORD (2,2),&wsaData );
//創(chuàng )建一個(gè)基于TCP的套接字
ppe=getprotobyname("tcp");
SOCKETClientSocket=socket (PF_INET,SOCK_STREAM,ppe->p_proto);
//連接一個(gè)套接字
//使用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ā)送的數據
cbWritten=send(ClientSocket,SData,strlen(SD ata)),MSG_DONTROUTE);
//接收消息
do
{
cbRead=recv(ClientSocket,RData,50,MSG_PEEK);
if(cbRead>0) {fSuccess=true;}
}while(!fSuccess);
...... //數據處理
//關(guān)閉Socket
closesocket(ClientSocket)
}
return(0);
}
被動(dòng)通信方代碼
被動(dòng)通信方選擇VxWorks為操作系統。Linux與VxWorks都可以使用BSD Socket,因此編程方法基本相同。通信任務(wù)和實(shí)時(shí)任務(wù)的數據交換以管道方式為例。
#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "taskLib.h"
//本機Socket地址
struct sockaddr_in serverAddr;
//目標通信機Socket地址
struct sockaddr_in clientAddr;
int sFd; //監聽(tīng)Socket描述苻
int newFd; //被連接Socket描述苻
int ix=0;//被連接的Socket數目
//啟動(dòng)管道函數
void SetupPipe(void)
{
pipeDrv();//管道驅動(dòng)
//管道建立
pipeDevCreate(“pipe mypipe”,20,40);
}
//主通信函數
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);
//監聽(tīng)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);
}
}
//已連接的通信的處理函數
void tcpCommunicateTask(int sFd,)
{
do
{
//讀取數據
ReadBytes=recv(sFd,chRequest, sizeof(chRequest),MSG_PEEK);
if(ReadBytes == 0) break;
else RSuccess=true;
GetAnswerToRequest(chRequest, chReply,&ReplyBytes);//數據處理
//返回數據
WriteBytes = send (sFd, chReply, ReplyBytes ,MSG_DONTROUTE);
if ( WriteBytes!= ReplyBytes) break;
else WSuccess=true;
}while(!(RSuccess && WSuccess));
//關(guān)閉Socket
close (sFd);
}
//處理數據函數
void GetAnswerToRequest(char * Request, char * Reply, int * ReplyBytes)
{
//打開(kāi)管道(每個(gè)任務(wù)有不同的管道)
int fd=open("pipemypipe", O_RDWR,0);
......//相應的數據交換
}
結語(yǔ)
使用這種嵌入式實(shí)時(shí)系統的跨平臺通信方案,不但可以實(shí)現嵌入式設備異平臺的互聯(lián)互通,而且給系統靈活組織帶來(lái)方便。多任務(wù)的處理方式以及通信任務(wù)的分離大大提高了系統的實(shí)時(shí)性和穩定性。作者據此方案建立的基于嵌入式設備的遠程數據采集系統運行穩定,取得了良好的效果?!?/P>
參考文獻
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)絡(luò )編程. 北京:機械工業(yè)出版社. 2000.1
評論