2016-05-25 45 views
0

我正在開發一個開發板(Beagle Bone Black)的應用程序,它將通過UART外設發送一些數據。開發板運行Linux Kernel(一些Debian發行版,3.8.x Linux內核版本)。UART上的串行數據被破壞

對於超過UART發送和接收數據I使用標準UNIX API:open()read(),和write()家庭功能。

用於設置通信參數(baud ratestop/start bitsparity,等...)我使用termios結構(從termios.h)。

這是一些相關的代碼序列,其中我做I/O設置:

fd_debug = open("output.out", O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 

fd_write = open(port.c_str(), O_WRONLY | O_NOCTTY | O_SYNC); 
std::cout << std::endl << "I opened: " << port; 

struct termios settings; 
tcgetattr(fd_write, &settings); 

cfsetospeed(&settings, B19200);   /* baud rate */ 
settings.c_cflag &= ~PARENB;   /* no parity */ 
settings.c_cflag &= ~CSTOPB;   /* 1 stop bit */ 
settings.c_cflag &= ~CSIZE; 
settings.c_cflag |= CS8 | CLOCAL;  /* 8 bits */ 
settings.c_lflag = ICANON;    /* canonical mode */ 
settings.c_oflag &= ~OPOST;    /* raw output */ 

tcsetattr(fd_write, TCSANOW, &settings); /* apply the settings */ 
tcflush(fd_write, TCOFLUSH); 

在那裏,我開了兩個文件描述符:

  • fd_debug:掛一檔,進行調試。
  • fd_write:鏈接到UART外設(在我的具體情況下爲/dev/ttyO4)。

這是當我想通過UART發送一個字節所執行的功能:

int UARTIOHandler::write(uchar8 byte) { 
    auto tp = std::chrono::steady_clock::now(); 
    std::cout << std::endl << "[write] Timestamp: " << std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count(); 
    ::write(fd_debug, &byte, 1); 
    return ::write(this->fd_write, &byte, 1); 
} 

因爲如果我發送的數據被正確接收了UART檢查,我已經連接TXRX我的船上引腳(環回測試)(因爲我希望能夠接收回來,我發送數據),並特別UART端口上運行minicom

minicom -D /dev/ttyO4 -b 19200 -C test.test 

發送一些數據後,我比較了兩個文件(調試文件和minicom生成的輸出文件(它應該包含通過UART收到的數據))。問題是數據不一樣!

這是實際的數據發送(十六進制):

55 33 02 04 06 08 0a 0c d5 55 0b 01 03 05 07 ef 55 3f 07 06 05 04 03 02 01 e3 55 16 01 02 03 04 05 06 07 08 db 55 3f 01 02 03 04 05 06 07 e3 

這是在調試文件(這是相同的,所以這證實了有一些UART問題)接收到的數據:

55 33 02 04 06 08 0a 0c d5 55 0b 01 03 05 07 ef 55 3f 07 06 05 04 03 02 01 e3 55 16 01 02 03 04 05 06 07 08 db 55 3f 01 02 03 04 05 06 07 e3 

這是minicom工具接收到的數據(即設置爲監聽同UART端口,和相同的設置(baudparity等):

55 33 02 04 06 08 0a d5 55 01 03 4d 69 6e 69 63 6f 6d 32 2e 36 2e 31 07 ef 55 3f 07 06 4d 69 6e 69 63 6f 6d 32 2e 36 2e 31 04 03 02 01 e3 55 16 01 02 03 04 4d 69 6e 69 63 6f 6d 32 2e 36 2e 31 06 07 08 db 55 3f 01 02 03 04 4d 69 6e 69 63 6f 6d 32 2e 36 2e 31 06 07 e3 

從某點可以看出,所有數據都被損壞,並且接收到更多的字節。

對於從輸出文件檢查的實際數據我用hexdump這樣的:

hexdump -ve '1/1 "%.2x "' test.test 

可能是什麼問題呢?

+0

C++不是C.它可以幫助你知道你正在編程的編程語言。 – Lundin

+0

@Lundin'unistd.h'和'termios.h'是C POSIX庫組件,這就是爲什麼我標記了'C'語言。 –

+0

您是否檢查過minicom的配置,特別是流量控制(硬件和軟件)? – blatinox

回答

1

這似乎是Minicom響應ENQ字符(0x05)並在會話捕獲中記錄其響應。額外的數據是Minicom2.6.1這不是腐敗。它在您的數據流中每取代0x05。

+1

似乎也跳過了'0c'和'0b'。 –

+0

這可能是真正的問題,我可以在live minicom會話中看到'Minicom2.6.1'字符串。我沒有找到任何方法來禁用這個替換壽。 –

+0

@WeatherVane是的。他們是「垂直標籤」和「換頁」,minicom可能是對他們採取行動而不是傳遞給他們。在古代,流中的^ L(0x12)會在硬拷貝終端上爲您提供新的工作表。 (也就是爲什麼它在'vi'和'curses'之類的東西中用作重畫命令) – janm