c - 串行端口(AT 命令)不断传输单个字节或 ERROR

标签 c serial-port at-command

我正在尝试从我的 BananaPi (Debian jessie) 的串行端口读取数据。我写了这段代码:

typdef struct write_args {
    int fd;
} write_args;

/* Thread to wait for user input */
void* serial_write_fn(void* args)
{
    write_args* wargs = (write_args*)args);
    char buf[256];
    while (1) {
        memset(buf, 0, sizeof(buf));
        fgets(buf, sizeof(buf), stdin);

        n = write(wargs->fd, buf, strlen(buf));
        if (n < 0) {
            fputs("write() failed.\n", stderr);
            return NULL;
        }
    }
    return NULL;
}

void serial()
{
    int fd = open("/dev/ttyACM0", O_RDWR | O_NOCCTY | O_NDELAY);
    if (fd == -1) {
        perror("open port failed.");
        return;
    }

    fcntl(fd, F_SETFL, 0);

    /* Create write thread */
    write_args wargs;
    wargs.fd = fd;
    pthread_t tid;
    int err = pthread_create(&tid, NULL, &serial_write_fn, &wargs);
    if (err != 0)
        perror("Failed to create thread.");

    char buffer[512];
    while (1) {
        memset(buffer, 0, 512);
        ssize_t bytes = read(fd, buffer, 512);

        if (bytes > 1) /* Try to remove this line */
            printf(buffer);
    }

    close(fd);
}

因此,当我运行程序时,它自然会创建写入线程并等待输入。然后,我输入 ATAT+VCID=1,两次都得到 OK 作为答案:

AT
OK
AT+VCID=1
OK

然后,我尝试调用该号码以查看输出,结果

RING
DATE = 0722
TIME = 0441
NMBR = 6982311133
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
...

这是第一个问题。第二个问题是,当我尝试删除最后一个 if ( if (bytes > 1) ) 时,read 函数永远不会停止读取数据。它总是返回 1 个字节。

我做错了什么吗?为什么我不断收到错误消息以及为什么 read 函数始终有 1 个字节要读取?

编辑#1

因此,在 MartinJames 发表评论后,我决定进行更多调查。

我将读取循环更改为:

while (1) {
    memset(buf, 0, sizeof(buf));
    bytes = read(fd, buf, sizeof(buf));
    if (bytes == 0) {
        printf("Read 0 bytes.\n");
        break;
    } else if (bytes == -1) {
        printf("Read -1 bytes.\n");
        break;
    } else if (bytes == 1) {
        printf("Read 1 bytes.\n");
    } else {
        printf(buf);
    }
}

程序运行并等待我编写命令。我写了at,正如你所看到的,读取函数每次都返回 1 个字节,除了偶尔有一些 OK 之外。

thecrafter@bananapi:~/serial$ sudo make run
Executing bin/Debug/serial.out ...
at <--- I typed that and clicked Enter
at
Read 1 bytes.
Read 1 bytes.
OK
Read 1 bytes.
Read 1 bytes.
atat
Read 1 bytes.
Read 1 bytes.
Read 1 bytes.
Read 1 bytes.
Read 1 bytes.
Read 1 bytes.
Read 1 bytes.
OK
Read 1 bytes.
Read 1 bytes.
...

最佳答案

事实证明,锯末正确地指出我应该阅读 Serial Programming Guide for POSIX Operating Systems更加仔细。

解决我的问题的配置是:

struct termios opt;
tcgetattr(fd, &opt);
opt->c_cflag     |= (CLOCAL | CREAD);
opt->c_lflag     &= ~(ICANON | ECHO | ECHOE | ISIG);
opt->c_oflag     &= ~OPOST;
opt->c_cc[VMIN]  = 1;
opt->c_cc[VTIME] = 10;
tcsetattr(fd, TCSADRAIN, &opt);

关于c - 串行端口(AT 命令)不断传输单个字节或 ERROR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45249867/

相关文章:

c - 在C中用另一个字符串替换字符串的一部分

c - 如何并行斐波那契数列直到 10^5 项

python - 将变量分配给 pyserial 端口

c - 读取系统调用未检测到文件结尾

excel - 从 Matlab 发送短信并确保所有收件人都收到短信

putty - 通过 USSD 查询余额时出错

http - 使用 SIM 900 中的 gprs 连接向服务器发送数据时收到错误的请求响应

c - 填充数组为空 - 中止陷阱 :6

c - 海明码错误检测

linux - 确定哪个 USB 设备是/dev/ttyUSB0