[英]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.