Documentation/driver-api/serial/serial-rs485.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

RS485 Serial Communications

RS-485 half-duplex direction, serial_rs485 sanitization·ioctl, RTS timing과 multipoint addressing을 다루는 전문 번역입니다.

Source pathDocumentation/driver-api/serial/serial-rs485.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

serial-rs485.rst:1-135

RS-485 driver는 RTS·DTR로 half-duplex 방향을 제어하고 `rs485_supported` capability로 userspace 설정을 sanitize합니다. RTS timing, 송신 중 수신, multipoint receive·destination address와 receiver-side filtering까지 설명합니다.

문서 구성
원문 줄내용
1-28표준과 half-duplex hardware
29-54Kernel structure, device tree와 callback
55-106Userspace RTS·delay configuration
107-131Multipoint addressing과 filtering
132-135Device-tree binding reference

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ===========================
2 RS485 Serial Communications
3 ===========================
4
5 1. Introduction
6 ===============
7
8 EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the
9 electrical characteristics of drivers and receivers for use in balanced
10 digital multipoint systems.
11 This standard is widely used for communications in industrial automation
12 because it can be used effectively over long distances and in electrically
13 noisy environments.
14
15 2. Hardware-related Considerations
16 ==================================
17
18 Some CPUs/UARTs (e.g., Atmel AT91 or 16C950 UART) contain a built-in
19 half-duplex mode capable of automatically controlling line direction by
20 toggling RTS or DTR signals. That can be used to control external
21 half-duplex hardware like an RS485 transceiver or any RS232-connected
22 half-duplex devices like some modems.
23
24 For these microcontrollers, the Linux driver should be made capable of
25 working in both modes, and proper ioctls (see later) should be made
26 available at user-level to allow switching from one mode to the other, and
27 vice versa.
28
29 3. Data Structures Already Available in the Kernel
30 ==================================================
31
32 The Linux kernel provides the struct serial_rs485 to handle RS485
33 communications. This data structure is used to set and configure RS485
34 parameters in the platform data and in ioctls.
35
36 The device tree can also provide RS485 boot time parameters
37 [#DT-bindings]_. The serial core fills the struct serial_rs485 from the
38 values given by the device tree when the driver calls
39 uart_get_rs485_mode().
40
41 Any driver for devices capable of working both as RS232 and RS485 should
42 implement the ``rs485_config`` callback and provide ``rs485_supported``
43 in the ``struct uart_port``. The serial core calls ``rs485_config`` to do
44 the device specific part in response to TIOCSRS485 ioctl (see below). The
45 ``rs485_config`` callback receives a pointer to a sanitizated struct
46 serial_rs485. The struct serial_rs485 userspace provides is sanitized
47 before calling ``rs485_config`` using ``rs485_supported`` that indicates
48 what RS485 features the driver supports for the ``struct uart_port``.
49 TIOCGRS485 ioctl can be used to read back the struct serial_rs485
50 matching to the current configuration.
51
52 .. kernel-doc:: include/uapi/linux/serial.h
53 :identifiers: serial_rs485 uart_get_rs485_mode
54
55 4. Usage from user-level
56 ========================
57
58 From user-level, RS485 configuration can be get/set using the previous
59 ioctls. For instance, to set RS485 you can use the following code::
60
61 #include <linux/serial.h>
62
63 /* Include definition for RS485 ioctls: TIOCGRS485 and TIOCSRS485 */
64 #include <sys/ioctl.h>
65
66 /* Open your specific device (e.g., /dev/mydevice): */
67 int fd = open ("/dev/mydevice", O_RDWR);
68 if (fd < 0) {
69 /* Error handling. See errno. */
70 }
71
72 struct serial_rs485 rs485conf;
73
74 /* Enable RS485 mode: */
75 rs485conf.flags |= SER_RS485_ENABLED;
76
77 /* Set logical level for RTS pin equal to 1 when sending: */
78 rs485conf.flags |= SER_RS485_RTS_ON_SEND;
79 /* or, set logical level for RTS pin equal to 0 when sending: */
80 rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
81
82 /* Set logical level for RTS pin equal to 1 after sending: */
83 rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
84 /* or, set logical level for RTS pin equal to 0 after sending: */
85 rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
86
87 /* Set rts delay before send, if needed: */
88 rs485conf.delay_rts_before_send = ...;
89
90 /* Set rts delay after send, if needed: */
91 rs485conf.delay_rts_after_send = ...;
92
93 /* Set this flag if you want to receive data even while sending data */
94 rs485conf.flags |= SER_RS485_RX_DURING_TX;
95
96 if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
97 /* Error handling. See errno. */
98 }
99
100 /* Use read() and write() syscalls here... */
101
102 /* Close the device when finished: */
103 if (close (fd) < 0) {
104 /* Error handling. See errno. */
105 }
106
107 5. Multipoint Addressing
108 ========================
109
110 The Linux kernel provides addressing mode for multipoint RS-485 serial
111 communications line. The addressing mode is enabled with
112 ``SER_RS485_ADDRB`` flag in struct serial_rs485. The struct serial_rs485
113 has two additional flags and fields for enabling receive and destination
114 addresses.
115
116 Address mode flags:
117 - ``SER_RS485_ADDRB``: Enabled addressing mode (sets also ADDRB in termios).
118 - ``SER_RS485_ADDR_RECV``: Receive (filter) address enabled.
119 - ``SER_RS485_ADDR_DEST``: Set destination address.
120
121 Address fields (enabled with corresponding ``SER_RS485_ADDR_*`` flag):
122 - ``addr_recv``: Receive address.
123 - ``addr_dest``: Destination address.
124
125 Once a receive address is set, the communication can occur only with the
126 particular device and other peers are filtered out. It is left up to the
127 receiver side to enforce the filtering. Receive address will be cleared
128 if ``SER_RS485_ADDR_RECV`` is not set.
129
130 Note: not all devices supporting RS485 support multipoint addressing.
131
132 6. References
133 =============
134
135 .. [#DT-bindings] Documentation/devicetree/bindings/serial/rs485.txt
136

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

RS-485 serial communication

1-4

이 문서는 RS-485 serial communication의 kernel·device-tree·userspace configuration interface를 설명합니다.

문서 식별 정보
항목
문서RS485 Serial Communications
표준EIA-485 / TIA/EIA-485 / RS-485

===========================
RS485 Serial Communications
===========================

Balanced multipoint 표준

5-14

EIA-485는 TIA/EIA-485 또는 RS-485라고도 하며 balanced digital multipoint system에 사용하는 driver와 receiver의 electrical characteristic을 정의합니다.

긴 거리와 electrical noise가 많은 환경에서도 효과적으로 사용할 수 있어 industrial automation 통신에 널리 쓰입니다.

RS-485 적용 특성
Balanced drivers and receiversMultipoint busLong distanceNoisy environmentIndustrial automation

Balanced signaling과 multipoint topology가 긴 거리·고잡음 산업 환경을 지원합니다.

1. Introduction
===============

   EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the
   electrical characteristics of drivers and receivers for use in balanced
   digital multipoint systems.
   This standard is widely used for communications in industrial automation
   because it can be used effectively over long distances and in electrically
   noisy environments.

Half-duplex direction control

15-28

Atmel AT91 또는 16C950 UART 같은 일부 CPU/UART에는 RTS나 DTR signal을 toggle해 line direction을 자동 제어하는 built-in half-duplex mode가 있습니다.

이 mode는 RS-485 transceiver 같은 external half-duplex hardware나 일부 modem처럼 RS-232로 연결된 half-duplex device를 제어할 수 있습니다.

이런 microcontroller의 Linux driver는 normal mode와 half-duplex mode를 모두 지원하고 userspace가 ioctl로 두 mode를 양방향 전환할 수 있게 해야 합니다.

Automatic half-duplex direction
UART half-duplex modeRTS / DTR toggleRS-485 transceiverMultipoint line
Userspace ioctlDriver mode switchNormal / RS-485

UART가 RTS·DTR을 toggle해 송수신 방향을 external transceiver에 전달합니다.

2. Hardware-related Considerations
==================================

   Some CPUs/UARTs (e.g., Atmel AT91 or 16C950 UART) contain a built-in
   half-duplex mode capable of automatically controlling line direction by
   toggling RTS or DTR signals. That can be used to control external
   half-duplex hardware like an RS485 transceiver or any RS232-connected
   half-duplex devices like some modems.

   For these microcontrollers, the Linux driver should be made capable of
   working in both modes, and proper ioctls (see later) should be made
   available at user-level to allow switching from one mode to the other, and
   vice versa.

serial_rs485 sanitization과 callback

29-54

Kernel은 platform data와 ioctl에서 RS-485 parameter를 설정하는 `struct serial_rs485`를 제공합니다. Device tree도 boot-time parameter를 제공할 수 있고, driver가 `uart_get_rs485_mode()`를 호출하면 serial core가 그 값으로 structure를 채웁니다.

RS-232와 RS-485를 모두 지원하는 driver는 `struct uart_port`에 `rs485_config` callback과 `rs485_supported` capability를 제공해야 합니다. Serial core는 `TIOCSRS485`에 응답해 device-specific 설정을 수행할 때 callback을 호출합니다.

Userspace가 제공한 `struct serial_rs485`는 callback 전에 `rs485_supported`가 나타내는 지원 feature로 sanitize됩니다. `TIOCGRS485`는 현재 configuration에 맞는 structure를 읽는 데 사용합니다.

Kernel-doc은 `include/uapi/linux/serial.h`의 `serial_rs485`와 `uart_get_rs485_mode` identifier를 가져옵니다.

RS-485 configuration sanitization
Device tree`uart_get_rs485_mode()``struct serial_rs485`
Userspace `TIOCSRS485``struct serial_rs485``rs485_supported` sanitization`rs485_config`Hardware
`TIOCGRS485`Read current configuration

Device tree 또는 userspace 설정을 driver capability로 제한한 뒤 callback에 전달합니다.

3. Data Structures Already Available in the Kernel
==================================================

   The Linux kernel provides the struct serial_rs485 to handle RS485
   communications. This data structure is used to set and configure RS485
   parameters in the platform data and in ioctls.

   The device tree can also provide RS485 boot time parameters
   [#DT-bindings]_. The serial core fills the struct serial_rs485 from the
   values given by the device tree when the driver calls
   uart_get_rs485_mode().

   Any driver for devices capable of working both as RS232 and RS485 should
   implement the ``rs485_config`` callback and provide ``rs485_supported``
   in the ``struct uart_port``. The serial core calls ``rs485_config`` to do
   the device specific part in response to TIOCSRS485 ioctl (see below). The
   ``rs485_config`` callback receives a pointer to a sanitizated struct
   serial_rs485. The struct serial_rs485 userspace provides is sanitized
   before calling ``rs485_config`` using ``rs485_supported`` that indicates
   what RS485 features the driver supports for the ``struct uart_port``.
   TIOCGRS485 ioctl can be used to read back the struct serial_rs485
   matching to the current configuration.

.. kernel-doc:: include/uapi/linux/serial.h
   :identifiers: serial_rs485 uart_get_rs485_mode

Userspace RS-485 설정 예제

55-106

Userspace 예제는 target device를 열고 `struct serial_rs485`에 RS-485 enable, 송신 중·송신 후 RTS level, 송신 전·후 delay와 송신 중 수신 허용 여부를 설정합니다.

`SER_RS485_ENABLED`가 mode를 켜고 `SER_RS485_RTS_ON_SEND`와 `SER_RS485_RTS_AFTER_SEND`는 각 단계의 RTS logical level을 정합니다. `delay_rts_before_send`·`delay_rts_after_send`는 direction 전환 timing을, `SER_RS485_RX_DURING_TX`는 송신 중 수신을 허용합니다.

완성한 configuration은 `TIOCSRS485` ioctl로 적용하고 이후 `read()`·`write()`로 통신한 뒤 device를 닫습니다.

`serial_rs485` 예제 설정
Field/flag역할
`SER_RS485_ENABLED`RS-485 mode enable
`SER_RS485_RTS_ON_SEND`송신 중 RTS level
`SER_RS485_RTS_AFTER_SEND`송신 후 RTS level
`delay_rts_before_send`송신 전 delay
`delay_rts_after_send`송신 후 delay
`SER_RS485_RX_DURING_TX`송신 중 수신 허용
`TIOCSRS485`Configuration 적용

4. Usage from user-level
========================

   From user-level, RS485 configuration can be get/set using the previous
   ioctls. For instance, to set RS485 you can use the following code::

        #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. */
        }

Multipoint addressing과 filtering

107-131

Kernel은 multipoint RS-485 line을 위한 addressing mode를 제공합니다. `struct serial_rs485`의 `SER_RS485_ADDRB`로 mode를 켜며 receive address와 destination address를 위한 flag와 field가 추가로 있습니다.

`SER_RS485_ADDR_RECV`는 receive filtering address를, `SER_RS485_ADDR_DEST`는 destination address를 enable합니다. 대응 field는 `addr_recv`와 `addr_dest`입니다.

Receive address를 설정하면 지정 device와만 통신하고 다른 peer는 filtering됩니다. Filtering 시행은 receiver 측 책임이며 `SER_RS485_ADDR_RECV`가 해제되면 receive address도 지워집니다.

RS-485를 지원하는 모든 device가 multipoint addressing까지 지원하는 것은 아닙니다.

RS-485 address mode
Flag/field의미
`SER_RS485_ADDRB`Addressing mode와 termios ADDRB enable
`SER_RS485_ADDR_RECV`Receive filter address enable
`SER_RS485_ADDR_DEST`Destination address enable
`addr_recv`Receive address
`addr_dest`Destination address

Receive-side hardware 또는 driver가 다른 peer를 실제로 filtering해야 합니다.

5. Multipoint Addressing
========================

   The Linux kernel provides addressing mode for multipoint RS-485 serial
   communications line. The addressing mode is enabled with
   ``SER_RS485_ADDRB`` flag in struct serial_rs485. The struct serial_rs485
   has two additional flags and fields for enabling receive and destination
   addresses.

   Address mode flags:
        - ``SER_RS485_ADDRB``: Enabled addressing mode (sets also ADDRB in termios).
        - ``SER_RS485_ADDR_RECV``: Receive (filter) address enabled.
        - ``SER_RS485_ADDR_DEST``: Set destination address.

   Address fields (enabled with corresponding ``SER_RS485_ADDR_*`` flag):
        - ``addr_recv``: Receive address.
        - ``addr_dest``: Destination address.

   Once a receive address is set, the communication can occur only with the
   particular device and other peers are filtered out. It is left up to the
   receiver side to enforce the filtering. Receive address will be cleared
   if ``SER_RS485_ADDR_RECV`` is not set.

   Note: not all devices supporting RS485 support multipoint addressing.

RS-485 device-tree binding

132-135

RS-485 boot-time parameter의 device-tree binding reference는 `Documentation/devicetree/bindings/serial/rs485.txt`입니다.

Reference
LabelSource path
`DT-bindings``Documentation/devicetree/bindings/serial/rs485.txt`

6. References
=============

.. [#DT-bindings]        Documentation/devicetree/bindings/serial/rs485.txt