UART 上的串行数据被损坏
Serial data over UART gets corrupted
我正在为开发板 (Beagle Bone Black) 开发一个应用程序,它将通过 UART
外围设备发送一些数据。开发板运行s Linux Kernel
(一些Debian发行版,3.8.x
Linux内核版本)。
为了通过 UART
发送和接收数据,我使用标准 UNIX
API:open()
、read()
和 write()
系列函数。
用于设置通信参数(baud rate
、stop/start bits
、parity
、等等...)我使用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
上被正确接收,我已经连接了我板上的 TX
和 RX
引脚(环回测试)(因为我想能够接收回我发送的数据),并且 运行 minicom
在那个特定的 UART
端口上:
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
端口,并且设置相同(baud
、parity
等):
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
可能是什么问题?
这似乎是 Minicom 响应 ENQ 字符 (0x05) 并在会话捕获中记录其响应。附加数据是 Minicom2.6.1
,这不是损坏。它会替换您流中的每个 0x05。
我正在为开发板 (Beagle Bone Black) 开发一个应用程序,它将通过 UART
外围设备发送一些数据。开发板运行s Linux Kernel
(一些Debian发行版,3.8.x
Linux内核版本)。
为了通过 UART
发送和接收数据,我使用标准 UNIX
API:open()
、read()
和 write()
系列函数。
用于设置通信参数(baud rate
、stop/start bits
、parity
、等等...)我使用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
上被正确接收,我已经连接了我板上的 TX
和 RX
引脚(环回测试)(因为我想能够接收回我发送的数据),并且 运行 minicom
在那个特定的 UART
端口上:
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
端口,并且设置相同(baud
、parity
等):
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
可能是什么问题?
这似乎是 Minicom 响应 ENQ 字符 (0x05) 并在会话捕获中记录其响应。附加数据是 Minicom2.6.1
,这不是损坏。它会替换您流中的每个 0x05。