2013-02-10 78 views
4

我希望能夠檢測到Linux中串行端口的BREAK條件。這是如何完成的?Linux串行端口接收/讀取BREAK條件

我想要檢測何時停止BREAK條件開始

我希望,如果我這樣做:

int serial_status; 
ioctl(serial_fd, TIOCMGET, &serial_status); 

則會有呈現出BREAK位值條件,但它似乎沒有這樣的事情。

我發現tcsendbreak()termios.h發送休息。我還發現了描述如何發送休息的tty_ioctl man page。但是如何獲得休息?

注意:BRKINT已被建議(它產生中斷髮生時的信號SIGINT)。但是,讓SIGINT是不是這樣一個有用的API,有幾個原因:

  • 我不能告訴它來自哪個串口從,在多串口方案。
  • 在終端運行程序時,我也可以從用戶按Ctrl-C獲得SIGINT
  • 如果我將我的程序作爲守護程序運行,那麼條件「如果終端是前臺進程組的控制終端」將不是真的,是嗎?
  • 不可能知道BREAK條件持續多久,何時停止。
+0

看看你連接到的'termios'手冊中的'BRKINT'。 – 2013-02-10 22:44:08

+1

@AntonKovalenko:我爲我的問題添加了一個註釋,說明爲什麼我不認爲'BRKINT'(生成'SIGINT')是有用的。 – 2013-02-10 22:52:13

+1

查看USART/UART驅動程序的源代碼,標誌爲'TTY_BREAK',當異常接收條件(例如奇偶校驗錯誤,成幀錯誤,溢出或中斷)發生時,標誌通常填充到接收緩衝區中。然而,*行規則*(userland獲取Rx數據之前的下一個處理階段)通常會過濾掉Rx數據中的標誌。我隱約想起一個* line的*版本,它插入了20個NUL作爲休息條件。或者可能是3個字節的'0xff'和'0x00'和'0x00' - http://lxr.free-electrons.com/source/drivers/char/n_tty.c?v=2.6.36#L1002 – sawdust 2013-02-11 00:07:14

回答

1

最佳答案我已經能夠到目前爲止發現是從IGNBRKBRKINT常數在termios結構tcsendbreak() man page描述爲c_iflag。它說:

當既不IGNBRK也不BRKINT被設置時,一個BREAK讀取作爲一個空字節('\0')中,當PARMRK設置除,在這種情況下讀出作爲序列\377 \0 \0

(即0xFF 0x00 0x00

所以我想我應該設置PARMRK,並準備做讀取的字節很少的處理。這提供了有關奇偶校驗/幀錯誤的明確信息(儘管0xFF 0x00 0x00代表BREAK或其他一些奇偶校驗/幀錯誤仍然不完全清楚)。

但是請注意,我發現this patch for PARMRK,這似乎意味着舊版內核中存在危險,即在使用PARMRK時可能會丟棄串行字節。

只要BREAK條件持續,或者只在BREAK條件開始時發送一次,這些字節是否連續發送也不清楚。所以目前尚不清楚BREAK條件的端是否可以通過這種方法檢測到。

+1

這是有點晚了,但萬一有人想知道同樣的事情......接收硬件也不明確是否中斷或幀錯誤。休息的電氣語義非常簡單:線路長時間保持低電平。 (需要多長時間?IIRC足夠長的時間,以給定的波特率支持2+正常字節傳輸,可能會被誤解)。還沒有好的方法可以知道中斷何時開始,因爲它只是低線條件。這只是一個休息時間,如果它足夠長時間才能晉級爲休息而不是低下。 – SirNickity 2016-12-09 23:09:37