通过CreateFile操作串口,调用写入(WriteFile)时被挂起(hanges)

Windows中C++写的串口操作类,用CreateFile打开串口:

	HANDLE hSerialPort = ::CreateFile	(	szPortName, 
											GENERIC_READ| GENERIC_WRITE, 
											0, 
											NULL, 
											OPEN_EXISTING, 
											FILE_ATTRIBUTE_NORMAL,
											NULL);

 

设置参数:

		DCB dcb={0};
		if(::GetCommState(hSerialPort, &dcb))
		{
			dcb.BaudRate	= wBaundRate;
 			dcb.ByteSize	= 8;
 			dcb.Parity		= NOPARITY;
 			dcb.StopBits	= ONESTOPBIT;
			bRet = ::SetCommState(hSerialPort, &dcb);
		}

设置超时:

 

		if(::SetupComm(hSerialPort, CT_READ_CACHE, CT_WRITE_CACHE))
		{
			//
			COMMTIMEOUTS cto={0};
			cto.ReadIntervalTimeout			= 0;
			cto.ReadTotalTimeoutConstant	= 0;
			cto.ReadTotalTimeoutMultiplier	= 3000;
			cto.WriteTotalTimeoutConstant	= 0;
			cto.WriteTotalTimeoutMultiplier	= 0;
			bRet =  ::SetCommTimeouts(hSerialPort, &cto);
		}

清空串口并开启读取线程:

	if(bRet&&::PurgeComm(hSerialPort,PURGE_TXCLEAR|PURGE_RXCLEAR))
	{
		if(NULL == m_pbBuffer)
		{
			m_cbBuffer	= CT_READ_CACHE;
			bRet = (NULL!=(m_pbBuffer=(LPBYTE)::malloc(m_cbBuffer*sizeof(BYTE))));
		}
		if(bRet)
		{
			m_bStarted = TRUE;
			bRet = (INVALID_HANDLE_VALUE!=(m_hReadThread = ::CreateThread(NULL, 0, LPTHREAD_START_ROUTINE (_SerialPortProc), this, 0, NULL)));
		}
	}

读取线程:

DWORD SerialPortHelper::SerialPortProc	(	void	)
{
	DWORD dwError = 0;
	COMSTAT cs={0};

	SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);
	DWORD dwCommStatus = 0;
	while (m_bStarted)
	{
		WaitCommEvent(m_hSerialPort, &dwCommStatus, 0);

		SetCommMask (m_hSerialPort, EV_RXCHAR);

		if(dwCommStatus & EV_RXCHAR)
		{
			if(::ClearCommError(m_hSerialPort, &dwError, &cs))
			{
				if(cs.cbInQue>0)
				{
					ReceiveData(cs.cbInQue);
				}
			}
		}
	}
	return 0;
}

这种情况下,如果调用WriteFile就永远无法返回,WriteFile被挂起了。

实际上原因在于读取线程中,如果串口没有任何数据到达,则串口被WaitCommEvent()挂起,所以无法写入数据,导致WriteFile()函数被挂起。

 

发表评论

电子邮件地址不会被公开。