如图3所示为采用关键区和同步事件对象实现的同步控制逻辑流程,其中EXCHANGE_ENABLE为读写指针是否可交换标志。对于数据处理子线程,该线程一直处于挂起状态直到同步事件对象被激活,激活后利用ptrRead指针读取缓存区数据进行后续处理,之后复位同步事件对象并置EXCHANGE_ENABLE为TRUE状态。对于读取串口子线程,首先检查EXCHANGE_ENABLE标志,若可交换则交换读写指针指向的缓存区,之后置EXCHANGE_ENABLE为FALSE状态并激活同步事件对象。此外,为保证逻辑流程的数据一致性,两个线程中与同步控制相关的流程必须放在关键区中执行[5].
4模式的编码实现与测试。
4.1模式的编码实现。
本模式以一个MFC规则动态链接库的方式实现,可以被其他应用程序链接调用,提供的外部接口函数如表1所示。
其中,CTRInitialCommSrv用于初始化串口服务,设置该串口是否采用重叠I/O方式,并返回一个指向目的串口的句柄,CTRSetCommSettings利用该句柄设置波特率、数据位、停止位、校验方式等参数,CTROpenComm利用该句柄打开串口开始数据收发工作。CTRStartRdCommThrd启动串口数据接收线程,CTRGetCommData读取已接收到的数据。CTR-WrtComm则通过串口向外发送数据。
4.2测试及效果评估。
在测试环境中,下位机通过高速串口传输JPEG标准的红外图像压缩码流,图像尺寸为640*480,压缩比为12.5,高速串口波特率为2.5M,传输带宽几乎全部被占用。读取串口子线程读取图像压缩码流,数据处理子线程对压缩码流进行解压并显示图像,单幅图像解压耗时约为40ms.如图4所示为解压出的红外灰度图像。
在测试过程中,在每秒解压图像达12帧的状态下,未出现数据丢失的情况,图像场景匀速。测试结果表明,提出的多线程设计模式解决了高速串口上位机软件设计中因串口缓冲区溢出导致的数据丢失问题,提出的同步控制逻辑解决了串口数据接收与耗时可观的后续数据处理任务之间的同步问题。
5结语。
考虑到串口传输带宽的占用率、后续数据处理任务的耗时程度,串口的上位机软件设计方法应根据实际应用环境来选择。在低速串口和后续数据处理任务耗时较少的情况下,采用微软的MSComm控件能减少代码量、简化设计;对于后续数据处理任务耗时较多的情况下,无论高速串口还是低速串口,应采用多线程设计方式,既能提高数据处理的实时性,又能降低读取不及时而导致串口缓冲区溢出的风险。
参考文献:
[1]王中训,徐超。基于VC++6.0的多串口通信方法 [J].计算机应用,2008,(6):254-256.
[2]赵晓辉,陈艳萍,张科英。基于VC++环境下串口通信的研究与实现 [J].电子设计工程,2010,(1):39-40.
[3]石海杰,常虹。基于VC的多线程串口通信程序设计 [J].PLC& FA,2009,(9):65-66.
[4]申晓宇,赵毅强。多线程串口类在实时数据采集系统中的应用[J].计算机时代,2010,(1):28-30.
[5]杨旭东,蔡敬坤。一种通用串口线程在C++ Builder中的实现[J].计算机测量与控制,2011,(7):1687-1689.