I am having some trouble reading some data from a serial port I opened the following way. I've used this instance of code plenty of times and all worked fine, but now, for some reason that I cant figure out, I am completely unable to read anything from the serial port.
我用下面的方法打开一个串口,在读取一些数据时遇到了一些麻烦。我已经多次使用这个代码实例,并且都运行得很好,但是现在,由于某些原因,我无法理解,我完全无法从串行端口读取任何内容。
I am able to write and all is correctly received on the other end, but the replies (which are correctly sent) are never received (No, the cables are all ok ;) )
我可以写,并且所有的都正确地收到了,但是回复(正确发送的)从来没有收到(不,电缆都是ok的)。
The code I used to open the serial port is the following:
我打开串口的代码如下:
fd = open("/dev/ttyUSB0", O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd == -1)
{
Aviso("Unable to open port");
return (fd);
}
else
{
//Get the current options for the port...
bzero(&options, sizeof(options)); /* clear struct for new port settings */
tcgetattr(fd, &options);
/*-- Set baud rate -------------------------------------------------------*/
if (cfsetispeed(&options, SerialBaudInterp(BaudRate))==-1)
perror("On cfsetispeed:");
if (cfsetospeed(&options, SerialBaudInterp(BaudRate))==-1)
perror("On cfsetospeed:");
//Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB; /* Parity disabled */
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE; /* Mask the character size bits */
options.c_cflag |= SerialDataBitsInterp(8); /* CS8 - Selects 8 data bits */
options.c_cflag &= ~CRTSCTS; // disable hardware flow control
options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable XON XOFF (for transmit and receive)
options.c_cflag |= CRTSCTS; /* enable hardware flow control */
options.c_cc[VMIN] = 0; //min carachters to be read
options.c_cc[VTIME] = 0; //Time to wait for data (tenths of seconds)
//Set the new options for the port...
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &options)==-1)
{
perror("On tcsetattr:");
}
PortOpen[ComPort] = fd;
}
return PortOpen[ComPort];
After the port is initializeed I write some stuff to it through simple write command...
在端口被初始化之后,我通过简单的写命令给它写一些东西……
int nc = write(hCom, txchar, n);
where hCom is the file descriptor (and it's ok), and (as I said) this works. But... when I do a read afterwards, I get a "Resource Temporarily Unavailable" error from errno.
hCom是文件描述符(它是ok的),并且(如我所说)它可以工作。但是…当我之后进行读取时,我从errno获得一个“资源暂时不可用”错误。
I tested select to see when the file descriptor had something t read... but it always times out!
我测试了select,看看文件描述符什么时候读不了……但它总是超时!
I read data like this:
我读过这样的数据:
ret = read(hCom, rxchar, n);
and I always get an EAGAIN and I have no idea why.
我总是得了重感冒,我不知道为什么。
Update:
The HW is working fine! I can see that there is inbound data on the serial port because I've made a debug cable to read whats going on on another terminal. So...
HW运行良好!我可以看到串行端口上有入站数据,因为我做了一条调试电缆来读取另一个终端上正在发生的事情。所以…
I know what nonblocking should do. My question is... why isn't anything getting read!. The same setup works fine on windows, so all hardware is working fine...
我知道非阻塞应该做什么。我的问题是……为什么没有任何东西被阅读!同样的设置在windows上运行良好,所以所有硬件都运行良好……
This is driving me nuts! I'm sure it's something simple as hell! I even tried getting rid of O_NONBLOCK to see when I would receive something... but nothing...
这真让我发疯!我敢肯定,这简直就是地狱!我甚至试着去掉O_NONBLOCK,看看什么时候会收到一些东西……但是没有……
5 个解决方案
#1
11
Read this.
读这篇文章。
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.
使用O_NONBLOCK选择了非阻塞I/O,并且没有立即可用的数据进行读取。
#2
2
You need to check the serial terminal settings first.
您需要先检查串行终端设置。
use command - stty -F /dev/ttyUSB0 -a
使用命令- stty - f /dev/ttyUSB0 -a
Check that ctsrts
is selected as -ctsrts
and do the other required settings with stty
utility and you are done.
检查ctsrts是否被选择为-ctsrts,并使用stty实用工具进行其他必需的设置,您就完成了。
#3
0
EAGAIN
with O_NONBLOCK
means there's been no data received on the port. Check that the port and cable are working properly (using minicom or some other known-good program), and that the remote really is sending some data.
O_NONBLOCK的EAGAIN意味着端口上没有接收到数据。检查端口和电缆是否正常工作(使用minicom或其他一些已知的好程序),并且远程程序确实正在发送一些数据。
#4
0
see my code samples, if EAGAIN, you'd try to read again:
看看我的代码样本,如果再次,你会尝试再次阅读:
...
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
...
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // input
options.c_oflag &= ~OPOST; // output
...
fd = open("/dev/ttyUSB0", O_RDWR | O_NDELY | O_NOCTTY);
fcntl(fd, F_SETFL, 0);
...
int nc = write(hCom, txchar, n);
msleep(500); // wait 500ms
fcntl(hCom, F_SETFL, FNDELAY); // don't block serial read
ret = read(hCom, rxchar, n);
if (ret > 0) {
here had read n bytes or just partial data, read again if partial.
}
if (ret < 0) {
if (EAGAIN == errno) {
not a real error, just read again.
} else {
oops, errors.
}
}
...
#5
0
I have this same problem. I can transmit but not receive (via USB-RS232 adapter cable). I tried on another linux box that had a RS232 port and it worked just fine. The only change I made was from /dev/ttyUSB0
to /dev/ttyS0
. The first computer was Fedora the second is Debian. Other than that, idunno.
我也有同样的问题。我可以发送但不接收(通过USB-RS232适配器电缆)。我尝试了另一个有RS232端口的linux盒子,它工作得很好。我所做的唯一更改是从/dev/ttyUSB0到/dev/ ttys0。第一个是Fedora,第二个是Debian。除此之外,idunno。
One other thing. When I close the com program and restart it, the data is read by my program! The data is the input buffer, but my program does not know it. Also, gtkterm works fine, so the h/w is all OK. My program does not see the UART interrupt.
另一件事。当我关闭com程序并重新启动它时,数据被我的程序读取!数据是输入缓冲区,但我的程序不知道它。同时,gtkterm也可以正常工作,所以h/w是可以的。我的程序没有看到UART中断。
This linux h/w abstraction layer is rather bogus. This should not be a problem.
这个linux h/w抽象层相当假。这应该不是问题。
#1
11
Read this.
读这篇文章。
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.
使用O_NONBLOCK选择了非阻塞I/O,并且没有立即可用的数据进行读取。
#2
2
You need to check the serial terminal settings first.
您需要先检查串行终端设置。
use command - stty -F /dev/ttyUSB0 -a
使用命令- stty - f /dev/ttyUSB0 -a
Check that ctsrts
is selected as -ctsrts
and do the other required settings with stty
utility and you are done.
检查ctsrts是否被选择为-ctsrts,并使用stty实用工具进行其他必需的设置,您就完成了。
#3
0
EAGAIN
with O_NONBLOCK
means there's been no data received on the port. Check that the port and cable are working properly (using minicom or some other known-good program), and that the remote really is sending some data.
O_NONBLOCK的EAGAIN意味着端口上没有接收到数据。检查端口和电缆是否正常工作(使用minicom或其他一些已知的好程序),并且远程程序确实正在发送一些数据。
#4
0
see my code samples, if EAGAIN, you'd try to read again:
看看我的代码样本,如果再次,你会尝试再次阅读:
...
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
...
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // input
options.c_oflag &= ~OPOST; // output
...
fd = open("/dev/ttyUSB0", O_RDWR | O_NDELY | O_NOCTTY);
fcntl(fd, F_SETFL, 0);
...
int nc = write(hCom, txchar, n);
msleep(500); // wait 500ms
fcntl(hCom, F_SETFL, FNDELAY); // don't block serial read
ret = read(hCom, rxchar, n);
if (ret > 0) {
here had read n bytes or just partial data, read again if partial.
}
if (ret < 0) {
if (EAGAIN == errno) {
not a real error, just read again.
} else {
oops, errors.
}
}
...
#5
0
I have this same problem. I can transmit but not receive (via USB-RS232 adapter cable). I tried on another linux box that had a RS232 port and it worked just fine. The only change I made was from /dev/ttyUSB0
to /dev/ttyS0
. The first computer was Fedora the second is Debian. Other than that, idunno.
我也有同样的问题。我可以发送但不接收(通过USB-RS232适配器电缆)。我尝试了另一个有RS232端口的linux盒子,它工作得很好。我所做的唯一更改是从/dev/ttyUSB0到/dev/ ttys0。第一个是Fedora,第二个是Debian。除此之外,idunno。
One other thing. When I close the com program and restart it, the data is read by my program! The data is the input buffer, but my program does not know it. Also, gtkterm works fine, so the h/w is all OK. My program does not see the UART interrupt.
另一件事。当我关闭com程序并重新启动它时,数据被我的程序读取!数据是输入缓冲区,但我的程序不知道它。同时,gtkterm也可以正常工作,所以h/w是可以的。我的程序没有看到UART中断。
This linux h/w abstraction layer is rather bogus. This should not be a problem.
这个linux h/w抽象层相当假。这应该不是问题。