我正在尝试在程序中设置半双工通信。我的RS485收发器使用RTS标志(TIOCM_RTS)在发送和接收之间来回切换。为了发送/接收数据,我需要手动更改RTS标志:
将“ RTS”设置为“高”。
发送数据。
将RTS设置为低。
int setRTS(int level) { int status; ioctl(ser_port, TIOCMGET, &status); if(level) { status |= TIOCM_RTS; } else { status &= ~TIOCM_RTS; } ioctl(ser_port, TIOCMSET, &status); return 1;
}
我的问题是:Linux内核不应该能够自动切换RTS吗?以及如何确保在调用setRTS(0)之前已发送数据?
linux内核不应该能够自动切换RTS吗?
是的,从Linux 3.0开始就有用于此的内核框架。 在 include / uapi / asm-generic / ioctls.h中 有两个ioctl :
#define TIOCGRS485 0x542E #define TIOCSRS485 0x542F
在RS-485模式下检索和配置tty串行端口驱动程序。 这些ioctl使用struct serial_rs485:
struct serial_rs485
/* * Serial interface for controlling RS485 settings on chips with suitable * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your * platform. The set function returns the new state, with any unsupported bits * reverted appropriately. */ struct serial_rs485 { __u32 flags; /* RS485 feature flags */ #define SER_RS485_ENABLED (1 << 0) /* If enabled */ #define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for RTS pin when sending */ #define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for RTS pin after sent*/ #define SER_RS485_RX_DURING_TX (1 << 4) __u32 delay_rts_before_send; /* Delay before send (milliseconds) */ __u32 delay_rts_after_send; /* Delay after send (milliseconds) */ __u32 padding[5]; /* Memory is cheap, new structs are a royal PITA .. */ };
我已经在Atmel和Etrax SoC上使用了此RS-485功能,但是在Linux UART / USART驱动程序中,这些ioctl的实现非常稀疏。 如果您的驱动程序没有,请考虑自己实施。您可以使用 drivers / tty / serial / atmel_serial.c中的实现 作为指南。另请阅读用于RS485的Linux内核文档。