← Documents Documentation/userspace-api/media/rc/lirc-dev-intro.rst GitHub 원문 ↗

Linux 6.18.37 · Userspace API / Media / Remote Controller

LIRC 장치 인터페이스 소개

LIRC 문자 장치의 scan code와 raw IR mode, BPF decoder 연결 방법을 설명합니다.

Source pathDocumentation/userspace-api/media/rc/lirc-dev-intro.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약·해설

lirc-dev-intro.rst:1-176

LIRC는 `/dev/lircX`에서 decode된 scan code 또는 raw pulse/space를 교환합니다. 세 mode의 데이터 형식과 repeat·toggle 의미, BPF decoder의 적재·연결·결과 제출 절차를 구분해야 합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
2
3 .. _lirc_dev_intro:
4
5 ************
6 Introduction
7 ************
8
9 LIRC stands for Linux Infrared Remote Control. The LIRC device interface is
10 a bi-directional interface for transporting raw IR and decoded scancodes
11 data between userspace and kernelspace. Fundamentally, it is just a chardev
12 (/dev/lircX, for X = 0, 1, 2, ...), with a number of standard struct
13 file_operations defined on it. With respect to transporting raw IR and
14 decoded scancodes to and fro, the essential fops are read, write and ioctl.
15
16 It is also possible to attach a BPF program to a LIRC device for decoding
17 raw IR into scancodes.
18
19 Example dmesg output upon a driver registering w/LIRC:
20
21 .. code-block:: none
22
23 $ dmesg |grep lirc_dev
24 rc rc0: lirc_dev: driver mceusb registered at minor = 0, raw IR receiver, raw IR transmitter
25
26 What you should see for a chardev:
27
28 .. code-block:: none
29
30 $ ls -l /dev/lirc*
31 crw-rw---- 1 root root 248, 0 Jul 2 22:20 /dev/lirc0
32
33 Note that the package `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_
34 contains tools for working with LIRC devices:
35
36 - ir-ctl: can receive raw IR and transmit IR, as well as query LIRC
37 device features.
38
39 - ir-keytable: can load keymaps; allows you to set IR kernel protocols; load
40 BPF IR decoders and test IR decoding. Some BPF IR decoders are also
41 provided.
42
43 .. _lirc_modes:
44
45 **********
46 LIRC modes
47 **********
48
49 LIRC supports some modes of receiving and sending IR codes, as shown
50 on the following table.
51
52 .. _lirc-mode-scancode:
53 .. _lirc-scancode-flag-toggle:
54 .. _lirc-scancode-flag-repeat:
55
56 ``LIRC_MODE_SCANCODE``
57
58 This mode is for both sending and receiving IR.
59
60 For transmitting (aka sending), create a struct lirc_scancode with
61 the desired scancode set in the ``scancode`` member, :c:type:`rc_proto`
62 set to the :ref:`IR protocol <Remote_controllers_Protocols>`, and all other
63 members set to 0. Write this struct to the lirc device.
64
65 For receiving, you read struct lirc_scancode from the LIRC device.
66 The ``scancode`` field is set to the received scancode and the
67 :ref:`IR protocol <Remote_controllers_Protocols>` is set in
68 :c:type:`rc_proto`. If the scancode maps to a valid key code, this is set
69 in the ``keycode`` field, else it is set to ``KEY_RESERVED``.
70
71 The ``flags`` can have ``LIRC_SCANCODE_FLAG_TOGGLE`` set if the toggle
72 bit is set in protocols that support it (e.g. rc-5 and rc-6), or
73 ``LIRC_SCANCODE_FLAG_REPEAT`` for when a repeat is received for protocols
74 that support it (e.g. nec).
75
76 In the Sanyo and NEC protocol, if you hold a button on remote, rather than
77 repeating the entire scancode, the remote sends a shorter message with
78 no scancode, which just means button is held, a "repeat". When this is
79 received, the ``LIRC_SCANCODE_FLAG_REPEAT`` is set and the scancode and
80 keycode is repeated.
81
82 With nec, there is no way to distinguish "button hold" from "repeatedly
83 pressing the same button". The rc-5 and rc-6 protocols have a toggle bit.
84 When a button is released and pressed again, the toggle bit is inverted.
85 If the toggle bit is set, the ``LIRC_SCANCODE_FLAG_TOGGLE`` is set.
86
87 The ``timestamp`` field is filled with the time nanoseconds
88 (in ``CLOCK_MONOTONIC``) when the scancode was decoded.
89
90 .. _lirc-mode-mode2:
91
92 ``LIRC_MODE_MODE2``
93
94 The driver returns a sequence of pulse and space codes to userspace,
95 as a series of u32 values.
96
97 This mode is used only for IR receive.
98
99 The upper 8 bits determine the packet type, and the lower 24 bits
100 the payload. Use ``LIRC_VALUE()`` macro to get the payload, and
101 the macro ``LIRC_MODE2()`` will give you the type, which
102 is one of:
103
104 ``LIRC_MODE2_PULSE``
105
106 Signifies the presence of IR in microseconds, also known as *flash*.
107
108 ``LIRC_MODE2_SPACE``
109
110 Signifies absence of IR in microseconds, also known as *gap*.
111
112 ``LIRC_MODE2_FREQUENCY``
113
114 If measurement of the carrier frequency was enabled with
115 :ref:`lirc_set_measure_carrier_mode` then this packet gives you
116 the carrier frequency in Hertz.
117
118 ``LIRC_MODE2_TIMEOUT``
119
120 When the timeout set with :ref:`lirc_set_rec_timeout` expires due
121 to no IR being detected, this packet will be sent, with the number
122 of microseconds with no IR.
123
124 ``LIRC_MODE2_OVERFLOW``
125
126 Signifies that the IR receiver encounter an overflow, and some IR
127 is missing. The IR data after this should be correct again. The
128 actual value is not important, but this is set to 0xffffff by the
129 kernel for compatibility with lircd.
130
131 .. _lirc-mode-pulse:
132
133 ``LIRC_MODE_PULSE``
134
135 In pulse mode, a sequence of pulse/space integer values are written to the
136 lirc device using :ref:`lirc-write`.
137
138 The values are alternating pulse and space lengths, in microseconds. The
139 first and last entry must be a pulse, so there must be an odd number
140 of entries.
141
142 This mode is used only for IR send.
143
144 *************************************
145 Data types used by LIRC_MODE_SCANCODE
146 *************************************
147
148 .. kernel-doc:: include/uapi/linux/lirc.h
149 :identifiers: lirc_scancode rc_proto
150
151 ********************
152 BPF based IR decoder
153 ********************
154
155 The kernel has support for decoding the most common
156 :ref:`IR protocols <Remote_controllers_Protocols>`, but there
157 are many protocols which are not supported. To support these, it is possible
158 to load an BPF program which does the decoding. This can only be done on
159 LIRC devices which support reading raw IR.
160
161 First, using the `bpf(2)`_ syscall with the ``BPF_LOAD_PROG`` argument,
162 program must be loaded of type ``BPF_PROG_TYPE_LIRC_MODE2``. Once attached
163 to the LIRC device, this program will be called for each pulse, space or
164 timeout event on the LIRC device. The context for the BPF program is a
165 pointer to a unsigned int, which is a :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`
166 value. When the program has decoded the scancode, it can be submitted using
167 the BPF functions ``bpf_rc_keydown()`` or ``bpf_rc_repeat()``. Mouse or pointer
168 movements can be reported using ``bpf_rc_pointer_rel()``.
169
170 Once you have the file descriptor for the ``BPF_PROG_TYPE_LIRC_MODE2`` BPF
171 program, it can be attached to the LIRC device using the `bpf(2)`_ syscall.
172 The target must be the file descriptor for the LIRC device, and the
173 attach type must be ``BPF_LIRC_MODE2``. No more than 64 BPF programs can be
174 attached to a single LIRC device at a time.
175
176 .. _bpf(2): http://man7.org/linux/man-pages/man2/bpf.2.html
177

