Serial-Port

如何在 RS485(半雙工)串列線路的串列寫入期間禁止串列接收

  • October 8, 2017

我有一個應用程序希望通過全雙工串列線路進行 I/O。那是:

char buf[4];
write(fd, "ping", 4);
read(fd, buf, 4);

…期望以遠端設備響應“ping”字元串而傳輸的任何四個字節結束。

但我在半雙工 RS485 線路上執行,因此在串列線路上傳輸的每個字節也會在串列線路上接收(因為它們同一條線路)。因此,上面的程式碼片段總是在遠端設備傳輸任何內容之前將“ping”讀入緩衝區。

顯然主機程式碼並不期待這一點。

我想出的最佳解決方案是始終在寫入後讀取並驗證接收到的字元是否與發送的字元匹配,然後忽略它們。

但是有更好的方法嗎?是否有可靠的 Unix 習慣用法用於在字元傳輸期間禁止接收字元?

(我很欣賞我的問題中有很多微妙之處和曲折的小迷宮。例如,UART 是否有 fifo?接收程序是否在同一個執行緒中執行?等等。如果這很容易,我不會問unix.stackexchange!:)

更新

我實現了一個簡單的常式,我在每個字節之後呼叫它write()read()然後使用它strncmp()來驗證它們是否匹配。它看起來很健壯,但我仍然想知道是否有一種驅動程序級別的方法可以做得更好,或者至少不同。

務實地說,如果您所擁有的似乎有效,並且您不期望設置有任何更改,或者這是一次性的黑客攻擊,那麼請繼續使用您的解決方案。

但是,Linux 有一個適用於適當硬體的rs485 API ,您可以嘗試。某些硬體具有內置的半雙工模式,如果您將串列埠置於適當的狀態,該模式將起作用。例如,ioctl 用於啟用 RS485 模式:

#include <linux/serial.h>
struct serial_rs485 rs485conf = {0};
rs485conf.flags |= SER_RS485_ENABLED;
if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) ...

或在發送時將 RTS 引腳的邏輯電平設置為 1:

rs485conf.flags |= SER_RS485_RTS_ON_SEND;

引用自:https://unix.stackexchange.com/questions/396758