获取C中Windows串行端口的输入缓冲区长度

时间:2016-06-14 08:40:03

标签: c windows serial-port

是否存在非阻塞函数,使用C?返回Windows中串行端口的当前rx队列长度?

我见过的所有例子都只是调用ReadFile阻塞直到指定的超时,所以我想知道在读取之前是否可以检查缓冲区中是否有任何内容?

E.g。我可以为每个角色做到这一点:

void ReadCharacter(char *theCharacter)
{
   DWORD numBytesRead = 0;

   while (numBytesRead == 0)
   {
        ReadFile(comPorthandle,
               theCharacter,
               sizeof(char),
               &numBytesRead,
               NULL);
   }
}

但是有可能有像

这样的东西
int numBytesRx = GetNumBytesRx(&portHandle);
if (numBytesRx > 0)
    Read(&portHandle, targetBuffer, numBytesRead);

2 个答案:

答案 0 :(得分:4)

要通过ReadFile使用COM端口执行异步IO,请考虑使用函数的最后一个参数LPOVERLAPPEDOVERLAPPED结构。 OVERLAPPED是Windows中异步IO的常见做法。

Here you can find examples

答案 1 :(得分:2)

ReadFile将始终返回rx缓冲区中已有的内容。因此,如果您没有设置超时,您将立即获得内容。

虽然请注意,没有专业应用程序将ReadFile置于忙等待循环中。这不仅会不必要地耗尽CPU,它还会阻塞循环所在的线程。

所以你应该将ReadFile放在自己的线程中。这是所有I / O功能的常见做法。这将解决阻塞问题,但您仍然遇到CPU使用率高的问题。

作为替代方案,您可以使用Windows调用"异步I / O" (*),使用ReadFileEx函数。它允许您指定一个回调函数,只要您实际收到一些数据就会触发它。

现在,如果你结合"异步I / O"通过线程,您可以获得无阻塞通信,在没有要处理的数据时不会消耗CPU。您的I / O线程可以等待SleepEx的I / O,也可以等待从回调内部手动设置的事件。

(*)"异步I / O"是一个无意义的Windows术语,从技术上讲,所有串行端口通信始终是异步的。您是否会同步发送数据而不会间歇,这样台式PC就无法跟上。