簡體   English   中英

linux串口read()錯誤數據

[英]linux serial port read() wrong data

我正在編寫一個用於與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;
}

在write()和read()之間使用sleep()在write()和read()之間沒有sleep()

埃里克

首先使用read()的返回值。 切記:read 不會產生以nul結尾的字符串。

n=read(fd, in, 100);

        printf("%*.*s\n", n,n, in);

(1)務必檢查返回碼。 (2)如果您嘗試打印未終止為null的字符串,則最終將打印出內存中(或更糟)的所有垃圾。

我的猜測是,您真正的問題是不能保證讀/寫操作可以寫入您指定的字節數。 他們實際讀/寫的數字在返回碼中。 因此,當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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM