我使用串口从设备接收数据。通信工作正常,但读取数据存在问题。我正在使用Linux(Ubuntu)。
这是我的代码:
int OpenPort(char *PortName, int *FileDesc) {
*FileDesc = open (PortName, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
perror("fakap");
return (P_OPEN_ERROR);
}
else return(P_OPEN_SUCCESS);
};
int SetPortAtributes (int fd, int speed, int parity) {
struct termios tty;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0)
{
perror("error %d from tcgetattr");
return -1;
}
cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag |= (IGNBRK | IGNPAR);,
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_iflag &= ~(ISTRIP);
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD | HUPCL); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
tty.c_lflag = 0;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
perror("error %d from tcsetattr");
return -1;
}
return 0;
}
阅读部分:
void PortRead(int *FileDesc) {
memset(&recBuff[0], 0, sizeof(recBuff)); //clear buff
int n = read (*FileDesc, recBuff, sizeof(recBuff)); // read
printf("n: %d \n", n);
int i = 0;
for(i = 0;i<n;i++) {
recData.buf[i].b_int = recBuff[i]; // put rec buff to ANS_u type variable
}
};
一切正常,直到我收到大于8个字节的消息。 read()不会读取超过8个字节,所以我必须使用read()第二次读取读取所有数据。 当我使用GtkTerm时,一切正常,但是在C实现过程中存在问题。
答案 0 :(得分:2)
所以我必须第二次使用read()来读取所有数据。
您必须准备好在任何情况下拨打read()
第二,第三,第四等时间。 始终即可。只是因为你知道对方已经发送了16个字节,你不能假设在一次操作中所有16个字节都将来自read()
。它可能是8 + 8,16 * 1,3 + 3 + 10,或任何其他总和达16的组合(尽管大多数组合极不可能)。
从阅读(2)的手册页:
返回值
成功时,返回读取的字节数... 如果此数字小于请求的字节数
,则不是错误
你也应该像已经评论的那样准备好处理EINTR。
在函数OpenPort中,open的结果被分配给* FileDesc但是其他一些fd变量被检查,也应该被修复。
答案 1 :(得分:1)
我不确定,但看起来'recBuff'是指向intput缓冲区的指针。
int n = read (*FileDesc, recBuff, sizeof(recBuff)); // read
如果这是真的,则sizeof(recBuff)等于8.(指针大小为8)。可以理解的是,最多8个字节是愿意阅读的。
答案 2 :(得分:0)
例如,可能会发生这种情况,因为实际上字节更少 现在可用(也许是因为我们接近文件结尾,或者 因为我们正在从管道或终端读取,或因为 read()被信号打断了。
只要有可用数据,就重复读取。
此外,由于另一端是一个微控制器,可能比你的工作站大很多,所以当你执行read()时,数据可能还不可用。当然,这是再次尝试的另一个原因。
看起来你可以试试
int n = 0, offset = 0, bytes_expected = 40;
do
{
n = read (*FileDesc, recBuff+offset, sizeof(recBuff));
offset += num;
} while (offset < bytes_expected);