【问题标题】:Linux C++ Serial Port Reading/WritingLinux C++ 串口读/写
【发布时间】:2014-07-11 15:32:59
【问题描述】:

我正在尝试读取已写入串行端口/tty/USBS0 的数据。我已经通过serial_fd = open(serialport.str().c_str(), O_RDWR | O_NOCTTY | O_NDELAY);打开了端口,我正在通过retVal2 = write(serial_fd, (void *)&msg, length);写数据。

但是,我遇到了一个问题,当我调用 read() 时,它停在那里;换句话说,它会无限期地继续阅读。

void cmgGSP::read_thread(){ 

unsigned char msg[256];
unsigned char messagelength;
msg_header msgHeader; //msg_header is defined in cmgCOM.h
msgHeader.startByte = 0;
msgHeader.length = 0;
msgHeader.ID = 0;
int totalBytes;
int retVal;
cout<<"Scope Test -- In Read Thread"<<endl;

while(1) //infinte loop, since we're going to want to always be reading command data

{

cout<<"Scope Test -- In While(1)"<< endl;

    totalBytes = 0;
    while (totalBytes == 0) {
        cout<<"Scope Test -- First While Loop"<<endl;

        retVal = read(serial_fd, (unsigned char*)&msgHeader, 1);
        cout<<"retVal: "<<retVal <<endl; //This does not get printed

        if (retVal == -1)
        {
            printf("read() message failed: %s\n", strerror(errno));
        }

        if (msgHeader.startByte != FROM_CMG) {
            printf("Bad start byte on read()\n");
            totalBytes = 0;

        } else {

            cout<<"scope test 2"<<endl;

            totalBytes+=retVal;

        }

    }



    while (totalBytes < sizeof(msgHeader)) {

retVal = read(serial_fd, (unsigned char*)&msgHeader+totalBytes, sizeof(msgHeader)-totalBytes);

        cout<< "in second while"<<endl;         

        if (retVal == -1){
            printf("read() message failed: %s\n", strerror(errno));
        }
        totalBytes+=retVal;

    }

    if (msgHeader.startByte != START_BYTE) {
        printf("Bad start byte on message\n");
        continue;
    }
    else
    {
        printf("MSG RCV: StartByte=0x%X, Length=0x%X, ID=0x%X\n", msgHeader.startByte, msgHeader.ID, msgHeader.length);

        break;
    }
}
}

上面是我创建的线程;但是,输出永远不会通过“范围测试——第一个 While 循环”。即使我在写入数据后显式调用线程,结果也是一样的:它无限读取。我知道它实际上正在读取,因为如果我在卡住时断开电路板,它会开始打印“read() message failed ...”

任何帮助表示赞赏 - 谢谢!

【问题讨论】:

  • 有什么理由不使用 QtSerialPort?
  • 我不知道QtSerialPort,但是从网站上的描述(“Qt Serial Port提供基本功能,包括配置,I / O操作,获取和设置RS的控制信号-232 引出线。”)这不是最佳解决方案,因为我们将 USB 连接到 RS-422。
  • 它也可以正常工作。
  • 但这能解决 read() 的问题吗?我认为我们在打开/连接到串行端口时没有问题。
  • 好吧,通过运行任何阅读命令行示例很容易测试。

标签: c++ multithreading serial-port


【解决方案1】:

您可能需要在 open 系统调用中设置 O_NONBLOCK 标志;这种方式取决于写入端口的数据,您将退出 read() 并错误输出/获取填充的缓冲区。

“如果某个进程打开了管道进行写入,并且 O_NONBLOCK 被清除,read() 将阻塞调用线程,直到某些数据被写入或管道被所有打开管道进行写入的进程关闭。”

在此处阅读有关 O_NONBLOCK 标志的信息: http://pubs.opengroup.org/onlinepubs/7908799/xsh/read.html

【讨论】:

  • 如何/在哪里将 O_NONBLOCK 添加到读取调用中?请你举个例子好吗?我尝试将它添加到 open() 中,但没有帮助;我尝试将它添加到 read() 并引发编译器错误,指出 read() 有太多参数。
  • 即使您将标志传递给 open() 后,它是否仍然挂在 read() 中?
  • 是的,它仍然挂起。
  • 如何将数据写入端口?
  • 我正在通过write(serial_fd, (void *)&amp;msg, length); 写入数据,其中serial_fd 是我们打开端口时设置的值(见问题顶部)。这就是我们调用 write 的地方,也是 msg 所在的地方。 pastie.org/9378572
猜你喜欢
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
相关资源
最近更新 更多