gpt4 book ai didi

c - 串行 c 在 linux 中读取有问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:25:02 25 4
gpt4 key购买 nike

我正在尝试使用 Odroid(单机板)在 C 中读取串口以通过 USB 电缆从 arduino 板获取数据。正在发布传感器数据的是 189。波特率为115200。

读取使用的主要代码:

#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/ipc.h>
#include <sys/shm.h>
#include "share.h"
#include <math.h>
#include <stdlib.h>
#pragma GCC diagnostic ignored "-Wwrite-strings"

/*
* @brief Open serial port with the given device name
*
* @return The file descriptor on success or -1 on error.
*/
int open_port(char *port_device)
{
int fd; /* File descriptor for the port */

fd = open(port_device, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
perror("open_port: Unable to open /dev/Servo_LIDAR ");
}
else
fcntl(fd, F_SETFL, 0);

return (fd);
}

int main()
{

//--------------------------------------------------------------------------------
struct termios options;
int fd=-1;
char *u_port = "/dev/Servo_LIDAR";
fd=open_port(u_port);
if(fd==-1)
{
printf("port not open");
return -1;
}

tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);

//Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CSIZE; /* Mask the character size bits */
options.c_cflag |= CS8; /* Select 8 data bits */

//No parity
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;

//Set the new options for the port...
tcsetattr(fd, TCSANOW, &options);


printf("Reading...\n");

while(true)
{


while(1)
{
//sleep(0.5);
char buff[1024]={0};
char buf[1]={0};
while(1) {
ssize_t res=read(fd, buf, 1);

if(res==0) continue;
buf[res]=0;

strcat(buff,buf);
if (buf[0] == '\n') break;
}
printf("%s\n", buff);
usleep(70000);
break;
}
}

close(fd);


}

我有这样的约会:

187

187187187

188

188188

188188188

188

1888

188

18188

188

186187

187

187

每次应该是 3 个字节的数据,但我遇到了这样的问题。任何建议,谢谢。

最佳答案

您的主要错误涉及语句:

    char buf[1]={0};
...
ssize_t res=read(fd, buf, 1);
...
buf[res]=0;

数组 buf[] 被声明为只有 一个 元素长,即 buf[0] 是数组的唯一元素.
read() 系统调用在成功时将返回值 1,因为这是指定的计数。
然后您尝试通过写入 buf[1] 来终止接收到的文本,但那是一个尚未分配的元素。
数组 buf[] 需要至少包含 2 个元素。

此错误的症状会因编译器和主机系统而异。在使用 gcc 4.8.4 的 x86 笔记本电脑上,您的原始程序根本不产生任何输出。

有关终止缓冲区数据的首选方法,请参阅 Linux Serial Read throws Error


代码审查

  1. 所有系统调用,包括tc[gs]etattr()read(),都应该检查错误返回代码,尤其是当您的程序没有表现如你所愿。

  2. 您的termios 配置不完整。您的程序将以任何先前配置的规范或非规范模式执行。这可能会产生意想不到的结果。

  3. 一次只读取一个字符(嵌套在多个 while 循环中)效率低下。规范读取可以为每个系统调用返回一行。学习"Two Styles of Input: Canonical or Not"

  4. usleep(70000) 等程序延迟是多余的。文件/设备已打开以阻止读取,因此 read() 在数据可用之前不会返回。

关于c - 串行 c 在 linux 中读取有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36589454/

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