簡體   English   中英

Linux中的串行通信異常?

[英]serial communication anomaly in Linux?

我正在使用select調用通過串行端口RS232與外部子系統(已提供了相同的協議並將其實現為Qt線程)進行通信。 我們沒有用於外部系統的硬件,因此,我們使用.Net 2.0和C#在內部模擬器中進行了開發,以模仿底層子系統硬件的行為。 有5個與我們的應用程序通信的子系統。 子系統的每個接口都實現為Qt線程。 由於這不是實時應用程序,並且在使用模擬器進行通訊時我們沒有實際的硬件,因此所有系統的確會找到24小時左右的時間,此后通訊不斷上升,最終所有通訊都中斷了,但是當我在不關閉我的應用程序的情況下重新啟動模擬器計算機時,一切都變好了。 為什么會這樣?

我的猜測是,由於.Net / C#不是實時框架,而且在模擬器運行24小時后,數據發送速率開始降低,這是串行端口阻塞的原因。 重新啟動會刷新所有內容,從而使所有內容恢復正常。 這只是一個猜測。 如果有人有更好的意見,請分享。 注意,模擬器是由.Net團隊的不同成員制作的。

注意:每個協議具有不同的數據速率,分別為1 Hz,5 Hz,10 Hz。

有一個系統即使重新啟動后重新啟動了模擬器,也不會恢復通訊。 該系統的端口配置為

SetPortConfiguration()
{
    tcgetattr(Fd,&mOldtio); 
       mNewtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD | CRTSCTS;
       mNewtio.c_iflag = 0; //setting the input flag to icrnl causes a blank frame to be displayed after every frame.
       mNewtio.c_oflag = 0;
       mNewtio.c_lflag =ICANON;
       mNewtio.c_cflag &=~PARENB;
       mNewtio.c_cflag &= ~CSTOPB;
        //mNewtio.c_cflag &= ~HUPCL;  //added on 24/3/09
       mNewtio.c_cc[VEOL]=0; //setting VEOL to '\r' or '\n' causes a blank frame to be displayed after every frame.
       mNewtio.c_cc[VKILL] = 0;     /* @ */
       mNewtio.c_cc[VSTART] = 0;     /* Ctrl-q */
       mNewtio.c_cc[VSTOP]  = 0;     /* Ctrl-s */
       mNewtio.c_cc[VMIN]=0;
       mNewtio.c_cc[VTIME]=0;
       tcflush(Fd, TCIFLUSH);
       tcflow(Fd,TCION);
       tcsetattr(Fd,TCSANOW,&mNewtio);
}

還有一個重置端口功能:

ResetPort()
{
    tcflush(Fd, TCIFLUSH); //flush all data received but not read

    tcflow(Fd,TCIOFF); //transmits a STOP character, which stops the terminal device from transmitting data to the system 
    tcsetattr(Fd, TCSANOW, &mOldtio);//set the old terminal settings

    ClosePort(); //close port
    OpenPort(mStrPortNo); //open the port specified by port number and in read mode
    SetPortConfiguration();
}

如果通信中斷,我將調用ResetPort函數,該函數將關閉並重新打開端口。 這解決了在所有情況下的問題,只有一個系統稱為XYZ。 XYZ系統以NMEA格式發送數據,每個數據包作為數據字符串,以回車,LineFeed組合終止。

有什么想法的家伙,可能是什么問題?

“ .Net實時”位是一個紅色鯡魚。 串行端口非常慢,以至於8086可以控制它們。 即使是115200 Baud,任何現代CPU都可能有備用周期。 即使不是,RS232緩沖區的深度通常以毫秒而不是小時為單位進行測量。

串行端口的“阻塞”將物理類比推得太遠了。

由於您實際上沒有告訴我們這是什么,因此很難弄清楚到底是什么導致了您的問題。 “崩潰”是我們無法解決的問題。 字節丟失,寫超時-這是我們可以解決的具體行為。

我已經解決了問題。 如果無法理解我的歉意。 早先我們使用信號處理進行串行接口,並將每個系統連接到專用串行端口,但由於我們的情況下信號處理程序過於復雜,因此該設計從一開始就存在缺陷。 理想情況下,信號處理程序應該只設置一些標志,不應該涉及函數調用,因為可能要處理同步問題,然后它陷入同步夢night,這在我的應用程序中很難調試。 這種設計會導致來自串行端口的數據包丟失。 為了解決這種情況,我們使用了重置端口功能,這是糾正丟包問題的粗略方法。 我刪除了信號處理程序,並對單個系統使用了select調用。 但是沒有丟棄復位端口,這是早期設計的一部分。 在調試時,我發現resetport是一個虛假函數,並將其刪除。 瞧! 現在一切正常。 根據記錄,我對在linux paltform上使用串行通信以使用select系統調用的任何人的建議。 您無需擔心處理串行通信的細節,而只需專注於處理傳入的數據包。

我希望該解決方案能夠為所有在linux / unix平台上進行串行通信的人們提供幫助。 關於該主題的文獻很少,並且在網上進行的所有搜索都將帶您找到Mike和Sweet撰寫的一些文檔,盡管它們對實際應用沒有多大幫助。 我感謝stackoverlow所有成員提供的幫助,這些幫助給了我不可思議的觀點來解決當前的問題。 謝謝大家,加油!!!

暫無
暫無

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

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