0001 ===========================
0002 RS485 Serial Communications
0003 ===========================
0004
0005 1. Introduction
0006 ===============
0007
0008 EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the
0009 electrical characteristics of drivers and receivers for use in balanced
0010 digital multipoint systems.
0011 This standard is widely used for communications in industrial automation
0012 because it can be used effectively over long distances and in electrically
0013 noisy environments.
0014
0015 2. Hardware-related Considerations
0016 ==================================
0017
0018 Some CPUs/UARTs (e.g., Atmel AT91 or 16C950 UART) contain a built-in
0019 half-duplex mode capable of automatically controlling line direction by
0020 toggling RTS or DTR signals. That can be used to control external
0021 half-duplex hardware like an RS485 transceiver or any RS232-connected
0022 half-duplex devices like some modems.
0023
0024 For these microcontrollers, the Linux driver should be made capable of
0025 working in both modes, and proper ioctls (see later) should be made
0026 available at user-level to allow switching from one mode to the other, and
0027 vice versa.
0028
0029 3. Data Structures Already Available in the Kernel
0030 ==================================================
0031
0032 The Linux kernel provides the serial_rs485 structure (see [1]) to handle
0033 RS485 communications. This data structure is used to set and configure RS485
0034 parameters in the platform data and in ioctls.
0035
0036 The device tree can also provide RS485 boot time parameters (see [2]
0037 for bindings). The driver is in charge of filling this data structure from
0038 the values given by the device tree.
0039
0040 Any driver for devices capable of working both as RS232 and RS485 should
0041 implement the rs485_config callback and provide rs485_supported in the
0042 uart_port structure. The serial core calls rs485_config to do the device
0043 specific part in response to TIOCSRS485 ioctl (see below). The rs485_config
0044 callback receives a pointer to a sanitizated serial_rs485 structure. The
0045 serial_rs485 userspace provides is sanitized before calling rs485_config
0046 using rs485_supported that indicates what RS485 features the driver supports
0047 for the uart_port. TIOCGRS485 ioctl can be used to read back the
0048 serial_rs485 structure matching to the current configuration.
0049
0050 4. Usage from user-level
0051 ========================
0052
0053 From user-level, RS485 configuration can be get/set using the previous
0054 ioctls. For instance, to set RS485 you can use the following code::
0055
0056 #include <linux/serial.h>
0057
0058 /* Include definition for RS485 ioctls: TIOCGRS485 and TIOCSRS485 */
0059 #include <sys/ioctl.h>
0060
0061 /* Open your specific device (e.g., /dev/mydevice): */
0062 int fd = open ("/dev/mydevice", O_RDWR);
0063 if (fd < 0) {
0064 /* Error handling. See errno. */
0065 }
0066
0067 struct serial_rs485 rs485conf;
0068
0069 /* Enable RS485 mode: */
0070 rs485conf.flags |= SER_RS485_ENABLED;
0071
0072 /* Set logical level for RTS pin equal to 1 when sending: */
0073 rs485conf.flags |= SER_RS485_RTS_ON_SEND;
0074 /* or, set logical level for RTS pin equal to 0 when sending: */
0075 rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
0076
0077 /* Set logical level for RTS pin equal to 1 after sending: */
0078 rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
0079 /* or, set logical level for RTS pin equal to 0 after sending: */
0080 rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
0081
0082 /* Set rts delay before send, if needed: */
0083 rs485conf.delay_rts_before_send = ...;
0084
0085 /* Set rts delay after send, if needed: */
0086 rs485conf.delay_rts_after_send = ...;
0087
0088 /* Set this flag if you want to receive data even while sending data */
0089 rs485conf.flags |= SER_RS485_RX_DURING_TX;
0090
0091 if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
0092 /* Error handling. See errno. */
0093 }
0094
0095 /* Use read() and write() syscalls here... */
0096
0097 /* Close the device when finished: */
0098 if (close (fd) < 0) {
0099 /* Error handling. See errno. */
0100 }
0101
0102 5. Multipoint Addressing
0103 ========================
0104
0105 The Linux kernel provides addressing mode for multipoint RS-485 serial
0106 communications line. The addressing mode is enabled with SER_RS485_ADDRB
0107 flag in serial_rs485. Struct serial_rs485 has two additional flags and
0108 fields for enabling receive and destination addresses.
0109
0110 Address mode flags:
0111 - SER_RS485_ADDRB: Enabled addressing mode (sets also ADDRB in termios).
0112 - SER_RS485_ADDR_RECV: Receive (filter) address enabled.
0113 - SER_RS485_ADDR_DEST: Set destination address.
0114
0115 Address fields (enabled with corresponding SER_RS485_ADDR_* flag):
0116 - addr_recv: Receive address.
0117 - addr_dest: Destination address.
0118
0119 Once a receive address is set, the communication can occur only with the
0120 particular device and other peers are filtered out. It is left up to the
0121 receiver side to enforce the filtering. Receive address will be cleared
0122 if SER_RS485_ADDR_RECV is not set.
0123
0124 Note: not all devices supporting RS485 support multipoint addressing.
0125
0126 6. References
0127 =============
0128
0129 [1] include/uapi/linux/serial.h
0130
0131 [2] Documentation/devicetree/bindings/serial/rs485.txt