C++ 串口通信偶尔WriteFile卡死

wodenide007 2018-08-07 04:00:29
最近做一个程序通过串口控制仪器,发现在正常收发数据一会儿之后,偶尔会在WriteFile发数据时程序卡死,部分代码如下,vs2013+win7.
bool CSerialPort::openComm()
{

m_hComm = CreateFileA(m_portNum.c_str(),
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //独占方式
NULL, OPEN_EXISTING, //打开而不是创建
0, //同步方式
NULL
);


if (m_hComm == INVALID_HANDLE_VALUE)
{

return false;

}
else
{
DCB dcb;
SetupComm(m_hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); // 设置读写缓冲区大小
GetCommState(m_hComm, &dcb);
dcb.BaudRate = m_dwBaudRate;
dcb.ByteSize = m_byteSize;
dcb.Parity = m_parityBit;
dcb.StopBits = m_stopBit;

if (!SetCommState(m_hComm, &dcb))
{
return false;
}
}
//在读写串口前,用 PurgeComm 函数清空缓冲区
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);

m_bOpen = true;

return true;

}

// 向串口发送数据
bool CSerialPort::writeToComm(const char* pData, unsigned int length)
{
DWORD dwError = 0;
if (ClearCommError(m_hComm, &dwError, NULL) && dwError > 0)
{
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR);
}

DWORD dwTx = 0;
BOOL ret = FALSE;

printf(pData);
printf("send\n");

ret = WriteFile(m_hComm, pData, length, &dwTx, NULL);

if (ret == FALSE)
{

return false;
}

return true;


}

UINT CSerialPort::GetBytesInCOM()
{
DWORD dwError = 0; /** 错误码 */
COMSTAT comstat; /** COMSTAT结构体,记录通信设备的状态信息 */
memset(&comstat, 0, sizeof(COMSTAT));

UINT BytesInQue = 0;
/** 在调用ReadFile和WriteFile之前,通过本函数清除以前遗留的错误标志 */
if (ClearCommError(m_hComm, &dwError, &comstat))
{
BytesInQue = comstat.cbInQue; /** 获取在输入缓冲区中的字节数 */
}

return BytesInQue;
}


bool CSerialPort::recv()
{
UINT BytesInQue = GetBytesInCOM();
if (BytesInQue == 0)
return false;

while (BytesInQue > 0)
{
BOOL bResult = TRUE;
DWORD BytesRead = 0;
char buf[bufsize];
/** 从缓冲区读取n个字节的数据 */
bResult = ReadFile(m_hComm, &buf, BytesInQue, &BytesRead, NULL);
if ((!bResult))
{
/** 获取错误码,可以根据该错误码查出错误原因 */
DWORD dwError = GetLastError();

/** 清空串口缓冲区 */
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_RXABORT);

return false;
}

if (BytesInQue + (int)strRecv.size() < bufsize)
strRecv += std::string(buf, BytesInQue);
else
strRecv = std::string(buf, BytesInQue);

Sleep(100);

BytesInQue = GetBytesInCOM();
}



return true;

}
...全文
1577 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
sevancheng 2018-09-19
  • 打赏
  • 举报
回复
设置下读写超时参数,即使串口没数据也不会一致阻塞在那里了
wodenide007 2018-09-13
  • 打赏
  • 举报
回复
引用 5 楼 chengbar 的回复:
卡死是一直不返回吗?一般是不会的,是计算机自带串口吗?不是自带串口考虑驱动问题
可以写日志或者使用串口抓包软件监控一下串口
卡死就是程序执行到这一步之后就没有响应了,不继续执行,也没有退出
wodenide007 2018-09-13
  • 打赏
  • 举报
回复
开始用的是蓝牙转串口,总是会出现程序运行一段时间,就卡在了WriteFile这一步,之后换成串口线直连电脑和仪器之后,运行就一直没出错了
翅膀又硬了 2018-08-29
  • 打赏
  • 举报
回复
卡死时候,暂停程序,看看卡在哪里。你这样把代码都贴上来,想叫大家替你改bug吗
sevancheng 2018-08-29
  • 打赏
  • 举报
回复
卡死是一直不返回吗?一般是不会的,是计算机自带串口吗?不是自带串口考虑驱动问题
可以写日志或者使用串口抓包软件监控一下串口
shwill123 2018-08-29
  • 打赏
  • 举报
回复
WriteFile 不应该会卡死的,先判断 m_hComm 的有效性,再调用 WriteFile
starytx 2018-08-07
  • 打赏
  • 举报
回复
引用 2 楼 wodenide007 的回复:
[quote=引用 1 楼 starytx 的回复:]
不想卡死可以用异步读写方式 FILE_FLAG_OVERLAPPED

想同步读写就没有办法实现吗?[/quote]既然是同步,就会出现阻塞现象,或者你 放到线程里,就不阻塞主进程了
wodenide007 2018-08-07
  • 打赏
  • 举报
回复
引用 1 楼 starytx 的回复:
不想卡死可以用异步读写方式 FILE_FLAG_OVERLAPPED

想同步读写就没有办法实现吗?
starytx 2018-08-07
  • 打赏
  • 举报
回复
不想卡死可以用异步读写方式 FILE_FLAG_OVERLAPPED

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