我有一些麻烦读取一些数据从串口我打开以下的方式。 我已经使用了这个代码大量的代码,一切正常,但现在,由于某种原因,我无法弄清楚,我完全无法从串口读取任何东西。
我可以写,所有的都是正确接收的另一端,但答复(这是正确发送)从来没有收到(不,电缆都没问题))
我用来打开串口的代码如下:
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];
端口初始化后,我通过简单的写入命令写入一些东西…
int nc = write(hCom, txchar, n);
其中hCom是文件描述符(也是可以的),(正如我所说)这是有效的。 但是,当我做了一个阅读之后,我得到了一个来自errno的“Resource暂时不可用”的错误。
我testing了select,看看什么时候文件描述符有东西读取…但它总是超时!
我读这样的数据:
ret = read(hCom, rxchar, n);
我总是得到一个EAGAIN,我不知道为什么。
硬件工作正常! 我可以看到在串口上有入站数据,因为我已经制作了一个debugging电缆来读取另一个terminal上正在发生的事情。 所以…
我知道非阻塞应该做什么。 我的问题是…为什么没有阅读! 相同的设置在Windows上工作正常,所以所有的硬件工作正常…
这让我疯狂! 我敢肯定,这是一个简单的地狱! 我甚至尝试摆脱O_NONBLOCK,看看我什么时候会收到东西…但没有…
阅读这个 。
EAGAIN使用O_NONBLOCK选择了非阻塞I / O,并且没有数据立即可用于读取。
您需要首先检查串行终端设置。
使用命令- stty -F /dev/ttyUSB0 -a
检查ctsrts
是否被选为-ctsrts
,并使用stty
实用程序执行其他所需的设置,然后完成。
EAGAIN
与O_NONBLOCK
意味着端口上没有收到数据。 检查端口和电缆是否正常工作(使用minicom或其他已知的程序),并确认远程设备正在发送一些数据。
看我的代码示例,如果EAGAIN,你会尝试再次阅读:
... 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. } } ...
我有着同样的问题。 我可以传输但不能接收(通过USB-RS232适配器电缆)。 我尝试了另一个有一个RS232端口的Linux机器,它工作得很好。 我做的唯一的改变是从/dev/ttyUSB0
到/dev/ttyS0
。 第一台电脑是Fedora,第二台是Debian。 除此之外,idunno。
还有一件事 当我关闭com程序并重新启动时,数据被我的程序读取! 数据是输入缓冲区,但我的程序不知道它。 此外,GTKTENT工作正常,所以H / W是一切OK。 我的程序没有看到UART中断。
这个linux的h / w抽象层是相当虚假的。 这不应该是一个问题。