0

考虑这个线程,它就像一个定时器,向串口发送一些数据包:

void PlCThead::run()
{
    while(1)
    {
        const char str[]={UPDATE_PACKET};

        QByteArray  built;
        built.append(0x02);
        built.append(0x05);
        built.append(0x03);

        emit requestForWriteAndReceive(built);

        msleep(100);
    }
}

发射工作正常,它进入插槽,在那里,它只将 78 或 char x 写入串行而不是 3 个字节的数据包。

bool RS::rs_ThreadPlcDataAqustn(QByteArray byteArray)
{
    QByteArray rd15Bytes;

    char *data = byteArray.data();
    int len = byteArray.length();

    if(!rs_serialWrite(data, len))
    {
        qDebug() << "Failure:( rs_dataqustn: rs_plcWrite(data, len)";
        emit plc_port_dscntd();
        return false;
    }
}

bool RS::rs_serialWrite(char* buff, size_t length)
{  
    int tries;

    int len;

    tries = 0;

    QByteArray built((char*)buff, length);

    qDebug() << built.toHex();


            len = write(fd, buff, length);

            qDebug() << len;

            qDebug() << strerror(errno);

            return true;
}

这就是 fd 创建的方式:

fd = open(portPath, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK, S_IWUSR | S_IRUSR | S_IXUSR);

这是在主窗口中创建线程的方式:

rs_plc->rs_plcOpenPort((char *)"/dev/ttyS0"); /*/dev/ttyS3*/

PlCThead *thread = new PlCThead();
connect(thread, SIGNAL(requestForWriteAndReceive(QByteArray)), rs_plc, SLOT(rs_ThreadPlcDataAqustn(QByteArray )));
thread->start();

rs_plc 是 MainWindow 的私有成员。

strerror返回此警告:

> Resource temporarily unavailable

有任何想法吗?这段代码在定时器上工作得很好,它已经过准确的检查和测试,但现在我需要添加这个线程而不是定时器。谢谢

4

1 回答 1

0

您的问题不足以进行全面诊断,因为您没有显示如何fd创建、如何设置线程(您说这是问题的一部分)等。

但是......你的resource temporarily unavailable台词是一个很大的提示。write() 函数没有成功写入所有内容,因为它返回了一个错误(可能是EAGAINor EWOULDBLOCK)。fd文件描述符附加到具有小缓冲区、没有缓冲区或缓冲区已满的东西上。它已经满了,在它可以处理之前不发送任何其他内容是应用程序的工作。一个常见的做法是睡觉,然后如果错误代码是EAGAIN或,则再次尝试写入EWOULDBLOCK

但是,您说它返回 3,这实际上也表示“没有错误”。如果是这种情况,那么错误字符串将不会指代 write 本身,以及errno之前设置的其他内容。(过去可能是write它自己)。

简而言之,如果这被多次调用(可能),您可能需要注意写入速度太快(它看起来像一个串行缓冲区,肯定属于易于填充缓冲区的类别) .

简而言之:如果它没有将所有字节写入fd你想要的,那是因为它不能处理更多。

顺便说一句,这可能与此完全无关qt。这都是关于write()电话的。

于 2013-04-23T13:52:29.897 回答