linux串口read()错误的数据

时间:2011-11-08 16:37:36

标签: linux serial-port posix

我正在编写一个与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;
}

with sleep() between write() and read() without sleep() between write() and read()

埃里克

2 个答案:

答案 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);
}