考虑这个线程,它就像一个计时器,将一些数据包发送到串口:
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
任何想法?这个代码适用于计时器,它已经过精确检查和测试,但现在我需要添加这个线程而不是计时器。感谢
答案 0 :(得分:0)
您的问题还不够完整,因为您没有展示如何创建fd
,如何设置线程(您说这是问题的一部分)等等。
但是......你的resource temporarily unavailable
行是一个很大的暗示。 write()函数没有成功写入所有内容,因为它返回了一个错误(可能是EAGAIN
或EWOULDBLOCK
)。 fd
文件描述符附加到具有小缓冲区,无缓冲区或已满的缓冲区的内容。并且它已经完整,并且应用程序的工作是在它可以处理之前不发送任何其他内容。常见的做法是睡眠,如果错误代码为EAGAIN
或EWOULDBLOCK
,则再次尝试写入。
但是,你说它返回3,实际上也表示“没有错误”。如果是这种情况,那么错误字符串将不会引用写入本身,而是先前设置errno
的其他内容。 (过去本来可能是write
)。
简而言之,如果这个被调用不止一次(可能),你可能需要注意写得太快(它看起来像一个串行缓冲区,它绝对属于易于填充的类别 - -buffer)。
简而言之:如果它没有将所有字节写入fd
而不是你想要的,那是因为它无法处理更多。
顺便说一句,这可能与qt
完全无关。这都是关于write()
电话。