基于MSCOMM的雷情实时处理软件的设计
2015-01-25毛小玲
祁 春,毛小玲,房 瑾
(中国飞行试验研究院 陕西 西安 710089)
飞行试验是航空技术发展与航空武器装备研制的关键环节,近年来随着新型飞机的不断涌现,特别是多机编队协同试飞科目的增多,给地面实时监控的遥测资源带来了严峻挑战。为了解决这一突出矛盾,在多机编队协同试飞科目中利用雷情数据是节约宝贵的遥测资源和提高整体试飞效率的一种有效途径。针对雷情数据采用RS232串口通信的特点,本文介绍了基于MSCOMM控件实现雷情数据实时接收与处理的方法。同时,作为面向对象的可视化开发工具Visual C++,在PC的串口通信方面具有很强的功能,且代码执行效率高[1],是本软件开发的首选开发平台。同时,在数值分析等复杂计算方面实现了VC与Matlab的混合编程,有效提高了软件开发效率并保证了雷情数据拟合与插值计算的正确性。目前该软件已成功应用于多机编队协同试飞科目的实时监控任务,缓解了对遥测资源的需求压力。
1 功能组成与通信实现方式
1.1 功能组成
在多机编队协同试飞科目中,雷情实时处理软件根据通信协议负责对导航雷达综合处理系统发送的雷情数据信息进行实时解析、误码剔除、目标筛选和参数计算等工作,并将结果数据通过局域网分发至各监控客户机进行实时监控。所以,从功能上软件主要由配置、串口通信、实时处理、存储和网络发送等模块组成,如图1所示。其中,串口通信和实时处理模块是整个软件的核心部分,也是本文讨论的重点。
图1 雷情实时处理软件功能组成Fig.1 Functional components of the software
1.2 通信实现方式
目前在Windows系统平台下开发串口通信应用程序主要有两种方式:1)利用 Windows的 API函数;2)利用MSComm控件[2-3]。前者可根据实际需求对软件进行功能裁剪,使用灵活,但代码实现较繁琐;后者是Microsoft公司为简化串口通信编程的复杂度而设计开发的ActiveX控件[4],具有事件驱动和查询两种工作模式[5],利用自身提供的属性和方法可快速实现与PC机的串口通信。因此,为了简化雷情实时处理软件编程的复杂度,且针对实时监控任务要求和数据信息有效长度变化的特点,采用MSComm控件及事件驱动模式更能有效保证通信数据的完整性和实时性,其应用设置及关键代码如图2所示。
图2 MSComm的应用设置Fig.2 Apply setting of the MSComm
首先利用GetPortOpen函数对串口资源使用情况进行检测,使端口资源处于释放状态。然后用SetInBufferSize函数设置接收缓存的大小(以字节为单位),该大小应大于实际通信中最大一帧数据的长度,以防止数据溢出。由于雷情数据中含有不可见字符,所以数据检取应采用二进制方式,即SetInputMode(1)。协议格式的设定可通过SetSettings函数设置,如图 2 中的字符串“115200,N,8,1”,其参数字段分别代表波特率、奇偶效验方式、数据位和停止位。针对雷情数据的特点,SetRThreshold(1)表示当接收缓存区有1个及以上字符时将触发接收事件,以提高数据处理的实时性。最后,用SetPortOpen(TRUE)函数打开端口,完成串口的设置。值得注意的是,在通信之前常常需要调用SetInputLen(0)函数,它将引起MSComm读取整个接收缓存区,以清空缓存中初始的随机内容。
2 关键技术
2.1 数据接收与处理技术
雷情数据包含了特定空域内所有飞机的信息,具有信息长度不固定和存在较多无效信息内容的特点,为了准确获取指定目标飞机的信息,需要完成目标挑选、信息有效性判断和可变数据信息的接收与处理。在MSComm事件触发函数中可利用函数GetInput获取缓存数据,其返回值的类型为VARIANT,它是一种特殊的数据类型,直接操作较为繁琐。为了简化数据获取,设计中利用GetInput的VARIANT类型返回值构造一个COleSafeArray类对象来实现的。COleSafeArray类是用来处理任意类型和维数的数组的类,是从OLE VARIANT结构派生而来的,利用其成员函数GetOneDimSize即可获得本次缓存区字符个数,然后利用GetElement将数据格式化到定义好的字节数组中以待进一步处理。因此,灵活转化数据类型可使数据接收简单化。
雷情数据通信格式如图3所示,每一帧的开始均采用了双同步设置。由于在通信过程中每次从缓存中读取的数据并不是一个完整的数据帧,因此在处理上并不能直接对数据缓存进行操作,而是需要对接收的数据进行拼接,直至找到完整的数据帧。本软件在处理上采用了双指针法,其处理过程如图3所示。
图3 雷情数据帧处理方法Fig.3 The processing method of data frames
1)当检取接收缓存区数据时,指针Ptr1根据函数GetOne DimSize获取的字节数,对接收缓存区中的数据逐字节进行分析,并存入处理缓存中,当找到SynWord1并且下一字节是SynWord2时,记录Ptr1在处理缓存中的位置Pos1,代表数据帧起始位置;
2)利用指针Ptr2寻找下一帧的 SynWord1,如果本次没有找到,则将下次到来的数据进行拼接处理,利用指针Ptr2继续寻找,当找到下一帧的SynWord1时记录位置Pos2,则完整的数据帧即为[Pos1,Pos2-1]区段上的数据。
3)为了提高数据处理效率,如果完整帧数据长度(Pos2-Pos1)小于最小有效数据长度则进行抛弃处理,否则对飞机代码进行判别,如果是需求的目标机数据,则对数据内容进行分析处理。
4)为了防止处理缓存溢出,在寻找一下完整数据帧前,从标记Pos2位置的字节开始,将剩余字节数据从处理缓存首地址开始存放,并使指针Ptr1从首地址开始寻找SynWord1,如果下一字节为SynWord2,记录Ptr1位置Pos1;
5)重复 2)、3)、4),如此循环处理。
2.2 多线程及线程消息
多线程技术的应用使得软件在实现雷情数据帧的接收、分析与处理的同时,可以显著提高软件的运行性能,避免界面操作出现假死现象。在实现上,将雷情数据的接收和雷情数据的分析处理分别置于不同的线程当中,由主线程MSComm事件触发函数实现接收缓存区中数据的读取,在子线程中完成分析与处理工作。雷情数据多线程处理方法如图4所示。
图4 雷情数据多线程处理方法Fig.4 The processing method of multithreading
为了防止各线程同时对共有缓存区进行读写操作而出现不可预知的结果,利用多线程同步技术对共有缓存区进行保护,使得在同一时刻只允许一个线程对共有缓存区进行读取或者写入操作,确保数据正确解析。常用的线程同步技术主要有互斥对象、事件对象和关键代码段等。但是,互斥对象和事件对象都属于内核对象,利用内核对象进行线程同步速度较慢,而关键代码段工作在用户方式下,同步速度较快且使用较为简单[6],所以,利用关键代码段能更好地满足雷情数据实时处理要求。在接收线程和处理线程中分别在共有缓存区前调用EnterCriticalSection函数,在访问完缓存数据后,调用LeaveCriticalSection函数。需要注意关键代码段这两个函数必须是成对出现的,否则另一线程会因无法获取所有权而无法执行。
Windows通信基于消息机制的[7],采用线程的消息队列可解决数据接收线程和数据处理线程间通信及协同运行问题。线程消息,即数据接收线程收到雷情数据后,利用PostThreadMessage函数向数据处理线程发送特定的消息,并将数据转化为LPARAM类型传递出去。PostThreadMessage函数会立即返回,而不用等待投递的消息被处理完。防止消息得不到及时处理导致数据接收线程无法执行而丢失数据。数据处理线程利用GetMessage函数循环查询指定消息,当收到PostThreadMessage函数发送的消息后,从MSG消息结构中取出数据进行处理。
2.3 VC与Matlab混合编程
目标机雷情数据更新率是1pps,为了满足实时监控至少4pps数据更新率的要求,本设计采用VC6.0与Matlab混合编程实现了数据拟合与插值计算。利用Matlab编译工具将调有Matlab polyfit函数的M文件转为C动态库文件供VC使用,以利用Matlab强大的数据分析计算能力,减轻VC在复杂数值计算方面的编程负担,确保处理的正确性,且这种方式可以实现脱离Matlab运行环境。
由生成的头文件可知,VC与动态库函数的数据交互是通过mxArray来实现的,mxArray是一种复杂的数据结构,对应于Matlab的Array类型。所以VC与Matlab混合编程的重点在于参数的传递与交互上,其实现的关键代码如下:
//定义代表X/Y坐标轴的mxArray类型变量用于参数传递
mxArray PointX, PointY ,mRes;
double*m_result;
//创建 PointNum*1的双精度double类型数组,mxREAL代表元素为实数
PointX=mxCreateDoubleMatrix(PointNum,1,mxREAL);
PointY=mxCreateDoubleMatrix(PointNum,1,mxREAL);
mRes=mxCreateDoubleMatrix(PointNum-1,1,mxREAL);
//将接收到雷情数据存储在mxArray类型数组
memcpy (mxGetPr (PointX),XData, PointNum*sizeof(double));
memcpy (mxGetPr (PointY),YData, PointNum*sizeof(double));
//注意:动态库中的函数名称加有ml前缀,形参和M函数文件定义不一样,增加了输出变量数和函数值的指针返回形式
mlMyNiHe(1,&mRes, PointX, PointY,3);
//获取处理结果,使用C指针指向mxArray结果数组
m_result=mxGetPr(mRes);
…
//开辟的mxArray类型数组空间的销毁,释放资源
mxDestroyArray(PointX);
mxDestroyArray(PointY);
mxDestroyArray(mRes);
3 结束语
雷情数据实时处理软件能够同时接收和分析处理多架目标机的雷情数据,并将结果数据组播至各个监控席位驱动画面的运行。该软件的成功研制有效缓解了现今紧张的遥测资源,特别是在多机编队试飞任务中,雷情数据实时处理软件提供的目标机数据信息完全满足实时监控要求,是解决资源紧缺问题的一种有效实现途径,已经成功应用于多机编队试飞任务的实时监控当中。
软件采用模块化设计思想,并利用微软MSComm控件快速实现与PC机的串口通信,采用多线程设计并灵活运用线程消息机制提高了数据处理效率和软件运行性能;在数据的接收上,利用双指针法实现了帧识别和拼接处理;同时,为了满足实时监控对数据更新率的要求,采用VC和Matlab混合编程实现了数据拟合和插值运算,将数值分析计算任务交由Matlab工具函数完成,弥补了VC在复杂运算方面的不足,减轻了编程负担和提高了软件研制效率。
[1]王正强.VC中应用MSComm控件实现串口通信[J].电子测试,2010(5):73-76.WANG Zheng-qiang,Realization serial-communication applied MSComm in VC[J].Electronic Testing,2010(5):73-76.
[2]李现勇.Visual C++串口通信技术与工程实践[M].北京:人民邮电出版社,2002.
[3]高远.通过MSComm控件实现串口的设备间数据传输[J].铁道通信信号,2009(1):56-57.GAOYuan.Realization devices serial-communication applied MSComm[J].Railway Communication Signal,2009(1):56-57.
[4]田添.利用控件MSComm实现计算机的串口通信[J].数字通信,2012(2):95-97.TIAN Tian.Realization computer serial-communication applied MSComm[J].Digital communication,2012(2):95-97.
[5]邱育桥.基于MSCOMM的PC机与单片机串行通讯程序设计[J].科技信息,2009(15):446-458.QIU Yu-qiao.Design of serial-communication between PC and SCM based on MSCOMM[J].Scientific and Technical Information,2009(15):446-458.
[6]孙鑫,余安萍.VC++深入详解[M].北京:电子工业出版社,2006.
[7]宋坤,刘锐宁,李伟明.Visual C++开发技术大全[M].北京:人民邮电出版社,2007.