gpt4 book ai didi

c++ - 串行端口接收线程未按预期运行 - C++

转载 作者:行者123 更新时间:2023-11-30 03:09:06 25 4
gpt4 key购买 nike

我的应用程序使用一个单独的线程来异步处理接收到的串行数据。 PC 按预期进入接收处理程序,但从那里开始事情变得奇怪。

这是我的线程函数:

// Create event for OVERLAPPED structure.
s_ov.hEvent = ::CreateEvent(
NULL, // No security
TRUE, // Create a manual-reset event object
FALSE, // Initial state is non-signaled
NULL // No name specified
);

// Load event handles.
pHandles[0] = s_hSerialPortRxThreadExitEvent;

while ( bContinue )
{
if ( !::WaitCommEvent( s_hSerialPort, &dwEventMask, &s_ov ) )
{
if ( ::GetLastError() != ERROR_IO_PENDING )
{
TRACE(_T("SerialPortRxThreadFn : Call to WaitCommEvent failed.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
return ::GetLastError();
}
}

pHandles[1] = s_ov.hEvent;

dwObjectWaitState = ::WaitForMultipleObjects( 2, pHandles, FALSE, INFINITE );

switch ( dwObjectWaitState )
{
case WAIT_ABANDONED:
TRACE(_T("SerialPortRxThreadFn : Owner thread terminated prematurely.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ERROR_ARENA_TRASHED, __WFILE__, __LINE__);
return ERROR_ARENA_TRASHED;
break;

case WAIT_TIMEOUT:
TRACE(_T("SerialPortRxThreadFn : The timeout is set to INFINITE; there should be no timeout. State is nonsignaled.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), WAIT_TIMEOUT, __WFILE__, __LINE__);
return WAIT_TIMEOUT;
break;

case WAIT_FAILED:
TRACE(_T("SerialPortRxThreadFn : Call to WaitCommEvent failed.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
return ::GetLastError();
break;

case WAIT_OBJECT_0: // thread exit event signalled
bContinue = FALSE;

if ( !::ResetEvent( pHandles[0] ) )
{
TRACE(_T("SerialPortRxThreadFn : Failed to reset the serial port thread exit event.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
return ::GetLastError();
}
break;

case WAIT_OBJECT_0 + 1: // OVERLAPPED structure event signalled
// Read data from serial port.
if ( !::ReadFile( s_hSerialPort, pBuf, RX_BUF_SIZE, &dwWritten, &s_ov ) ) // <- Set breakpoint here
{
TRACE(_T("SerialPortRxThreadFn : Call to ReadFile filed.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
return ::GetLastError();
}

// Discontinue thread operation if there are no more bytes in the serial port receive buffer.
if ( dwWritten == 0 ) // <- Or, set breakpoint here
{
bContinue = FALSE;
}
// Copy the received bytes to the thread-safe buffer.
else if ( !s_pobjRxRingBuffer->Add( pBuf, dwWritten, TRUE ) )
{
TRACE(_T("SerialPortRxThreadFn : Failed to add bytes to ring buffer.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ERROR_INSUFFICIENT_BUFFER, __WFILE__, __LINE__);
return ERROR_INSUFFICIENT_BUFFER;
}
else if ( s_SpCallbackFn != NULL )
{
// Notify application of received data.
if ( (dwRetVal = s_SpCallbackFn( s_pobjRxRingBuffer->ItemsInBuffer() )) != ERROR_SUCCESS )
{
TRACE(_T("SerialPortRxThreadFn : Serial port callback function failed.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), dwRetVal, __WFILE__, __LINE__);
return dwRetVal;
}
}

if ( !::ResetEvent( pHandles[1] ) )
{
TRACE(_T("SerialPortRxThreadFn : Failed to reset the OVERLAPPED structure event.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__);
return ::GetLastError();
}
break;

default:
// Do nothing.
break;
}
}

::CloseHandle( s_ov.hEvent );

return ERROR_SUCCESS;

如果我在调用 ReadFile 的行上设置我的断点,一切都会按我预期的那样运行,并且 PC 会进入回调函数。但是,如果我在下一行设置断点,其中 dwWritten 的计算结果为零,则为零,表达式计算结果为 TRUE,然后循环退出; PC 永远不会收到回调。我究竟做错了什么?谢谢。

最佳答案

我不是 Win32 API 方面的专家,但它确实听起来像是一个计时问题(这是 heisenbugs 的常见原因。)假设当您到达 ReadFile 时,那里没有数据可读。闯入调试器可能会给它足够的暂停时间让数据到达,所以当你恢复/跳过 ReadFile 时,它会成功。

除了数据到达之外,还有很多其他因素可以触发该事件。您可能需要检查您的 dwEventMask看看我的假设是否正确。

关于c++ - 串行端口接收线程未按预期运行 - C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4393188/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com