2016-05-25 46 views
0

我正在开发一个开发板(Beagle Bone Black)的应用程序,它将通过UART外设发送一些数据。开发板运行Linux Kernel(一些Debian发行版,3.8.x Linux内核版本)。UART上的串行数据被破坏

对于超过UART发送和接收数据I使用标准UNIX API:open()read(),和write()家庭功能。

用于设置通信参数(baud ratestop/start bitsparity,等...)我使用termios结构(从termios.h)。

这是一些相关的代码序列,其中我做I/O设置:

fd_debug = open("output.out", O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 

fd_write = open(port.c_str(), O_WRONLY | O_NOCTTY | O_SYNC); 
std::cout << std::endl << "I opened: " << port; 

struct termios settings; 
tcgetattr(fd_write, &settings); 

cfsetospeed(&settings, B19200);   /* baud rate */ 
settings.c_cflag &= ~PARENB;   /* no parity */ 
settings.c_cflag &= ~CSTOPB;   /* 1 stop bit */ 
settings.c_cflag &= ~CSIZE; 
settings.c_cflag |= CS8 | CLOCAL;  /* 8 bits */ 
settings.c_lflag = ICANON;    /* canonical mode */ 
settings.c_oflag &= ~OPOST;    /* raw output */ 

tcsetattr(fd_write, TCSANOW, &settings); /* apply the settings */ 
tcflush(fd_write, TCOFLUSH); 

在那里,我开了两个文件描述符:

  • fd_debug:挂一档,进行调试。
  • fd_write:链接到UART外设(在我的具体情况下为/dev/ttyO4)。

这是当我想通过UART发送一个字节所执行的功能:

int UARTIOHandler::write(uchar8 byte) { 
    auto tp = std::chrono::steady_clock::now(); 
    std::cout << std::endl << "[write] Timestamp: " << std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count(); 
    ::write(fd_debug, &byte, 1); 
    return ::write(this->fd_write, &byte, 1); 
} 

因为如果我发送的数据被正确接收了UART检查,我已经连接TXRX我的船上引脚(环回测试)(因为我希望能够接收回来,我发送数据),并特别UART端口上运行minicom

minicom -D /dev/ttyO4 -b 19200 -C test.test 

发送一些数据后,我比较了两个文件(调试文件和minicom生成的输出文件(它应该包含通过UART收到的数据))。问题是数据不一样!

这是实际的数据发送(十六进制):

55 33 02 04 06 08 0a 0c d5 55 0b 01 03 05 07 ef 55 3f 07 06 05 04 03 02 01 e3 55 16 01 02 03 04 05 06 07 08 db 55 3f 01 02 03 04 05 06 07 e3 

这是在调试文件(这是相同的,所以这证实了有一些UART问题)接收到的数据:

55 33 02 04 06 08 0a 0c d5 55 0b 01 03 05 07 ef 55 3f 07 06 05 04 03 02 01 e3 55 16 01 02 03 04 05 06 07 08 db 55 3f 01 02 03 04 05 06 07 e3 

这是minicom工具接收到的数据(即设置为监听同UART端口,和相同的设置(baudparity等):

55 33 02 04 06 08 0a d5 55 01 03 4d 69 6e 69 63 6f 6d 32 2e 36 2e 31 07 ef 55 3f 07 06 4d 69 6e 69 63 6f 6d 32 2e 36 2e 31 04 03 02 01 e3 55 16 01 02 03 04 4d 69 6e 69 63 6f 6d 32 2e 36 2e 31 06 07 08 db 55 3f 01 02 03 04 4d 69 6e 69 63 6f 6d 32 2e 36 2e 31 06 07 e3 

从某点可以看出,所有数据都被损坏,并且接收到更多的字节。

对于从输出文件检查的实际数据我用hexdump这样的:

hexdump -ve '1/1 "%.2x "' test.test 

可能是什么问题呢?

+0

C++不是C.它可以帮助你知道你正在编程的编程语言。 – Lundin

+0

@Lundin'unistd.h'和'termios.h'是C POSIX库组件,这就是为什么我标记了'C'语言。 –

+0

您是否检查过minicom的配置,特别是流量控制(硬件和软件)? – blatinox

回答

1

这似乎是Minicom响应ENQ字符(0x05)并在会话捕获中记录其响应。额外的数据是Minicom2.6.1这不是腐败。它在您的数据流中每取代0x05。

+1

似乎也跳过了'0c'和'0b'。 –

+0

这可能是真正的问题,我可以在live minicom会话中看到'Minicom2.6.1'字符串。我没有找到任何方法来禁用这个替换寿。 –

+0

@WeatherVane是的。他们是“垂直标签”和“换页”,minicom可能是对他们采取行动而不是传递给他们。在古代,流中的^ L(0x12)会在硬拷贝终端上为您提供新的工作表。 (也就是为什么它在'vi'和'curses'之类的东西中用作重画命令) – janm