我使用无线电模块XBee pro并记录了一些无线电数据。
我使用FTDI串口转USB转换器,因此该模块显示在/dev/ttyUSB0
。
我已经写了这段代码:
void TsToCoord::serialConfig()
{
// Open Serial Port
cout << "Opening serial port..." << endl;
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (fd < 0 )
{
cout << "Error " << errno << " opening /dev/ttyUSB0: " << strerror(errno) << endl;
}
else
{
//Configure Serial Port
cout << "Configuring serial port..." << endl;
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
cout << "Error " << errno << " from tcgetattr: " << strerror (errno) << endl;
}
cfsetispeed(&tty, B57600);
cfsetospeed(&tty, B57600);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 50;
tty.c_cflag |= CREAD | CLOCAL;
cfmakeraw(&tty);
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &tty) != 0)
{
cout << "Error " << errno << " from tcsetattr" << endl;
}
}
}
void TsToCoord::listenPort()
{
// Creation of a buffer to store data from radio module
fill_n(buff, 2048, '\0');
this-> ind = 0;
while(true)
{
char mes[1024];
fill_n(mes, 1024, '0');
//cout << "Blocking read" << endl;
int rd = read(fd, &mes, sizeof(mes));
if (rd > 0)
{
//cout << "Storing in buffer" << endl;
storeInBuff(mes, rd);
fill_n(mes, 1024, '0');
struct pollfd fds;
fds.fd = fd;
fds.events = POLLIN | POLLPRI;
int slct = 1;
/*
int slct = 1;
fd_set rdfds;
FD_ZERO(&rdfds);
FD_SET(fd, &rdfds);
struct timeval to;
to.tv_sec = 0;
to.tv_usec = 100000;
*/
//fd_set rdfdsCopy = rdfds;
//cout << "Entering second while loop" << endl;
while (slct > 0)
{
//cout << "Call to select" << endl;
//slct = select((fd+1), &rdfdsCopy, NULL, NULL, &to);
slct = poll(&fds, 1, 100);
if (slct > 0)
{
//cout << "Next call to read, would not block" << endl;
rd = read(fd, &mes, sizeof(mes));
storeInBuff(mes, rd);
//rdfdsCopy = rdfds;
}
}
findFrame(0);
ind = 0;
fill_n(buff, 2048, '\0');
}
}
}
我的问题是,当它启动时它完美无缺。但是在20分钟之后,它再也没有完成它的工作了。 CPU使用率达到100%,因此读取呼叫似乎不再阻止。它就像文件描述符不再链接到设备......
由于我绝对不知道原因和错误,因为它在崩溃之前需要一段随机的时间,所以我不能将它取消守护并在终端上观看输出......
所以我想问:
我添加了一个检查无线电插头的情况,因此程序无法退出。我很确定这不是问题,因为在崩溃发生后模块保持在/dev/ttyUSB0
之下。
我使用的是Debian 3.2.57-3 i686。
在将我的无线电模块用于其他软件时,我不会遇到任何问题。
我似乎没有问题在另一台类似的计算机上使用此代码......
感谢阅读并抱歉不太好的英语。
编辑:从这篇文章和这个程序更准确地说明我想要的东西: 在某些时候,程序无法阻止读取,并且每个toher调用读取不会阻止并且不读取任何内容,因此程序不会执行为其创建的内容:来自无线电的日志数据模块。我只是想避免它,因为如果没有它,它可以很好地工作,它可能会对硬件造成伤害。
答案 0 :(得分:1)
快速查看代码 - 如果在读取时出现EOF或错误(即read()返回零或-1),您将永远循环。我可以看到你处于原始模式,但我看到FTDI驱动程序和固件中的各种错误可能导致这种情况发生,并且不是你要处理的情况。
答案 1 :(得分:0)
所以我跟着@janm提示。我删除了这一行:
tty.c_cflag &= ~CRTSCTS;
并做了这样的测试:
rd = read(fd, &mes, sizeof(mes));
if (rd > 0)
{
doSomeStuff();
}
else
{
close(fd);
serialConfig();
listenPort();
}
也许当阅读失败时,我会丢失一些数据,但至少程序无法关闭,不必手动重启。