VxWorks环境下基于Zinc的通信
从图1中,在VxWorks中Zinc事件的主要来源是输入设备和应用程序(比如GSM通信程序) ,由于VxWorks不支持事件驱动的系统,事件管理器周期性地查询或接收来自输入设备的数据并以Zinc定义的事件结构包装成事件。一旦事件管理器获得事件, Zinc主控进程重新获得对应用程序的控制,该进程从时间管理器中得到事件并传送给窗口管理器。窗口管理器决定事件的最终目的地和合适的路由并将其发送。最终窗口对象的Event方法收到每个事件并对其进行处理。在EGIS中,通过重载Event函数实现对自定义事件的处理。
5 EGIS 系统中GUI任务与非GUI任务之间通信的实现
嵌入式地理信息系统包括了两个部分,跑车分系统和中心显示分系统。跑车上包括一台PC机、一台GPS接收机和一台短信收发设备。中心包括一台 VxWorks目标机、一台PC机(用于开发和调试)和一台短信收发设备。其中,VxWorks目标机上运行的是EGIS各功能模块。
为了提高系统性能和简化代码,将目标机上的EGIS软件划分为两个任务: GUI任务和GSM通信任务。GUI任务的主要功能是:负责界面和菜单的实现,并且需要根据GSM实时接收到的经纬度数据在地图上画出跑车的运行轨迹。 GSM通讯任务的主要功能是:实时接收以短消息方式传输的GPS经纬度数据,存放在环形缓冲区中,并通知GUI任务。
EGIS系统需要满足两方面的实时性:第一, GSM通信任务接收经纬度数据的实时性;第二, GUI任务响应菜单操作的实时性和特定情况下画出跑车轨迹的实时性。为此,在该系统中采取两种通信方式: Zinc入口点和共享内存。GUI任务与非GUI任务之间通信的实现主要包括如下几个方面:
a)用户事件的定义
Zinc中的事件共分为七类,其中包括用户事件。用户事件的取值范围为10,000到32,767。在EGIS中定义的用户事件为:
const ZafEventType TRACKING = 10028;
其中, ZafEventType是Zinc事件类型。
b)用户事件的发送
用户事件的发送通过下面的调用完成:
zafApplication-> EventManager() -> Put(TRACKING)
其中, zafApplication是Zinc全局变量,也是GUI任务的任务变量。某些程序可能同时被多个任务调用,这些程序可能要求全局变量或静态变量对于每个调用该程序的任务具有一个不同的值。为了适应这种情况, VxWorks提供了一种所谓任务变量的机制。一个4字节的变量可以以任务变量的方式被添加到一个任务的上下文中,这样每当任务切换的时候同时切换该变量的值。由于在GUI任务和GSM通信任务中的zafApplication具有不同的值,因此,可以在创建GSM通信任务的时候通过参数传递使GSM通信任务获得GUI任务的任务变量zafApplication:
if (GSMTaskID = taskSpawn("SERIAL_PORT",90, VX_FP_TASK,
ZAF_VXW_STACK_SIZE, (FUNCPTR)Trace,
(int)zafApplication,0,0,0,0,0,0,0,0,0) != ERROR)
{
taskVarAdd(GSMTaskID,(int*)
zafApplication);
/*将zafApplication添加为任务变量*/
} /*通过参数传递GUI任务的任务变量zafApplication*/
在GSM通信任务中:
int Trace(CGIS_Window * pWindow,ZafApplication *application)
{
……
taskVarAdd(0,(int*)zafApplication);
/*将zafApplication添加为任务变量*/
zafApplication = application; /*GSM通信任务变量zafApplication赋值*/
zafApplication->EventManager() -> Put(TRACKING) /*发送用户事件*/
……
}
c)用户事件的处理
ZafEventType CGIS_Window::Event(const ZafEventStruct event)
{
ZafEventType code;
if ( event_type == TRACKING) /*判断是否用户定义事件TRACKING*/
{
……
m_pMainController->ZoomToPosition ( Lat_Long[0],Lat_Long[1]); /*事件处理函数*/
code = TrackCode;
return (code);
}
else
{
……/*处理其他事件*/
}
d)任务之间的数据共享
共享数据是通过下面的全局变量数据实现的。GSM任务收到数据之后,首先将经纬度数据存入数组Lat_Long中,然后将变量PntNumber加1,而GUI任务首先读取PntNumber,然后处理Lat_Long中的数据。因此不会产生共享冲突。
float Lat_Long [ 2000 ]; /*存放通过GSM终端所收到的经纬度数据*/
int PntNumber; /*存放通过GSM终端所收到的经纬度数据的个数*/
6 结论
本文介绍了VxWorks支持的任务之间进行通信的各种方式,给出了在特定应用场合选择任务之间通信方式的原则,介绍了Zinc的事件模型,并详细地给出了嵌入式地理信息系统中非GUI任务与GUI任务进行通信的实现方式。实验证明,该通信方式能够满足嵌入式地理信息系统各方面的实时性要求。
评论