我正在尝试从我的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);
}
因此,当我运行程序时,自然会创建写入线程等待输入。然后,我输入AT
和AT+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.
...
答案 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);