3. 한국어 전문 번역

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

LIRC 문자 장치와 양방향 데이터

1-18

LIRC는 Linux Infrared Remote Control의 약자입니다. LIRC 장치 인터페이스는 userspace와 kernelspace 사이에서 raw IR 데이터와 decode된 scan code를 양방향으로 운반합니다.

기본 형태는 `/dev/lircX` 문자 장치이며 X는 0부터 증가합니다. 표준 `struct file_operations`가 정의되고, raw IR 및 scan code의 송수신에서 핵심 연산은 `read`, `write`, `ioctl`입니다.

Raw IR을 scan code로 decode하는 BPF program을 LIRC 장치에 연결할 수도 있습니다. 이 경로는 kernel에 내장되지 않은 protocol을 지원할 때 사용합니다.

LIRC 데이터 경로
항목설명
read수신한 raw pulse/space 또는 decode된 scan code 읽기
write전송할 scan code 또는 pulse/space sequence 쓰기
ioctl장치 기능 조회와 수신·송신 mode 및 parameter 설정
BPFRaw IR event를 사용자 제공 decoder로 scan code 변환

장치 파일을 경계로 userspace와 kernelspace가 데이터를 교환합니다.

.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later

.. _lirc_dev_intro:

************
Introduction
************

LIRC stands for Linux Infrared Remote Control. The LIRC device interface is
a bi-directional interface for transporting raw IR and decoded scancodes
data between userspace and kernelspace. Fundamentally, it is just a chardev
(/dev/lircX, for X = 0, 1, 2, ...), with a number of standard struct
file_operations defined on it. With respect to transporting raw IR and
decoded scancodes to and fro, the essential fops are read, write and ioctl.

