我在使用boost将数据写入串口时遇到问题。 我从这里使用稍微修改过的minicom_client类: https://code.google.com/p/vkbrd/source/browse/trunk/src/Dg5Emulator/MiniComClient.h https://code.google.com/p/vkbrd/source/browse/trunk/src/Dg5Emulator/MiniComClient.cpp
消息中的前17个字节发送良好,但其余部分替换为:
FD FD FD FD AB AB AB AB AB AB AB AB EE FE EE FE 00 00 00 etc
消息长度正确。
当我打电话
for (int i = 0; i < 128; ++i)
miniComClient.do_write(i);
我在第二面收到了这个:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F FD FD FD FD AB AB AB AB
AB AB AB AB EE FE EE FE 00 00 00 00 00 00 00 00 2E F1 5C 42 BD 8B 07 18
40 6D C1 03 E8 9E 40 02 00 00 00 00 00 00 00 00 04 00 00 00 01 00 00 00
F4 62 00 00 FD FD FD FD 40 54 40 02 FD FD FD FD AB AB AB AB AB AB AB AB
00 00 00 00 00 00 00 00 2F F1 5C 43 BF 8B 07 18 A0 A3 3B 02 38 A5 3B 02
00 00 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
FD FD FD FD AB AB AB AB AB AB AB AB EE FE EE FE 00 00 00 00 00 00 00 00
2E F1 5C 42 BD 8B 07 18 40 6D C1 03 E8 9E 40 02 00 00 00 00 00 00 00 00
04 00 00 00 01 00 00 00 F4 62 00 00 FD FD FD FD 40 54 40 02 FD FD FD FD
AB AB AB AB AB AB AB AB 00 00 00 00 00 00 00 00 2F F1 5C 43 BF 8B 07 18
A0 A3 3B 02 38 A5 3B 02 00 00 00 00 00 00 00 00
我有三重检查波特率,停止位和奇偶校验。
有没有办法改变发送缓冲区大小?也许这是另一个问题。
答案 0 :(得分:3)
像0xfdfdfdfd,0xabababab和0xfeeefeee这样的值是magic numbers。
换句话说,您正在查看从堆分配的未初始化内存。在串口编程中,这是一个非常标准的错误,假设您只需读取一次整个消息。只有在调试程序时才会发生这种情况,并将其放慢速度。从未以全速运行时,串行端口是非常慢的设备。您必须注意read_complete()函数中的bytes_transferred
和不解释收到的数据,直到您收到所有字节为止。这需要跟踪总数,缓冲部分数据并在收到完整响应时有个好主意。
数据变成垃圾的字节值也是一个神奇的数字。 0x10是换行控制字符的ASCII代码。这通常用作消息结束指示符。请确保在线路的另一端配置您使用的任何软件,以便不检查线路终结器并仅显示它实际接收的字节。
答案 1 :(得分:0)
出现此问题的原因是我对原始代码进行了“轻微”修改。
我想让整个字节数组更简单(而不是在循环中调用do_write()),所以我添加了方法:
void miniComClient::do_write_buffer( QByteArray msg )
bool write_in_progress = !writeMsgs.empty(); // is there anything currently being written?
for(int i = 0; i < msg.size(); ++i)
writeMsgs.push_back(msg[i]); // store in write buffer
if (!write_in_progress) // if nothing is currently being written, then start
write_start();
}
但最糟糕的是我尝试优化的东西,所以我将write_start()修改为这样的东西(将所有内容都发送到缓冲区而不是下一个字节):
void miniComClient::write_start( void )
{
// Start an asynchronous write and call write_complete when it completes or fails
boost::asio::async_write(serialPort,
boost::asio::buffer(&writeMsgs.front(), writeMsgs.size()),
boost::bind(&miniComClient::write_complete,
this,
boost::asio::placeholders::error));
}
这是一个可怕的错误,因为writeMsgs的类型为std:deque,因此它不会连续存储在内存中,因此它会从我想要的点发送一些字节,之后会发送垃圾。