c++ - 嵌入式串行读取操作和台式 PC 之间有什么区别

标签 c++ linux embedded-linux uart

在嵌入式 Linux 系统中,我正在编写一个在物理环回环境中测试串行端口的项目。意思是我连接的是rx-tx,外设输出是RS-232

为了测试我发送 1 个字节的端口,然后我读取发送的字节。我从 0x00 到 0XFF 重复这个循环。我正在为 UART 使用原始输入类型。

如果我在 Linux 桌面 PC 上运行我的代码,它看起来不错。

但是在我的嵌入式 Linux 系统上,我无法正确地从 RS-232 连接读取数据。最后,我得到了 read return zero。

你怎么看待可能出现的问题?

我正在检查引用 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系统的输出。如你所见,读取和写入数据是完全不同的。在一定数量的重复之后,它以零读取结束?

    -----------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

毕竟,它解决了读返回零问题。我可以完成最多 255 个测试数据。但是,读取和写入数据仍然不匹配!

其次,我清除了所有 termios 标志,而不是从系统中读取。这使我能够独立于操作环境。

然后我在 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

Serial port binary transfer changes carriage return

关于c++ - 嵌入式串行读取操作和台式 PC 之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54811326/

相关文章:

c++ - 类/头文件 - 无法调用没有对象的成员

linux - Git hooks 可能需要更高的权限

linux - SD 卡 : how to force the kernel to read the WP pin again without removing the sdcard

c++ - Linux 中 QToolButton 的事件处理问题

c++ - C++ 中的 sqldriverconnect 无法连接到本地数据库 sql 2008

c++ - ROS Linking errors using boost::filesystem library 在linux下使用C++

linux - 如何在opensuse 15上安装没有互联网连接的c编译器?

python - 在 Fedora 上运行 python 脚本时没有名为 lxml.html 的模块

embedded-linux - 从美元卡启动时出错 - 没有文件系统可以挂载根目录,尝试了 :Ext4

c - 从不同的 UART 驱动读取数据