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

时间:2017-07-22 01:54:28

标签: 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个字节。

我做错了吗?为什么我一直得到ERROR以及为什么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);
    }
}

程序运行并等待我编写命令。我在写了,正如你所看到的,read函数每次返回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.
...

1 个答案:

答案 0 :(得分:0)

事实证明,锯末是正确的,我应该更仔细地阅读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);