【问题标题】:Problems with reading data from virtual serial port built with com0com从 com0com 构建的虚拟串口读取数据的问题
【发布时间】:2012-10-14 16:11:37
【问题描述】:

我正在尝试读取写入使用com0com 创建的串行端口的数据。当前配置有两个串口,即COM8和COM9相互连接。

当我使用PuTTY 打开这两个串口并在一个终端中写入一些东西时,它会立即出现在另一个终端中。但是,当我尝试以编程方式进行时,情况就不同了。

我可以毫无问题地进行写入,但由于某些原因读取失败。我使用 Tom Archer 和 Rick Leinecker 的 CSerial library

读取数据的函数如下。

int CSerial::ReadData( void *buffer, int limit )
{
    if( !m_bOpened || m_hIDComDev == NULL ) 
        return( 0 );

    BOOL bReadStatus;
    DWORD dwBytesRead, dwErrorFlags;
    COMSTAT ComStat;

    SetCommMask (m_hIDComDev, 0);
    SetCommMask (m_hIDComDev, EV_RXCHAR);
    ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
    if( !ComStat.cbInQue ) return( 0 );

    dwBytesRead = (DWORD) ComStat.cbInQue;
    if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;

    bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
    if( !bReadStatus ){
        if (GetLastError() == ERROR_IO_PENDING ){
            WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
            cout<< "Read data" << endl;
            return( (int) dwBytesRead );
        }
        return( 0 );
    }
    return( (int) dwBytesRead );
}

当程序在这一行退出时,我无法从串口读取数据:

if( !ComStat.cbInQue )
    return( 0 );

这真的很奇怪,因为串行缓冲区有数据,但 cbInQue 告诉数据是否可用于读取操作被设置为零。

这种情况有解决方法吗?或者 com0com 中是否有任何设置需要更改?

仅供参考,我在 Windows 7 64 位上使用 Code::Blocks IDE 和 MinGW 编译器。

【问题讨论】:

  • 你不是和here有同样的问题吗?
  • ClearCommError() 等返回结果 - 您没有检查它们。另外,(调试 101),如果您注释掉该检查会发生什么 - ReadFile() 调用有什么有趣的事情吗? ?
  • @Martin James 评论说 cbInQue 检查没有做任何事情。我会检查 ClearCommError 结果。
  • @Lol4t0 我会检查的。看起来很相似。

标签: c++ winapi serial-port


【解决方案1】:

由于 cbInQue() 返回零,这意味着还没有可用的数据。您需要让程序进入休眠状态,直到某些数据可用为止。

类似这样的:

/**

  Check for data waiting to be read

  @return  the number of bytes waiting to be read

*/
int cSerial::ReadDataWaiting( void )
{

    if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

    DWORD dwErrorFlags;
    COMSTAT ComStat;

    ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

    return( (int) ComStat.cbInQue );

}
/**

  Blocking wait for an amount of data to be ready

  @param[in] len number of bytes required
  @param[in] msec number of milliseconds to wait

  @return 1 if data ready, 0 if timeout

  */
int cSerial::WaitForData( int len, int msec )
{
    int timeout = 0;
    while( ReadDataWaiting() < len )
    {
        if( timeout++ > msec ) {
            return 0;
        }
        Sleep(1);
    }
    return 1;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多