嵌入式串行读取操作和台式 PC 之间有什么区别
What could be the difference between an embedded serial read operation and a Desktop- PC
在嵌入式 Linux 系统中,我正在编写一个在物理环回环境中测试串口的项目。这意味着我正在连接 rx-tx.The 外设输出是 RS-232
为了测试端口,我发送了 1 个字节,然后我读取了发送的字节。我从 0x00 到 0XFF 重复这个循环。我正在为 UART 使用原始输入类型。
如果我 运行 我的代码在 Linux- 台式电脑上看起来不错。
但是在我的嵌入式 Linux 系统上,我无法正确读取 RS-232 连接。最后,我读 return 零。
您认为可能出现的问题是什么?
我正在检查参考 Serial Programming Guide for POSIX Operating Systems
的 termios 配置
StatusResult UartInterface::openComPort() {
m_fileDesc = open(m_device.c_str(), O_RDWR | O_NOCTTY );
if (m_fileDesc == -1) {
retStatus.type = COMM_ERROR;
}
configureUART();
return retStatus;
}
void UartInterface::configureUART(){
struct termios options;
tcgetattr(m_fileDesc, &options);
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag |= (CLOCAL |CREAD);
tcsetattr(m_fileDesc, TCSANOW, &options);
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CRTSCTS;
/*=============================================*/
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/*=============================================*/
options.c_iflag &= (IXON | IXOFF | IXANY);
/*=============================================*/
options.c_oflag &= ~OPOST;
/*=============================================*/
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
tcsetattr(m_fileDesc, TCSANOW, &options);
}
这是我的主要测试循环
std::cout<<"-----------UART DEBUG-------------\n";
while( int(write_data) < 255 ){
n = write(m_fileDesc, &write_data, 1);
if( n != 1) {
std::cout << "UART write failed!\n";
res=false;
return res;
}
n = read(m_fileDesc, &read_data, 1);
if ( n == 1){
if(read_data != write_data) {
std::cout << "UART mismatch error!\t data_read:0x" << int(read_data)<<" data write:0x"<<int(write_data)<< std::endl;
res=false;
//return res;
}
std::cout<<std::hex<<"Byte: 0x"<<int(read_data) <<" is OK!"<<std::endl;
}
else {
std::cout << "UART read failed! Res: "<<n<<"Errno"<< strerror(errno)<<std::endl;
res=false;
return res;
}
write_data++;
}
(res) ? (std::cout<<"Uart interface test OK!"<<std::endl) : ((std::cout<<"UART FAILED!!"<<std::endl));
return res;
}
这里是嵌入式的输出 linux system.As 你看读写数据是完全不同的。重复一定量后,它以零读取结束?
-----------UART DEBUG-------------
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x1
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x2
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x3
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x4
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x5
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x6
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x7
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x8
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x9
Byte: 0x0 is OK!
UART mismatch error! data_read:0x1 data write:0xa
Byte: 0x1 is OK!
UART mismatch error! data_read:0x2 data write:0xb
Byte: 0x2 is OK!
UART mismatch error! data_read:0x3 data write:0xc
Byte: 0x3 is OK!
UART mismatch error! data_read:0x4 data write:0xd
Byte: 0x4 is OK!
UART mismatch error! data_read:0x5 data write:0xe
Byte: 0x5 is OK!
UART mismatch error! data_read:0x6 data write:0xf
Byte: 0x6 is OK!
UART mismatch error! data_read:0x7 data write:0x10
Byte: 0x7 is OK!
UART mismatch error! data_read:0x8 data write:0x11
Byte: 0x8 is OK!
UART mismatch error! data_read:0x9 data write:0x12
Byte: 0x9 is OK!
UART mismatch error! data_read:0xa data write:0x13
Byte: 0xa is OK!
UART mismatch error! data_read:0xb data write:0x14
Byte: 0xb is OK!
UART mismatch error! data_read:0xc data write:0x15
Byte: 0xc is OK!
UART mismatch error! data_read:0xd data write:0x16
Byte: 0xd is OK!
UART mismatch error! data_read:0xe data write:0x17
Byte: 0xe is OK!
UART mismatch error! data_read:0xf data write:0x18
Byte: 0xf is OK!
UART mismatch error! data_read:0x10 data write:0x19
Byte: 0x10 is OK!
UART mismatch error! data_read:0x12 data write:0x1a
Byte: 0x12 is OK!
UART read failed! Res: 0 Errno: No such file or directory
通过 3 次更正解决了问题:
首先,我发现了一个关于termios配置的错误。这是我的硬件。必须关闭流量控制,并且 Tildy 看起来不见了。
options.c_iflag &= (IXON | IXOFF | IXANY); //FALSE
options.c_iflag &= ~(IXON | IXOFF | IXANY); //CORRECT
毕竟,它发现读取 return 的问题为零。我最多可以完成255个测试数据。但是,读写数据仍然不匹配!
其次,我清除了所有 termios 标志,而不是从 system.This 中读取,这使我能够独立于操作环境。
然后我在 tcsetattr() 之后添加了以下两行以刷新第一个数据。并且 sleep() 是必需的,因为 ioctl 系统调用无法找到任何要刷新的数据,除非您等待一段时间。
....
//tcgettattr(m_fileDesc, &options); //Ignore default system data
memset(&options, 0, sizeof options);
.
.
tcsetattr(m_fileDesc, TCSANOW, &options);
sleep(2);
tcflush(m_fileDesc, TCIOFLUSH);
sleep() 看起来像是一种解决方法,但我找不到更好的解决方案。此外,以下主题非常有帮助。
Clearing the serial port's buffer
在嵌入式 Linux 系统中,我正在编写一个在物理环回环境中测试串口的项目。这意味着我正在连接 rx-tx.The 外设输出是 RS-232
为了测试端口,我发送了 1 个字节,然后我读取了发送的字节。我从 0x00 到 0XFF 重复这个循环。我正在为 UART 使用原始输入类型。
如果我 运行 我的代码在 Linux- 台式电脑上看起来不错。
但是在我的嵌入式 Linux 系统上,我无法正确读取 RS-232 连接。最后,我读 return 零。
您认为可能出现的问题是什么?
我正在检查参考 Serial Programming Guide for POSIX Operating Systems
的 termios 配置 StatusResult UartInterface::openComPort() {
m_fileDesc = open(m_device.c_str(), O_RDWR | O_NOCTTY );
if (m_fileDesc == -1) {
retStatus.type = COMM_ERROR;
}
configureUART();
return retStatus;
}
void UartInterface::configureUART(){
struct termios options;
tcgetattr(m_fileDesc, &options);
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag |= (CLOCAL |CREAD);
tcsetattr(m_fileDesc, TCSANOW, &options);
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CRTSCTS;
/*=============================================*/
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/*=============================================*/
options.c_iflag &= (IXON | IXOFF | IXANY);
/*=============================================*/
options.c_oflag &= ~OPOST;
/*=============================================*/
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
tcsetattr(m_fileDesc, TCSANOW, &options);
}
这是我的主要测试循环
std::cout<<"-----------UART DEBUG-------------\n";
while( int(write_data) < 255 ){
n = write(m_fileDesc, &write_data, 1);
if( n != 1) {
std::cout << "UART write failed!\n";
res=false;
return res;
}
n = read(m_fileDesc, &read_data, 1);
if ( n == 1){
if(read_data != write_data) {
std::cout << "UART mismatch error!\t data_read:0x" << int(read_data)<<" data write:0x"<<int(write_data)<< std::endl;
res=false;
//return res;
}
std::cout<<std::hex<<"Byte: 0x"<<int(read_data) <<" is OK!"<<std::endl;
}
else {
std::cout << "UART read failed! Res: "<<n<<"Errno"<< strerror(errno)<<std::endl;
res=false;
return res;
}
write_data++;
}
(res) ? (std::cout<<"Uart interface test OK!"<<std::endl) : ((std::cout<<"UART FAILED!!"<<std::endl));
return res;
}
这里是嵌入式的输出 linux system.As 你看读写数据是完全不同的。重复一定量后,它以零读取结束?
-----------UART DEBUG-------------
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x1
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x2
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x3
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x4
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x5
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x6
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x7
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x8
Byte: 0x0 is OK!
UART mismatch error! data_read:0x0 data write:0x9
Byte: 0x0 is OK!
UART mismatch error! data_read:0x1 data write:0xa
Byte: 0x1 is OK!
UART mismatch error! data_read:0x2 data write:0xb
Byte: 0x2 is OK!
UART mismatch error! data_read:0x3 data write:0xc
Byte: 0x3 is OK!
UART mismatch error! data_read:0x4 data write:0xd
Byte: 0x4 is OK!
UART mismatch error! data_read:0x5 data write:0xe
Byte: 0x5 is OK!
UART mismatch error! data_read:0x6 data write:0xf
Byte: 0x6 is OK!
UART mismatch error! data_read:0x7 data write:0x10
Byte: 0x7 is OK!
UART mismatch error! data_read:0x8 data write:0x11
Byte: 0x8 is OK!
UART mismatch error! data_read:0x9 data write:0x12
Byte: 0x9 is OK!
UART mismatch error! data_read:0xa data write:0x13
Byte: 0xa is OK!
UART mismatch error! data_read:0xb data write:0x14
Byte: 0xb is OK!
UART mismatch error! data_read:0xc data write:0x15
Byte: 0xc is OK!
UART mismatch error! data_read:0xd data write:0x16
Byte: 0xd is OK!
UART mismatch error! data_read:0xe data write:0x17
Byte: 0xe is OK!
UART mismatch error! data_read:0xf data write:0x18
Byte: 0xf is OK!
UART mismatch error! data_read:0x10 data write:0x19
Byte: 0x10 is OK!
UART mismatch error! data_read:0x12 data write:0x1a
Byte: 0x12 is OK!
UART read failed! Res: 0 Errno: No such file or directory
通过 3 次更正解决了问题:
首先,我发现了一个关于termios配置的错误。这是我的硬件。必须关闭流量控制,并且 Tildy 看起来不见了。
options.c_iflag &= (IXON | IXOFF | IXANY); //FALSE
options.c_iflag &= ~(IXON | IXOFF | IXANY); //CORRECT
毕竟,它发现读取 return 的问题为零。我最多可以完成255个测试数据。但是,读写数据仍然不匹配!
其次,我清除了所有 termios 标志,而不是从 system.This 中读取,这使我能够独立于操作环境。
然后我在 tcsetattr() 之后添加了以下两行以刷新第一个数据。并且 sleep() 是必需的,因为 ioctl 系统调用无法找到任何要刷新的数据,除非您等待一段时间。
....
//tcgettattr(m_fileDesc, &options); //Ignore default system data
memset(&options, 0, sizeof options);
.
.
tcsetattr(m_fileDesc, TCSANOW, &options);
sleep(2);
tcflush(m_fileDesc, TCIOFLUSH);
sleep() 看起来像是一种解决方法,但我找不到更好的解决方案。此外,以下主题非常有帮助。 Clearing the serial port's buffer