gpt4 book ai didi

c - 在 C 中刷新 linux 串行缓冲区

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:36:09 26 4
gpt4 key购买 nike

我有一个蓝牙 IMU(在/dev/rfcomm0 中被视为串行设备),它以四元数的形式每秒返回 50 次当前角度。

我做了一个读取数据的测试程序并且它有效,但我必须将它集成到一个 while 循环中,在读取完成后,创建一个线程并完成计算昂贵的详细说明,所以我无法读取与 IMU 数据保持速率。

IMU 向我发送了一个 54 字节的数据包,前两个字节始终设置为 Ascii“tt”。

这是我正在使用的 C 代码:

int set_interface_attribs(int fd, int speed)
{
struct termios tty;

if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}

cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);

tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */

/* setup for non-canonical mode */
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;

/* fetch bytes as they become available */
tty.c_cc[VMIN] = 54;
tty.c_cc[VTIME] = 1;

if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}

int start_serial()
{
char *portname = "/dev/rfcomm0";
int fd;
int wlen;
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
printf("Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
set_interface_attribs(fd, B115200);
wlen = fwrite(fd, "?!CALIB050!?\n", 14);
if (wlen != 14) {
printf("Error from write: %d, %d\n", wlen, errno);
}

tcflush(fd,TCIFLUSH);
tcdrain(fd); /* delay for output */
return fd;
}

int read_serial(int fd)
{
char buf[54];
int rdlen;
rdlen = read(fd, buf, 54);
if (rdlen > 0)
{
struct CPacketCalib cc = CPacketCalibConvert(buf);
printf("%f %f %f %f\n",cc.q.I, cc.q.J, cc.q.K,cc.q.W);
}
else if (rdlen < 0)
{
printf("Error from read: %d: %s\r\n", rdlen, strerror(errno));
}
return 1;
}

int stop_serial(int fd)
{
int wlen = write(fd, "?!STOPSEND!?\n", 14);
if (wlen != 14)
{
printf("Error from write: %d, %d\n", wlen, errno);
}
fclose(fd);
return 1;
}

如何在每个周期刷新串行缓冲区并开始正确获取我的数据包?

感谢您的帮助。

最佳答案

您的问题听起来像是您在数据包的中间开始读取并获得一个数据包的一半和另一个数据包的一半。在这种情况下,您需要阅读直到到达数据包的开头,然后才将其提供给您的解析函数。所以像这样:

char ch;
char[52] buf;
while(1){
if(read(fd, &ch, sizeof(ch)) > 0 && ch == 't'){
if(read(fd, &ch, sizeof(ch)) > 0 && ch == 't'){
if(read(fd, buf, sizeof(buf)) == sizeof(buf)){
struct CPacketCalib cc = CPacketCalibConvert(buf);
}
}
}
}

所以 CPacketCalibConvert 只会用完整的数据包调用(减去两个 't',也许将它们添加回最里面的 block 内?)。

关于c - 在 C 中刷新 linux 串行缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48753391/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com