It is also possible to attach a BPF program to a LIRC device for decoding
raw IR into scancodes.

장치 등록 확인과 v4l-utils 도구

19-42

Driver가 LIRC에 등록되면 kernel log에는 RC 장치, LIRC minor 번호, raw IR receiver 및 transmitter 지원 여부가 나타납니다. 예시는 `mceusb`가 minor 0에 등록된 경우입니다.

이에 대응하는 문자 장치는 `/dev/lirc0`처럼 보이며 예시에서는 major 248, minor 0입니다. 실제 번호와 권한은 시스템 구성에 따라 달라질 수 있습니다.

`v4l-utils`에는 LIRC 장치용 도구가 포함됩니다. `ir-ctl`은 raw IR 수신·송신과 기능 조회를 담당하고, `ir-keytable`은 keymap과 kernel IR protocol 설정, BPF IR decoder 적재 및 decode 시험을 지원합니다.

v4l-utils의 LIRC 도구
항목설명
ir-ctlRaw IR 수신, IR 송신, LIRC 장치 feature 조회
ir-keytableKeymap 적재, kernel protocol 선택, BPF decoder 적재와 시험

작업 목적에 따라 도구를 선택합니다.

Example dmesg output upon a driver registering w/LIRC:

.. code-block:: none

    $ dmesg |grep lirc_dev
    rc rc0: lirc_dev: driver mceusb registered at minor = 0, raw IR receiver, raw IR transmitter

What you should see for a chardev:

.. code-block:: none

    $ ls -l /dev/lirc*
    crw-rw---- 1 root root 248, 0 Jul 2 22:20 /dev/lirc0

