gpt4 book ai didi

linux - UART 回复包括之前的命令?

转载 作者:太空宇宙 更新时间:2023-11-04 09:12:16 27 4
gpt4 key购买 nike

我尝试使用 C 程序在 Linux 环境中读取 UART 设备,但在使用屏幕与 UART 通信方面我遇到了不同的结果。

我用来测试UART通信的C代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <getopt.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <signal.h>
#include <ctype.h>

bool loop;

void sigHandler(int32_t sig)
{
if(sig == SIGINT)
{
printf("Catched SIGINT");
loop = false;
}
}

int main(int argc, char *argv[])
{
char *devname = argv[1];
int fd = -1;

int nread = -1;
int nwrite = -1;

int ret;

struct termios t_new = {0};
struct termios t_old = {0};


signal(SIGINT, sigHandler);


fd = open(devname, O_RDWR | O_NOCTTY |O_NONBLOCK);
if(fd > 0)
{
printf("TTY open ! Configuring TTY");
}
else
{
fd = -1;
return 1;
}

ret = tcgetattr(fd, &t_old);
if(ret < 0)
{
perror("tcgetattr ");
close(fd);
fd = -1;
return 1;
}

t_new = t_old;
t_new.c_cflag = (B9600 | CS8 | CREAD );
t_new.c_oflag = 0;
t_new.c_iflag = 0;
t_new.c_lflag = 0;

ret = tcsetattr(fd, TCSANOW, &t_new);

loop = true;
while(loop)
{
char s[] = "at+gmi=?\r\n";
nwrite = write(fd, s, strlen(s));
if(nwrite == strlen(s))
{
fd_set rfd;
struct timeval tm = {.tv_sec = 0, .tv_usec = 500000};
FD_ZERO(&rfd);
FD_SET(fd, &rfd);

char buffer[64] = {0};

if(select(fd + 1, &rfd, NULL, NULL, &tm) > 0)
nread = read(fd, buffer, sizeof(buffer));

if(nread > 0)
printf("Reply is: %s\n", buffer);
}

usleep(500000);
}
}

但是当我阅读回复时,它总是包含我发送的字符串。我在使用 screen 时没有遇到这个问题。

使用 Linux 以 C 语言读取 UART 的最佳方法是什么?多路复用方式(使用 select)会导致问题吗?

编辑为了完整起见,输出为:

Reply is: at+gmi=?

OK

另外,有时我什么都不读。

最佳答案

But when I read the reply, it always includes the string I have sent.

由于您的 termios 配置消除了本地回声属性并且您正在发送 AT 调制解调器命令,您应该尝试发送 ATE0 命令来禁用调制解调器的回声。

I don't experience this problem using screen.

此观察确认已连接的调制解调器已启用其回显。

AT 命令在您键入时(由调制解调器)回显,但在这种情况下您不反对接收到的数据(因为您想查看您键入的内容)。
如果调制解调器没有启用回显,那么您会提示您在屏幕 中键入的内容不可见。

当使用终端仿真程序(例如screen)时需要IOW回显,但当通过程序发送数据时需要禁用回显。

What is the best way to read from an UART in C using Linux ?

(从技术上讲,您不是从 “UART” 读取数据,而是从完全缓冲所有输入和输出的串行终端读取数据。)
符合 Setting Terminal Modes Properly 中描述的 POSIX 标准的代码和 Serial Programming Guide for POSIX Operating Systems会比你现在拥有的要好得多。
我很惊讶它能正常工作(例如 CREAD 未启用)。

Could the multiplexed way (using select) causing the problems ?

不是回声“问题”。
您的程序不会执行任何需要使用 select() 和非阻塞模式的操作。

Also, sometimes I don't read anything.

当您编写不符合 POSIX 标准的代码时,您不应期待可靠的程序行为。

关于linux - UART 回复包括之前的命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53831329/

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