요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. 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.
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_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:
``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:
``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 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
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
LIRC 문자 장치와 양방향 데이터
1-18LIRC는 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을 지원할 때 사용합니다.
장치 파일을 경계로 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-42Driver가 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 시험을 지원합니다.
작업 목적에 따라 도구를 선택합니다.
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-89LIRC는 여러 수신·송신 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 시각입니다.
송수신 방향과 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`로 설정합니다.
상위 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와 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-176Kernel은 흔한 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개 연결할 수 있습니다.
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
요약·해설
lirc-dev-intro.rst:1-176LIRC는 `/dev/lircX`에서 decode된 scan code 또는 raw pulse/space를 교환합니다. 세 mode의 데이터 형식과 repeat·toggle 의미, BPF decoder의 적재·연결·결과 제출 절차를 구분해야 합니다.