Note that the package `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_
contains tools for working with LIRC devices:

 - ir-ctl: can receive raw IR and transmit IR, as well as query LIRC
   device features.

 - ir-keytable: can load keymaps; allows you to set IR kernel protocols; load
   BPF IR decoders and test IR decoding. Some BPF IR decoders are also
   provided.

LIRC_MODE_SCANCODE 송수신

43-89

LIRC는 여러 수신·송신 mode를 지원합니다. `LIRC_MODE_SCANCODE`는 송신과 수신 양쪽에서 decode된 scan code structure를 교환합니다.

송신할 때는 `struct lirc_scancode`의 `scancode`에 원하는 값, `rc_proto`에 IR protocol을 넣고 나머지 member를 0으로 만든 뒤 LIRC 장치에 씁니다. 수신할 때는 같은 structure를 읽으며, 유효한 key mapping이 있으면 `keycode`, 없으면 `KEY_RESERVED`가 들어갑니다.

`flags`에는 toggle bit가 있는 rc-5·rc-6 같은 protocol의 `LIRC_SCANCODE_FLAG_TOGGLE`, repeat message가 있는 NEC 같은 protocol의 `LIRC_SCANCODE_FLAG_REPEAT`가 설정될 수 있습니다.

Sanyo와 NEC remote는 button을 계속 누를 때 전체 scan code 대신 scan code가 없는 짧은 repeat message를 보냅니다. 이 경우 kernel은 repeat flag를 설정하고 이전 scan code와 key code를 반복합니다. NEC에서는 길게 누르기와 같은 button을 반복해 누르기를 구분할 수 없습니다.

rc-5와 rc-6는 button을 놓았다가 다시 누를 때 반전되는 toggle bit가 있어 새 입력을 구분합니다. `timestamp`는 scan code를 decode한 `CLOCK_MONOTONIC` 기준 nanosecond 시각입니다.

lirc_scancode 핵심 member
항목설명
scancode송신할 값 또는 수신해 decode한 scan code
rc_proto적용한 IR protocol
keycodeKeymap 결과, 대응이 없으면 KEY_RESERVED
flagsTOGGLE 또는 REPEAT 상태
timestampCLOCK_MONOTONIC 기준 decode 시각(ns)

송수신 방향과 protocol 상태를 함께 전달합니다.

.. _lirc_modes:

**********
LIRC modes
**********

LIRC supports some modes of receiving and sending IR codes, as shown
on the following table.

.. _lirc-mode-scancode:
.. _lirc-scancode-flag-toggle:
.. _lirc-scancode-flag-repeat:

``LIRC_MODE_SCANCODE``

    This mode is for both sending and receiving IR.

    For transmitting (aka sending), create a struct lirc_scancode with
    the desired scancode set in the ``scancode`` member, :c:type:`rc_proto`
    set to the :ref:`IR protocol <Remote_controllers_Protocols>`, and all other
    members set to 0. Write this struct to the lirc device.

    For receiving, you read struct lirc_scancode from the LIRC device.
    The ``scancode`` field is set to the received scancode and the
    :ref:`IR protocol <Remote_controllers_Protocols>` is set in
    :c:type:`rc_proto`. If the scancode maps to a valid key code, this is set
    in the ``keycode`` field, else it is set to ``KEY_RESERVED``.

    The ``flags`` can have ``LIRC_SCANCODE_FLAG_TOGGLE`` set if the toggle
    bit is set in protocols that support it (e.g. rc-5 and rc-6), or
    ``LIRC_SCANCODE_FLAG_REPEAT`` for when a repeat is received for protocols
    that support it (e.g. nec).

    In the Sanyo and NEC protocol, if you hold a button on remote, rather than
    repeating the entire scancode, the remote sends a shorter message with
    no scancode, which just means button is held, a "repeat". When this is
    received, the ``LIRC_SCANCODE_FLAG_REPEAT`` is set and the scancode and
    keycode is repeated.

    With nec, there is no way to distinguish "button hold" from "repeatedly
    pressing the same button". The rc-5 and rc-6 protocols have a toggle bit.
    When a button is released and pressed again, the toggle bit is inverted.
    If the toggle bit is set, the ``LIRC_SCANCODE_FLAG_TOGGLE`` is set.

    The ``timestamp`` field is filled with the time nanoseconds
    (in ``CLOCK_MONOTONIC``) when the scancode was decoded.

LIRC_MODE_MODE2 raw IR packet

90-130

`LIRC_MODE_MODE2`는 IR 수신 전용 mode입니다. Driver는 pulse와 space 정보를 u32 값의 sequence로 userspace에 반환합니다.

상위 8 bit는 packet type, 하위 24 bit는 payload입니다. `LIRC_MODE2()`로 type을, `LIRC_VALUE()`로 payload를 얻습니다.

`LIRC_MODE2_PULSE`는 microsecond 단위 IR 존재 구간이며 flash라고도 하고, `LIRC_MODE2_SPACE`는 IR 부재 구간이며 gap이라고도 합니다. `LIRC_MODE2_FREQUENCY`는 carrier 측정을 활성화했을 때 Hertz 단위 carrier frequency를 전합니다.

`LIRC_MODE2_TIMEOUT`은 설정한 시간 동안 IR을 감지하지 못했을 때 발생하며 payload는 IR이 없었던 microsecond 수입니다. `LIRC_MODE2_OVERFLOW`는 receiver overflow로 일부 IR 데이터가 빠졌음을 알리고, 이후 데이터는 다시 정상이어야 합니다. Kernel은 lircd 호환성을 위해 overflow 값을 `0xffffff`로 설정합니다.

MODE2 packet type
항목설명
LIRC_MODE2_PULSEIR이 존재한 시간(us)
LIRC_MODE2_SPACEIR이 없었던 시간(us)
LIRC_MODE2_FREQUENCY측정한 carrier frequency(Hz)
LIRC_MODE2_TIMEOUTTimeout까지 IR이 없었던 시간(us)
LIRC_MODE2_OVERFLOW일부 수신 데이터 손실, 호환 값 0xffffff

상위 8 bit type에 따라 하위 24 bit payload를 해석합니다.

.. _lirc-mode-mode2:

``LIRC_MODE_MODE2``

    The driver returns a sequence of pulse and space codes to userspace,
    as a series of u32 values.

    This mode is used only for IR receive.

    The upper 8 bits determine the packet type, and the lower 24 bits
    the payload. Use ``LIRC_VALUE()`` macro to get the payload, and
    the macro ``LIRC_MODE2()`` will give you the type, which
    is one of:

    ``LIRC_MODE2_PULSE``

        Signifies the presence of IR in microseconds, also known as *flash*.

    ``LIRC_MODE2_SPACE``

        Signifies absence of IR in microseconds, also known as *gap*.

    ``LIRC_MODE2_FREQUENCY``

        If measurement of the carrier frequency was enabled with
        :ref:`lirc_set_measure_carrier_mode` then this packet gives you
        the carrier frequency in Hertz.

    ``LIRC_MODE2_TIMEOUT``

        When the timeout set with :ref:`lirc_set_rec_timeout` expires due
        to no IR being detected, this packet will be sent, with the number
        of microseconds with no IR.

    ``LIRC_MODE2_OVERFLOW``

        Signifies that the IR receiver encounter an overflow, and some IR
        is missing. The IR data after this should be correct again. The
        actual value is not important, but this is set to 0xffffff by the
        kernel for compatibility with lircd.

LIRC_MODE_PULSE와 SCANCODE data type

131-150

`LIRC_MODE_PULSE`는 IR 송신 전용입니다. `lirc-write`를 사용해 pulse와 space 길이를 microsecond 단위 정수 sequence로 LIRC 장치에 씁니다.

값은 pulse, space 순서로 번갈아야 하며 첫 항목과 마지막 항목은 모두 pulse여야 합니다. 따라서 항목 수는 홀수여야 합니다.

뒤이어 `include/uapi/linux/lirc.h`의 kernel-doc에서 `lirc_scancode`와 `rc_proto` 정의를 가져와 `LIRC_MODE_SCANCODE`가 사용하는 ABI data type을 설명합니다.

PULSE 송신 배열 검증
첫 값은 pulse 길이다음 값은 space 길이Pulse와 space를 교대로 반복마지막 값은 pulse전체 항목 수는 홀수

배열의 위치로 pulse와 space를 구분합니다.

.. _lirc-mode-pulse:

``LIRC_MODE_PULSE``

    In pulse mode, a sequence of pulse/space integer values are written to the
    lirc device using :ref:`lirc-write`.

    The values are alternating pulse and space lengths, in microseconds. The
    first and last entry must be a pulse, so there must be an odd number
    of entries.

    This mode is used only for IR send.

*************************************
Data types used by LIRC_MODE_SCANCODE
*************************************

.. kernel-doc:: include/uapi/linux/lirc.h
    :identifiers: lirc_scancode rc_proto

BPF 기반 IR decoder

151-176

Kernel은 흔한 IR protocol을 decode하지만 모든 protocol을 지원하지는 않습니다. Raw IR 읽기를 지원하는 LIRC 장치에는 지원되지 않는 protocol을 처리하는 BPF decoder를 적재할 수 있습니다.

먼저 `bpf(2)`의 `BPF_LOAD_PROG`로 `BPF_PROG_TYPE_LIRC_MODE2` program을 적재합니다. 장치에 연결하면 LIRC의 pulse, space, timeout event마다 program이 호출됩니다. Context는 `LIRC_MODE_MODE2` 값을 담은 unsigned int pointer입니다.

Decode가 끝나면 `bpf_rc_keydown()` 또는 `bpf_rc_repeat()`으로 scan code를 제출합니다. Mouse나 pointer의 상대 이동은 `bpf_rc_pointer_rel()`로 보고할 수 있습니다.

Program file descriptor를 얻은 뒤 다시 `bpf(2)`로 LIRC 장치에 연결합니다. Target은 LIRC device fd, attach type은 `BPF_LIRC_MODE2`여야 하며, 한 LIRC 장치에는 BPF program을 최대 64개 연결할 수 있습니다.

BPF IR decode 경로
BPF_PROG_TYPE_LIRC_MODE2 program 적재LIRC device fd에 BPF_LIRC_MODE2 type으로 attachPulse, space 또는 timeout마다 program 호출Protocol state를 갱신해 scan code decodebpf_rc_keydown(), bpf_rc_repeat() 또는 pointer helper로 결과 제출

Raw MODE2 event에서 RC 입력 event를 만듭니다.

********************
BPF based IR decoder
********************

The kernel has support for decoding the most common
:ref:`IR protocols <Remote_controllers_Protocols>`, but there
are many protocols which are not supported. To support these, it is possible
to load an BPF program which does the decoding. This can only be done on
LIRC devices which support reading raw IR.

First, using the `bpf(2)`_ syscall with the ``BPF_LOAD_PROG`` argument,
program must be loaded of type ``BPF_PROG_TYPE_LIRC_MODE2``. Once attached
to the LIRC device, this program will be called for each pulse, space or
timeout event on the LIRC device. The context for the BPF program is a
pointer to a unsigned int, which is a :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`
value. When the program has decoded the scancode, it can be submitted using
the BPF functions ``bpf_rc_keydown()`` or ``bpf_rc_repeat()``. Mouse or pointer
movements can be reported using ``bpf_rc_pointer_rel()``.

Once you have the file descriptor for the ``BPF_PROG_TYPE_LIRC_MODE2`` BPF
program, it can be attached to the LIRC device using the `bpf(2)`_ syscall.
The target must be the file descriptor for the LIRC device, and the
attach type must be ``BPF_LIRC_MODE2``. No more than 64 BPF programs can be
attached to a single LIRC device at a time.

.. _bpf(2): http://man7.org/linux/man-pages/man2/bpf.2.html