RS485 序列通訊¶
1. 簡介¶
EIA-485,也稱為 TIA/EIA-485 或 RS-485,是一種標準,定義了用於平衡數字多點系統中驅動器和接收器的電氣特性。 該標準廣泛用於工業自動化中的通訊,因為它可以在長距離和電氣噪聲環境中有效使用。
3. 核心中已有的資料結構¶
Linux 核心提供了
struct serial_rs485來處理 RS485 通訊。 此資料結構用於設定和配置平臺數據和 ioctl 中的 RS485 引數。裝置樹還可以提供 RS485 啟動時間引數 [1]。 當驅動程式呼叫 uart_get_rs485_mode() 時,序列核心會從裝置樹提供的值填充
struct serial_rs485。任何能夠同時作為 RS232 和 RS485 工作的裝置的驅動程式都應實現
rs485_config回撥並在struct uart_port中提供rs485_supported。 序列核心呼叫rs485_config來執行裝置特定部分,以響應 TIOCSRS485 ioctl(見下文)。rs485_config回撥接收指向已清除的struct serial_rs485的指標。 在使用rs485_supported呼叫rs485_config之前,會清除使用者空間提供的struct serial_rs485,rs485_supported指示驅動程式對struct uart_port支援哪些 RS485 功能。 TIOCGRS485 ioctl 可用於讀取與當前配置匹配的struct serial_rs485。
-
struct serial_rs485¶
用於控制 RS485 設定的序列介面。
定義:
struct serial_rs485 {
__u32 flags;
#define SER_RS485_ENABLED _BITUL(0);
#define SER_RS485_RTS_ON_SEND _BITUL(1);
#define SER_RS485_RTS_AFTER_SEND _BITUL(2);
#define SER_RS485_RX_DURING_TX _BITUL(4);
#define SER_RS485_TERMINATE_BUS _BITUL(5);
#define SER_RS485_ADDRB _BITUL(6);
#define SER_RS485_ADDR_RECV _BITUL(7);
#define SER_RS485_ADDR_DEST _BITUL(8);
#define SER_RS485_MODE_RS422 _BITUL(9);
__u32 delay_rts_before_send;
__u32 delay_rts_after_send;
union {
__u32 padding[5];
struct {
__u8 addr_recv;
__u8 addr_dest;
__u8 padding0[2];
__u32 padding1[4];
};
};
};
成員
flagsRS485 功能標誌。
delay_rts_before_send傳送前延遲(毫秒)。
delay_rts_after_send傳送後延遲(毫秒)。
{unnamed_union}anonymous
padding已棄用,請改用 padding0 和 padding1。 請勿與 addr_recv 和 addr_dest 一起使用(由於重疊)。
{unnamed_struct}anonymous
addr_recvRS485 定址模式的接收過濾器(僅當設定了
SER_RS485_ADDR_RECV時使用)。addr_destRS485 定址模式的目標地址(僅當設定了
SER_RS485_ADDR_DEST時使用)。padding0填充(設定為零)。
padding1填充(設定為零)。
描述
用於控制具有合適支援的晶片上的 RS485 設定的序列介面。 如果您的平臺支援,請使用 TIOCSRS485 進行設定,並使用 TIOCGRS485 進行獲取。 設定函式返回新狀態,所有不支援的位都會適當恢復。
標誌位是
SER_RS485_ENABLED- 啟用 RS485。SER_RS485_RTS_ON_SEND- 傳送時 RTS 引腳的邏輯電平。SER_RS485_RTS_AFTER_SEND- 傳送後 RTS 引腳的邏輯電平。SER_RS485_RX_DURING_TX- 全雙工 RS485 線路。SER_RS485_TERMINATE_BUS- 啟用匯流排端接(如果支援)。SER_RS485_ADDRB- 啟用 RS485 定址模式。SER_RS485_ADDR_RECV- 啟用接收地址過濾器(啟用 addr_recv)。 需要SER_RS485_ADDRB。SER_RS485_ADDR_DEST- 目標地址(啟用 addr_dest)。 需要SER_RS485_ADDRB。SER_RS485_MODE_RS422- 啟用 RS422。 需要SER_RS485_ENABLED。
4. 從使用者級別使用¶
從使用者級別,可以使用之前的 ioctl 獲取/設定 RS485 配置。 例如,要設定 RS485,您可以使用以下程式碼
#include <linux/serial.h> /* Include definition for RS485 ioctls: TIOCGRS485 and TIOCSRS485 */ #include <sys/ioctl.h> /* Open your specific device (e.g., /dev/mydevice): */ int fd = open ("/dev/mydevice", O_RDWR); if (fd < 0) { /* Error handling. See errno. */ } struct serial_rs485 rs485conf; /* Enable RS485 mode: */ rs485conf.flags |= SER_RS485_ENABLED; /* Set logical level for RTS pin equal to 1 when sending: */ rs485conf.flags |= SER_RS485_RTS_ON_SEND; /* or, set logical level for RTS pin equal to 0 when sending: */ rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND); /* Set logical level for RTS pin equal to 1 after sending: */ rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; /* or, set logical level for RTS pin equal to 0 after sending: */ rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); /* Set rts delay before send, if needed: */ rs485conf.delay_rts_before_send = ...; /* Set rts delay after send, if needed: */ rs485conf.delay_rts_after_send = ...; /* Set this flag if you want to receive data even while sending data */ rs485conf.flags |= SER_RS485_RX_DURING_TX; if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) { /* Error handling. See errno. */ } /* Use read() and write() syscalls here... */ /* Close the device when finished: */ if (close (fd) < 0) { /* Error handling. See errno. */ }
5. 多點定址¶
Linux 核心為多點 RS-485 序列通訊線路提供定址模式。 定址模式透過
struct serial_rs485中的SER_RS485_ADDRB標誌啟用。struct serial_rs485具有兩個額外的標誌和欄位,用於啟用接收和目標地址。
- 地址模式標誌
SER_RS485_ADDRB: 啟用定址模式(也在 termios 中設定 ADDRB)。
SER_RS485_ADDR_RECV: 啟用接收(過濾)地址。
SER_RS485_ADDR_DEST: 設定目標地址。- 地址欄位(使用相應的
SER_RS485_ADDR_*標誌啟用)
addr_recv: 接收地址。
addr_dest: 目標地址。設定接收地址後,通訊只能與特定裝置進行,並且其他對等方將被過濾掉。 過濾由接收方強制執行。 如果未設定
SER_RS485_ADDR_RECV,則將清除接收地址。注意:並非所有支援 RS485 的裝置都支援多點定址。