요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=======
Buffers
=======
* struct iio_buffer — general buffer structure
* :c:func:`iio_validate_scan_mask_onehot` — Validates that exactly one channel
is selected
* :c:func:`iio_buffer_get` — Grab a reference to the buffer
* :c:func:`iio_buffer_put` — Release the reference to the buffer
The Industrial I/O core offers a way for continuous data capture based on a
trigger source. Multiple data channels can be read at once from
:file:`/dev/iio:device{X}` character device node, thus reducing the CPU load.
IIO buffer sysfs interface
==========================
An IIO buffer has an associated attributes directory under
:file:`/sys/bus/iio/devices/iio:device{X}/buffer/*`. Here are some of the
existing attributes:
* :file:`length`, the total number of data samples (capacity) that can be
stored by the buffer.
* :file:`enable`, activate buffer capture.
IIO buffer setup
================
The meta information associated with a channel reading placed in a buffer is
called a scan element. The important bits configuring scan elements are
exposed to userspace applications via the
:file:`/sys/bus/iio/devices/iio:device{X}/scan_elements/` directory. This
directory contains attributes of the following form:
* :file:`enable`, used for enabling a channel. If and only if its attribute
is non *zero*, then a triggered capture will contain data samples for this
channel.
* :file:`index`, the scan_index of the channel.
* :file:`type`, description of the scan element data storage within the buffer
and hence the form in which it is read from user space.
Format is [be|le]:[s|u]bits/storagebits[Xrepeat][>>shift] .
* *be* or *le*, specifies big or little endian.
* *s* or *u*, specifies if signed (2's complement) or unsigned.
* *bits*, is the number of valid data bits.
* *storagebits*, is the number of bits (after padding) that it occupies in the
buffer.
* *repeat*, specifies the number of bits/storagebits repetitions. When the
repeat element is 0 or 1, then the repeat value is omitted.
* *shift*, if specified, is the shift that needs to be applied prior to
masking out unused bits.
For example, a driver for a 3-axis accelerometer with 12 bit resolution where
data is stored in two 8-bits registers as follows::
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06)
+---+---+---+---+---+---+---+---+
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07)
+---+---+---+---+---+---+---+---+
will have the following scan element type for each axis::
$ cat /sys/bus/iio/devices/iio:device0/scan_elements/in_accel_y_type
le:s12/16>>4
A user space application will interpret data samples read from the buffer as
two byte little endian signed data, that needs a 4 bits right shift before
masking out the 12 valid bits of data.
For implementing buffer support a driver should initialize the following
fields in iio_chan_spec definition::
struct iio_chan_spec {
/* other members */
int scan_index
struct {
char sign;
u8 realbits;
u8 storagebits;
u8 shift;
u8 repeat;
enum iio_endian endianness;
} scan_type;
};
The driver implementing the accelerometer described above will have the
following channel definition::
struct iio_chan_spec accel_channels[] = {
{
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_X,
/* other stuff here */
.scan_index = 0,
.scan_type = {
.sign = 's',
.realbits = 12,
.storagebits = 16,
.shift = 4,
.endianness = IIO_LE,
},
}
/* similar for Y (with channel2 = IIO_MOD_Y, scan_index = 1)
* and Z (with channel2 = IIO_MOD_Z, scan_index = 2) axis
*/
}
Here **scan_index** defines the order in which the enabled channels are placed
inside the buffer. Channels with a lower **scan_index** will be placed before
channels with a higher index. Each channel needs to have a unique
**scan_index**.
Setting **scan_index** to -1 can be used to indicate that the specific channel
does not support buffered capture. In this case no entries will be created for
the channel in the scan_elements directory.
More details
============
.. kernel-doc:: include/linux/iio/buffer.h
.. kernel-doc:: drivers/iio/industrialio-buffer.c
:export:
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
IIO buffer 개요
1-14문서 제목은 `Buffers`입니다. `struct iio_buffer`는 일반 buffer 구조이고, `iio_validate_scan_mask_onehot`은 channel이 정확히 하나 선택됐는지 검증합니다. `iio_buffer_get`은 buffer reference를 얻고 `iio_buffer_put`은 그 reference를 해제합니다.
Industrial I/O core는 trigger source를 기반으로 continuous data capture를 제공합니다. `/dev/iio:device{X}` character device node에서 여러 data channel을 한꺼번에 읽을 수 있어 CPU load를 줄입니다.
Trigger에서 multi-channel userspace read까지의 경로입니다.
IIO buffer sysfs interface
15-24IIO buffer의 attribute directory는 `/sys/bus/iio/devices/iio:device{X}/buffer/*` 아래에 있습니다. `length`는 buffer가 저장할 수 있는 data sample 총수, 즉 capacity이고 `enable`은 buffer capture를 활성화합니다.
Capacity와 capture 활성화를 제어합니다.
Scan element 설정
25-51Buffer에 놓이는 channel reading의 meta information을 scan element라고 합니다. Scan element를 구성하는 핵심 bit는 userspace에 `/sys/bus/iio/devices/iio:device{X}/scan_elements/` directory로 노출됩니다.
`enable` 값이 0이 아닐 때에만 triggered capture에 해당 channel sample이 포함됩니다. `index`는 channel의 `scan_index`이고, `type`은 buffer 내부 storage와 userspace에서 읽는 data 형식을 설명합니다.
`type` 형식은 `[be|le]:[s|u]bits/storagebits[Xrepeat][>>shift]`입니다. `be`·`le`은 big endian·little endian, `s`·`u`는 signed 2's complement·unsigned, `bits`는 유효 data bit 수, `storagebits`는 padding 뒤 buffer에서 차지하는 bit 수입니다.
`repeat`는 bits/storagebits 반복 횟수이며 값이 0 또는 1이면 생략합니다. `shift`가 있으면 쓰지 않는 bit를 masking하기 전에 적용할 shift입니다.
각 token이 buffer sample 해석에 주는 의미입니다.
12-bit accelerometer 예제
52-72예제는 resolution 12-bit인 3-axis accelerometer가 data를 두 8-bit register에 저장하는 경우입니다. 원문의 register ASCII diagram은 아래에 그대로 보존하고 같은 내용을 bit-field 표로 다시 구성했습니다.
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06)
+---+---+---+---+---+---+---+---+
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
|D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07)
+---+---+---+---+---+---+---+---+
LOW·HIGH byte의 address와 유효 bit를 구조화했습니다.
각 axis의 scan element type은 다음과 같습니다.
$ cat /sys/bus/iio/devices/iio:device0/scan_elements/in_accel_y_type
le:s12/16>>4
Userspace application은 buffer sample을 two-byte little-endian signed data로 해석하고, 유효한 12 data bit를 masking하기 전에 4-bit right shift해야 합니다.
Raw 16-bit storage에서 signed 12-bit 값을 얻는 순서입니다.
Driver buffer channel 정의
73-120Buffer support를 구현하려면 driver가 `iio_chan_spec` 정의의 `scan_index`와 `scan_type` field를 초기화해야 합니다. `scan_type`에는 `sign`, `realbits`, `storagebits`, `shift`, `repeat`, `endianness`가 있습니다.
struct iio_chan_spec {
/* other members */
int scan_index
struct {
char sign;
u8 realbits;
u8 storagebits;
u8 shift;
u8 repeat;
enum iio_endian endianness;
} scan_type;
};
앞의 accelerometer를 구현하는 channel definition은 각 axis를 signed 12-bit data, 16-bit storage, shift 4, little endian으로 선언합니다.
struct iio_chan_spec accel_channels[] = {
{
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_X,
/* other stuff here */
.scan_index = 0,
.scan_type = {
.sign = 's',
.realbits = 12,
.storagebits = 16,
.shift = 4,
.endianness = IIO_LE,
},
}
/* similar for Y (with channel2 = IIO_MOD_Y, scan_index = 1)
* and Z (with channel2 = IIO_MOD_Z, scan_index = 2) axis
*/
}
`scan_index`는 enable된 channel이 buffer 안에 놓이는 순서를 정의합니다. 값이 낮은 channel이 높은 channel보다 먼저 놓이며 각 channel의 `scan_index`는 unique해야 합니다.
`scan_index = -1`은 해당 channel이 buffered capture를 지원하지 않음을 나타냅니다. 이 경우 그 channel의 entry는 `scan_elements` directory에 생성되지 않습니다.
Channel storage 형식을 만드는 driver field입니다.
Buffer 배치 순서와 비지원 channel 표시입니다.
Buffer kernel API source
121-126Buffer structure와 core API의 kernel-doc source는 `include/linux/iio/buffer.h`와 `drivers/iio/industrialio-buffer.c`입니다. 두 번째 source는 exported symbol을 문서화합니다.
.. kernel-doc:: include/linux/iio/buffer.h
.. kernel-doc:: drivers/iio/industrialio-buffer.c
:export:
Declaration과 exported implementation을 구분합니다.
요약과 해설
buffers.rst:1-126IIO buffer는 trigger event마다 여러 channel sample을 정해진 scan_index 순서와 scan_type storage 형식으로 쌓아 character device에서 효율적으로 읽게 합니다. Driver와 userspace는 endian, signedness, valid bits, padding과 shift를 같은 방식으로 해석해야 합니다.