[英]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;
}
埃里克
首先使用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.