Boost asio串口从18字节写入损坏的数据

时间:2013-12-10 11:29:34

标签: boost serial-port boost-asio send

我在使用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   

我有三重检查波特率,停止位和奇偶校验。

有没有办法改变发送缓冲区大小?也许这是另一个问题。

2 个答案:

答案 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,因此它不会连续存储在内存中,因此它会从我想要的点发送一些字节,之后会发送垃圾。