hEventComm);被执行了三次之后这个应用程序才会被触发去读虚拟串口的数据——就是去调用虚拟串口的COM_Read函数,真是晕倒了,不懂为什么会这样,PulseEvent函数要三次才有效吗?不会这么搞笑吧,先看看PB帮助先吧。
This function provides a single operation that sets to signaled the state of the specified event object and then resets it to nonsignaled after releasing the appropriate number of waiting threads.
BOOL PulseEvent(
HANDLE hEvent
);
Parameters
hEvent
[in] Handle to the event object. The CreateEvent function returns this handle.
从PB帮助上看,貌似这个函数没有这么变态啊,晕倒。之所以会有数据延迟的现象,就是有时候这个PulseEvent没有被执行到三次造成的,所以这个是要解决的关键,我想到在COM_IOControl函数的case IOCTL_SERIAL_WAIT_ON_MASK: 中加入如下语句
If(g_bReaded = = FALSE)
PulseEvent(g_hEventComm);
这样就变成,只要这个数据没有被读过,那么就触发一下应用程序的读虚拟串口数据的线程,不过我现在觉得这个还不合理,这样会造成一个现象,极有可能是应用程序多次读取虚拟串口数据,这样会造成读到的数据不完整,断断续续的现象,因为满足If(g_bReaded = = FALSE)
这个条件的时候大多数都是虚拟串口没有读完物理串口数据的时候。那怎么办?我想下面的条件比较合适If((g_bReaded = = FALSE)&& (等待g_hEventComm超时的情况))这样应该不会导致读数据不完整了吧,试试看,等下来报告结果。
晕倒,这样不行,因为(g_bReaded初始化的值是FALSE,所以这样会造成应用程序会不停的读虚拟串口,所以这个方法再次暴毙!
我真的很粗心大意,要发三次数据,应用程序才会去调用虚拟串口的COM_Read的原因不是PulseEvent,因为PulseEvent压根没有执行三次,这个是我在串口监视线程多次使用了WaitCommEvent函数,这个函数需要物理串口触发,如果没有数据来就会在那里无限等待。数据量小的时候只执行了一个WaitCommEvent,所以会造成发三次数据才开始接收数据的现象,纠结!一切都是我的错!
不过我多次使用WaitCommEvent函数这个是好的出发点,因为加了几个WaitCommEvent之后,能够保证虚拟串口把物理串口的数据完整的读入缓存,实测的效果标明,发送大量数据1K字节的时候,即使500ms间隔发送也不会丢数据,没有加之前512字节都会丢数据,所以这点我要自恋一下,并且今天我已经把多次加入WaitCommEvent带入的缺点(小量数据滞后性)解决了,嘿嘿,下面就来说说我的土鳖方法吧。
一、 在MonitorCommEventProc里面多次重复判断WaitCommEvent,并作相应处理(详细见源码)
二、 定义一个解决数据滞后性的全局变量g_ReadFlag,放在在每次的调用WaitCommEvent之后,并赋值,在COM_IOControl中他会有重要表现。
三、 参考g_hEventComm定义一个事件handler ——g_hEventCommTimeOut用于监视串口中是否有数据,并防止滞后性。
嘿嘿,貌似就这么多了,仅仅这点改变,耗费了我四五天的心力,纠结!在这几天曾经有不断的尝试各种方法,但是都失败了,最终就照着上述修改,测试结果表明,数据无滞后性,每隔800ms 发送1024 字节,测试三个小时没有一个字节丢失,比以前有很大的提升,并且测试的时候还打印了多个debug信息(O(∩_∩)O哈哈哈~,以前没有输出debug信息都丢失了)。
通过这次虚拟串口的纠结经历,让我更加了解了,wince串口驱动的一些原理,结构,以前搞过4.2/5.0/6.0的物理串口驱动,前段日子还移植了外部串口驱动,把外部串口驱动的性能弄到相当的完美,这次再次把虚拟串口弄成这样可靠,哎,我这个土鳖也算是对串口的认识有点半桶水了。
快下班了,发博!This is it!
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gooogleman/archive/2010/05/22/5615844.aspx