推广 热搜: 电机  PLC  变频器  服务机器人  培训  变送器  危化品安全,爆炸  西门子PLC  触摸屏  阀门 

嵌入式实时系统中跨平台通信的实现

   日期:2013-03-23     来源:工控之家网    作者:工控之家    浏览:26    评论:0    

摘 要: 本文以套接字Socket 为基础,提出并设计了一种跨平台嵌入式实时系统的通信模型,并根据这种模型给出了示范。

关键词: 跨平台;嵌入式实时系统;套接字

引言

    当前嵌入式系统正以前所未有的速度发展,并广泛应用到通信、军事、航空、航天、工业控制等高精尖技术及实时性要求极高的领域中。在这些领域中,迫切需要一个能够让日益增多的嵌入式设备相互通信的解决方案。同时,由于嵌入式系统的专用性强,在不同领域的嵌入式设备往往使用不同的嵌入式实时操作系统。这样就为构建一个统一的通信平台带来了困难。当前微软公司正大力开发用于工业领域的Windows CE 嵌入式平台,作为工业控制领域的领导厂商,泓格积极倡导和顺应这一趋势,经过两年不懈地开发和测试,泓格于2003 年领先推出了基于Windows CE.NET 和RISC CPU 架构的嵌入式控制系统WinCon-8000 系列,并于2003 年10 月与微软WEP 部门(Microsoft Windows Embedded Partner Program)正式建立了合作关系。这一充满活力的产品一经推出,就获得了国内各界专家的好评,并被浙江大学、华东理工大学等知名高校选作自动化等相关专业的试验平台。

    本文介绍一个采用泓格科技(ICP DAS)的全系列产品实现不同平台下的嵌入式系统的通信方案。

设计目标

灵巧性

    完备的嵌入式系统大都具备嵌入式实时操作系统,绝大多数实时操作系统都带有网络协议栈,利用网络协议就可以构建通信平台。TCP/IP 协议簇是目前使用最广泛的一种网络通信协议。当前,基于TCP/IP 的流行应用,存在功能单一、消耗系统资源等问题。而嵌入式设备一般通信量不大,同时系统资源有限,不能支持大型的应用。所以,嵌入式设备间的通信应当实现简单、可灵活增减。

实时性

    实时系统要求系统能够在规定的时间内对外部事件给予响应。但在不同应用中,通信的嵌入式设备间的物理距离不同,使用的通信方式也不尽相同。通信延迟是影响实时系统的主要因素之一。在近距离通信中,可以采用高速通信线路,但是在远距离通信中,则通信线路的选择余地较小。在低速通信线路中,为了提高系统的实时性能,嵌入式实时系统的通信需要设计成多线程多任务,确保每个通信请求都有单独的线程来处理,这样可以保证系统对通信的及时响应。

稳定性

    嵌入式实时系统大都具备繁重的测量和运算任务。嵌入式实时系统同时运行大量任务,不能保证系统永不出现问题,但通信任务不能受嵌入式设备本身任务的影响。因此,在设计中,需要把通信任务和实际的检测控制任务分离。用一个专门的任务处理通信事件,同时设立一个缓冲区保证通信数据能够被及时保存。

通用性

    嵌入式实时操作系统种类繁多,目前尚无一种操作系统在嵌入式领域占绝对优势。嵌入式设备的跨平台通信必须能够适用于各种常见的实时操作系统,能将不同实时操作系统的嵌入式设备联网。

实现方案

    根据嵌入式实时系统不同平台通信的特点,可以采用如下方案设计:

跨平台通信

    通信部分采用大多数实时操作系统都支持的TCP/IP 协议簇作为系统的基本协议。为了方便使用,采用基于TCP/IP 的套接字。套接字是一种仿照电话系统设计,并在UNIX 上得到成功应用的进程通信机制,它提供进程间通信的端点。通信之前,进程双方都创建一个端点,服务器端绑定一个固定的端口,客户端则可以随机的申请一个端口。客户可以通过网络向服务器的端口发送连接请求,服务器端接收到请求后允许客户端的连接。这样,服务器端和客户端就建立了一个双向的通信通道。

    套接字分为三种类型:流套接字、数据包套接字、原始套接字。流套接字可以提供可靠的、面向连接的通信流,有固定的发送和接收顺序,采用TCP 和IP 协议。数据包套接字是一种无连接的数据服务,数据通过相互独立的报文进行无序传输,使用UDP 和IP 协议,它允许对底层协议如IP 或ICMP 直接访问。原始套接字虽然功能强大,但是使用较复杂,主要用于一些协议的开发和测试工作。

    通信处理程序设计成多线程方式。一旦其它嵌入式设备发起连接就启动一个线程或任务专门处理对外部嵌入式设备发送过来的数据,通过解析确定数据的类别并转入相应的处理函数。处理函数的多少可以根据实际应用确定,这样可以最大限度地利用有限的系统资源。

