Linux串口获取完整的数据包

        当使用代码如下,测试的时候发现收到的串口数据有时会被分段。

unsigned char readBuf[128] = { 0 };
int receive_byte = 0;
int read_len = 0;

do
{

	read_len = read(fd, readBuf + receive_byte, sizeof(readBuf) - receive_byte);
	if (read_len > 0)
	{
		receive_byte += read_len;
	}
				
} while (read_len > 0);

        有看到网上说可以指定要获取的长度,一直循环获取到该长度。或者获取到指定的标志位之类。但是我这因为设备上协议已经固定,没有特别的标志位,数据还是变长的,并不主动上报消息,只有在下发指令后要及时获取回应的消息,所以这些方法都不太适用。只好给了个合适的时间段,获取该时间段内收到的数据。

        代码使用了异步,发消息和收消息是两个线程。

        发消息的时候设置标志位通知开始收,因为我这有多个串口,所以用map记录了标志位

nSendByte = write(fd, pData, dataLen);

{
	boost::mutex::scoped_lock locker(m_mutexStartReadSerial);			
	m_mapStartReadSerial[strPortName] = true;
}

        收消息的时候标志位读数组中相应串口的标志位,为true就开始计时并循环收消息,直到规定的时间为止,因为我收到的数据都不长,所以给了50ms的时间,此处可根据收到数据量的多少调整时间长度

unsigned char readBuf[128] = { 0 };
int32_t timeOutMs = 50;
bool bStartReadSerial = false;

while (!m_fini)
{
	{
		boost::mutex::scoped_lock locker(m_mutexStartReadSerial);
		if (m_mapStartReadSerial.find(strPortName) != m_mapStartReadSerial.end())
		{
			bStartReadSerial = m_mapStartReadSerial[strPortName];
		}
	}

	if (bStartReadSerial)
	{
		int receive_byte = 0;
		int read_len = 0;

		boost::xtime tstart, tend;// 时间对象
		boost::xtime_get(&tstart, boost::TIME_UTC_);	// 获取当前时间
		double dIntervalMs = 0;

		do
		{
			read_len = read(fd, readBuf + receive_byte, sizeof(readBuf) - receive_byte);
			if (read_len > 0)
			{
				receive_byte += read_len;
			}
				
            boost::xtime_get(&tend, boost::TIME_UTC_);
			uint64_t t = (tend.sec - tstart.sec - 1) * 1000 + (tend.nsec + 1000000000 - tstart.nsec) / 1000000;
			dIntervalMs = (double)t;

        } while (dIntervalMs < timeOutMs);


		if (receive_byte > 0)
		{
			boost::mutex::scoped_lock locker(m_mutexSerialReadMsg);
			m_serialReadMsg[strPortName].assign((char*)readBuf, receive_byte);
		}

		{
			boost::mutex::scoped_lock locker(m_mutexStartReadSerial);
			m_mapStartReadSerial[strPortName] = false;
		}
			
	}
	else
	{
		boost::xtime m_xt;
		boost::xtime_get(&m_xt, boost::TIME_UTC_);
		m_xt.nsec += 20000000;
		boost::thread::sleep(m_xt);
	}
}

测试后发现能正常运行。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值