我正在编写一个与AVR MCU通信的小程序,在PC端我用posix write()和read()来访问串口,我连接串口的RX和TX引脚进行测试如果它可以正确地发送和接收数据,理论上发送的所有内容应该在接收缓冲区中完全相同,当发送的消息很短并且发送频率很低时,read()返回相同的消息。发送出去,但是当消息变得更长并且发送频率更高时,read()返回错误的数据,字符似乎是错误的顺序,我猜是read()或write()不是块模式,所以当旧传输尚未完成,新传输(write()?)到达,中断旧传输并更改TX缓冲区。
我是Linux编程的新手,请有人帮我这个,它杀了我...... 非常感谢任何帮助。
编辑:我在write()手册页中注意到: 从write()成功返回并不能保证数据已提交到磁盘。事实上,在一些错误的实现上,它甚至不能保证已成功为数据保留空间。唯一可以确定的方法是在完成所有数据写入后调用fsync(2)。
我尝试了fsync()函数,但仍然得到了相同的错误结果。
以下是代码:
#include <stdio.h>
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
int main(void) {
int fd;
// fd = open("/dev/tty.usbmodem1a21", O_RDWR | O_NOCTTY | O_NDELAY);
fd = open("/dev/tty.usbmodem1a21", O_RDWR | O_NOCTTY);
if (fd == -1) {
//Could not open the port.
perror("open_port: Unable to open port ");
}
else
fcntl(fd, F_SETFL, 0);
char s[] = "Hello, this is a test of the serial port access";
int cnt;
unsigned char in[100];
for(cnt=0; cnt<10; cnt++) {
int n = write(fd, s, sizeof(s));
if (n < 0)
fputs("write() failed!\n", stderr);
usleep(50000); // works fine with delay
read(fd, in, 100);
printf("%s\n", in);
}
return 0;
}
埃里克
答案 0 :(得分:2)
首先使用read()的返回值。请记住:读不会产生以空字符结尾的字符串。
n=read(fd, in, 100);
printf("%*.*s\n", n,n, in);
答案 1 :(得分:2)
(1)始终检查返回代码。 (2)如果你尝试printf一个没有空终止的字符串,你将最终打印内存中的任何垃圾(或者更糟糕)。
我的猜测是你真正的问题是读/写不能保证写入你指定的字节数。它们实际读/写的数字在返回码中。因此,当fd缓冲区填满时,您可能会写入1个字节,然后尝试打印该1个字节的非空字符串及其后的所有内容。
尝试这样的事情,看看情况是否有所改变。
int cnt;
unsigned char in[100];
for(cnt=0; cnt<10; cnt++)
{
int n = write(fd, s, sizeof(s));
if (n < 0)
{
perror("write");
exit(EXIT_FAILURE);
}
n = read(fd, in, 100);
if (n < 0)
{
perror("read");
exit(EXIT_FAILURE);
}
in[n] = '\0';
printf("%s\n", in);
}