通信数据处理

    利用命名管道或共享内存技术,建立一个介于嵌入式设备实际任务和通信处理任务间的缓冲区。

    如果通信中嵌入式设备需要连续数据交换,可以使用管道技术。命名管道支持单向和双向进程或任务间的通信。命名管道有两种实现方式:字节模式和消息模式。在字节模式中,消息以一个连续的字节流的形式,在客户机与服务器之间流动。这意味着,对进程双方来说,在任何一个特定的时间段内,它们不能准确知道有多少字节从管道中读入或者写入管道。在消息模式中,客户机和服务器则通过一系列不连续的数据单位,进行数据的收发。每次在管道上发出了一条消息后,它必须作为一条完整的消息读入。因此,消息模式比较适合通信任务和实时任务的数据交换。

    如果通信中嵌入式设备只要瞬时数据交换,则可以采用共享内存方式构造缓冲区。简单说地共享内存就是被多个进程共享的内存。共享内存方式是进程间通信方法中最快的一种,它可以将信息直接映射到内存中,省去了许多中间步骤。利用共享内存方式实现进程通信,需要注意进程间的同步问题。如果通信量不大的话,最简单的方法就是对进程双方给予不同权限(读或写),这样就可以省去复杂的同步机制。通信方案的结构框图如图1 所示,嵌入式设备间的通信流程如图2 所示。


图1 通信方案的结构框图


图2 嵌入式设备的通信流程

部分代码示例

    下面给出在两个常见的嵌入式设备操作系统下通信的实现代码:

主动通信方代码

    主动通信方选择WinCE 为操作系统。WinCE 与Windows2000 都是使用WinSocket,因此编程方法基本相同。

#include "Winsock2.h"
#include "Windows.h"
WSADATA wsaData;//使用的WinSocket 版本
//使用的通信协议标志
struct protoent *ppe;
//待通信Socket 的地址
struct sockaddr_in daddr;
//读写数据长度
DWORD cbRead=0,cbWritten=0;
BOOL fSuccess=false;//通信标志
//通信程序
DWORD HostConnect(void)

//确定使用WinSocket 的版本
WSAStartup(MAKEWORD (2,2),&wsaData );
//创建一个基于TCP 的套接字
ppe=getprotobyname("tcp");
SOCKETClientSocket=socket (PF_INET,SOCK_STREAM,ppe->p_proto);
//连接一个套接字
//使用TCP 协议
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

//发送消息
......//准备发送的数据
cbWritten=send(ClientSocket,SData,strlen(SD ata)),MSG_DONTROUTE);
//接收消息
do

cbRead=recv(ClientSocket,RData,50,MSG_PEEK);
if(cbRead>0) {fSuccess=true;}
}while(!fSuccess);
...... //数据处理
//关闭Socket
closesocket(ClientSocket)

return(0);

被动通信方代码

    被动通信方选择VxWorks 为操作系统。Linux 与VxWorks 都可以使用BSD Socket,因此编程方法基本相同。通信任务和实时任务的数据交换以管道方式为例。

#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "taskLib.h"
//本机Socket 地址
struct sockaddr_in serverAddr;
//目标通信机Socket 地址
struct sockaddr_in clientAddr;
int sFd; //监听Socket 描述苻
int newFd; //被连接Socket 描述苻
int ix=0;//被连接的Socket 数目
//启动管道函数
void SetupPipe(void)

pipeDrv();//管道驱动
//管道建立
pipeDevCreate(“\pipe\ mypipe”,20,40);

//主通信函数
void Server(void)

//使用TCP/IP 协议
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 地址
//创建Socket
sFd = socket (AF_INET, SOCK_STREAM, 0);
//绑定Socket
bind (sFd, (struct sockaddr *) &serverAddr, sockAddrSize);
//监听Socket
listen (sFd, SERVER_MAX_CONNECTIONS);
//等待通信事件发生
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));
//关闭Socket
close (sFd);

//处理数据函数
void GetAnswerToRequest(char * Request, char * Reply, int * ReplyBytes)

//打开管道(每个任务有不同的管道)
int fd=open("\pipe\mypipe", O_RDWR,0);
......//相应的数据交换

结语

    使用这种嵌入式实时系统的跨平台通信方案,不但可以实现嵌入式设备异平台的互联互通,而且给系统灵活组织带来方便。多任务的处理方式以及通信任务的分离大大提高了系统的实时性和稳定性。作者据此方案采用泓格科技(ICP DAS)的全系列产品包括PCI 和ISA 接口工业数据采集卡和嵌入式控制系统WinCon-8000 系列等产品建立的基于嵌入式设备的远程数据采集系统运行稳定,取得了良好的效果,当然这以泓格科技在中国提供及时、到位的服务及技术支持和质量过硬的系列产品是分不开的。

参考文献

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 网络编程. 北京:机械工业出版社. 2000.1
4 李朝青.PC 机及单片机数据通信技术.北京:北京航空航天出版社.2000
5 原嵩,林浒.通用串行总线的原理及实现. 小型微行计算机系统.1999(5)
6 张洪润,蓝清华.单片机应用技术教程. 北京:清华大学出版社.1997

 
打赏
 
更多>同类环保知识
0相关评论

推荐图文
推荐环保知识
点击排行
网站首页  |  免责声明  |  联系我们  |  关于我们  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  RSS订阅  |  违规举报  |  鲁ICP备12015736号-1
Powered By DESTOON