我正在为一个小型硬件项目开发接收器。我正在研究一个使用UART传输数据的小型板子。
下面是完整的接收器代码,稍后我将逐个解释问题所在。
#define TTY "/dev/ttys002"
#include <stdio.h>
#include <string.h>
#include <unistd.h> //Unix standard functions
#include <fcntl.h> //File controls
#include <errno.h> //Error numbers
#include <assert.h>
#include <termios.h> //Posix terminal
int open_port(const char * tty) {
int fd;
fd = open(tty, (O_RDWR | O_NOCTTY | O_NDELAY));
assert("__failed to open port__" && fd != -1);
//Block until read
fcntl(fd, F_SETFL, 0);
return fd;
}
void configure_port(int fd) {
struct termios options;
//Get current options
tcgetattr(fd, &options);
//9600 Baud
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
//Receive & local mode
options.c_cflag |= (CLOCAL | CREAD);
//Raw output
options.c_oflag &= ~OPOST;
//No hardware flow control
options.c_cflag &= ~CRTSCTS;
//No parity, 1 stop bit
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
//8 data bits
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//Write options back, set them immediately
tcsetattr(fd, TCSANOW, &options);
}
int main(int argc, const char * argv[]) {
int fd = open_port(TTY);
const size_t count = 8;
char buf[count + 1];
ssize_t n;
configure_port(fd);
while (1) {
n = read(fd, buf, count);
buf[count] = '\0';
if (n > 0) {
printf("%s\n", buf);
}
}
return 0;
}
由于我目前手头没有我的硬件,所以我决定在常规tty上测试我的接收器(#define TTY "/dev/ttys002"
)。为了测试它,我只需编译并运行上述代码,然后打开一个单独的终端并执行以下操作:
echo "text" >> /dev/ttys002
所有这些工作都很好,并且我获取了所有要回显到tty的数据。
然而,当我将长消息输入到tty中时,问题就出现了:
echo "this is a longer test message" >> /dev/ttys002
在我的程序输出中,我将整个消息作为一个单独的字符串接收到。为什么会这样?我本来希望文本被分成8个字符一块(const size_t count = 8;
)。
如果重要的话,我正在使用这个指南进行配置。
编辑:请参见评论以进一步讨论此问题。
printf("%s\n", buf);
改为printf("[%s]\n", buf);
,但它仅打印了原始字符串。可能是我的测试设置有问题,但请尝试一下,因为如果您得到相同的结果,则您的起始前提是错误的。 - Jongwarebuf
中。我刚刚删除了while
循环内的所有内容,只留下while (1) {}
... 这并没有产生任何影响。 - JongwareICANON
,得到了一些令人惊讶的结果(事后想想,这与ICANON
设置无关)。添加一行printf ("%ld bytes received\n", n);
并重新启动。打开另一个终端并启动man termios
。现在,一些键入到man
终端中的字符将被回显到您的陷阱中!这需要一个终端专家。 - Jongware