요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=============
Core elements
=============
The Industrial I/O core offers both a unified framework for writing drivers for
many different types of embedded sensors and a standard interface to user space
applications manipulating sensors. The implementation can be found under
:file:`drivers/iio/industrialio-*`
Industrial I/O Devices
----------------------
* struct iio_dev - industrial I/O device
* iio_device_alloc() - allocate an :c:type:`iio_dev` from a driver
* iio_device_free() - free an :c:type:`iio_dev` from a driver
* iio_device_register() - register a device with the IIO subsystem
* iio_device_unregister() - unregister a device from the IIO
subsystem
An IIO device usually corresponds to a single hardware sensor and it
provides all the information needed by a driver handling a device.
Let's first have a look at the functionality embedded in an IIO device
then we will show how a device driver makes use of an IIO device.
There are two ways for a user space application to interact with an IIO driver.
1. :file:`/sys/bus/iio/devices/iio:device{X}/`, this represents a hardware sensor
and groups together the data channels of the same chip.
2. :file:`/dev/iio:device{X}`, character device node interface used for
buffered data transfer and for events information retrieval.
A typical IIO driver will register itself as an :doc:`I2C <../i2c>` or
:doc:`SPI <../spi>` driver and will create two routines, probe and remove.
At probe:
1. Call iio_device_alloc(), which allocates memory for an IIO device.
2. Initialize IIO device fields with driver specific information (e.g.
device name, device channels).
3. Call iio_device_register(), this registers the device with the
IIO core. After this call the device is ready to accept requests from user
space applications.
At remove, we free the resources allocated in probe in reverse order:
1. iio_device_unregister(), unregister the device from the IIO core.
2. iio_device_free(), free the memory allocated for the IIO device.
IIO device sysfs interface
==========================
Attributes are sysfs files used to expose chip info and also allowing
applications to set various configuration parameters. For device with
index X, attributes can be found under /sys/bus/iio/devices/iio:deviceX/
directory. Common attributes are:
* :file:`name`, description of the physical chip.
* :file:`dev`, shows the major:minor pair associated with
:file:`/dev/iio:deviceX` node.
* :file:`sampling_frequency_available`, available discrete set of sampling
frequency values for device.
* Available standard attributes for IIO devices are described in the
:file:Documentation/ABI/testing/sysfs-bus-iio file in the Linux kernel
sources.
IIO device channels
===================
struct iio_chan_spec - specification of a single channel
An IIO device channel is a representation of a data channel. An IIO device can
have one or multiple channels. For example:
* a thermometer sensor has one channel representing the temperature measurement.
* a light sensor with two channels indicating the measurements in the visible
and infrared spectrum.
* an accelerometer can have up to 3 channels representing acceleration on X, Y
and Z axes.
An IIO channel is described by the struct iio_chan_spec.
A thermometer driver for the temperature sensor in the example above would
have to describe its channel as follows::
static const struct iio_chan_spec temp_channel[] = {
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
},
};
Channel sysfs attributes exposed to userspace are specified in the form of
bitmasks. Depending on their shared info, attributes can be set in one of the
following masks:
* **info_mask_separate**, attributes will be specific to
this channel
* **info_mask_shared_by_type**, attributes are shared by all channels of the
same type
* **info_mask_shared_by_dir**, attributes are shared by all channels of the same
direction
* **info_mask_shared_by_all**, attributes are shared by all channels
When there are multiple data channels per channel type we have two ways to
distinguish between them:
* set **.modified** field of :c:type:`iio_chan_spec` to 1. Modifiers are
specified using **.channel2** field of the same :c:type:`iio_chan_spec`
structure and are used to indicate a physically unique characteristic of the
channel such as its direction or spectral response. For example, a light
sensor can have two channels, one for infrared light and one for both
infrared and visible light.
* set **.indexed** field of :c:type:`iio_chan_spec` to 1. In this case the
channel is simply another instance with an index specified by the **.channel**
field.
Here is how we can make use of the channel's modifiers::
static const struct iio_chan_spec light_channels[] = {
{
.type = IIO_INTENSITY,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_IR,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
{
.type = IIO_INTENSITY,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_BOTH,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
{
.type = IIO_LIGHT,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
}
This channel's definition will generate two separate sysfs files for raw data
retrieval:
* :file:`/sys/bus/iio/devices/iio:device{X}/in_intensity_ir_raw`
* :file:`/sys/bus/iio/devices/iio:device{X}/in_intensity_both_raw`
one file for processed data:
* :file:`/sys/bus/iio/devices/iio:device{X}/in_illuminance_input`
and one shared sysfs file for sampling frequency:
* :file:`/sys/bus/iio/devices/iio:device{X}/sampling_frequency`.
Here is how we can make use of the channel's indexing::
static const struct iio_chan_spec light_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
},
{
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
},
}
This will generate two separate attributes files for raw data retrieval:
* :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage0_raw`, representing
voltage measurement for channel 0.
* :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage1_raw`, representing
voltage measurement for channel 1.
More details
============
.. kernel-doc:: include/linux/iio/iio.h
.. kernel-doc:: drivers/iio/industrialio-core.c
:export:
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Industrial I/O core
1-9문서 제목은 `Core elements`입니다. Industrial I/O core는 여러 종류의 embedded sensor driver를 작성하는 unified framework와 sensor를 조작하는 userspace application용 standard interface를 함께 제공합니다. 구현은 `drivers/iio/industrialio-*` 아래에 있습니다.
Hardware sensor에서 공통 userspace interface까지의 계층입니다.
IIO device lifecycle
10-48`struct iio_dev`는 industrial I/O device입니다. Driver는 `iio_device_alloc()`으로 할당하고 `iio_device_free()`로 해제하며, `iio_device_register()`로 IIO subsystem에 등록하고 `iio_device_unregister()`로 등록을 해제합니다.
IIO device는 보통 hardware sensor 하나에 대응하며 device를 다루는 driver에 필요한 모든 정보를 제공합니다.
Userspace application이 IIO driver와 상호작용하는 방법은 두 가지입니다. `/sys/bus/iio/devices/iio:device{X}/`는 hardware sensor를 나타내고 같은 chip의 data channel을 묶습니다. `/dev/iio:device{X}` character device node는 buffered data transfer와 event information retrieval에 사용합니다.
일반적인 IIO driver는 I2C 또는 SPI driver로 등록하고 `probe`와 `remove` routine을 만듭니다. Probe에서는 `iio_device_alloc()`으로 memory를 할당하고 device name·channel 같은 driver-specific field를 초기화한 뒤 `iio_device_register()`를 호출합니다. 이 호출 뒤 device가 userspace request를 받을 수 있습니다.
Remove에서는 probe의 역순으로 resource를 해제합니다. 먼저 `iio_device_unregister()`로 IIO core 등록을 해제하고 `iio_device_free()`로 device memory를 해제합니다.
Sysfs와 character device의 용도를 비교합니다.
등록과 해제를 정확히 역순으로 수행합니다.
IIO device sysfs interface
49-65Sysfs attribute는 chip information을 노출하고 application이 configuration parameter를 설정하게 하는 file입니다. Index X인 device의 attribute는 `/sys/bus/iio/devices/iio:deviceX/` 아래에 있습니다.
일반 attribute에는 physical chip 설명인 `name`, `/dev/iio:deviceX` node의 `major:minor` pair를 보여 주는 `dev`, device가 지원하는 discrete sampling frequency 집합인 `sampling_frequency_available`이 있습니다. IIO standard attribute 전체는 kernel source의 `Documentation/ABI/testing/sysfs-bus-iio`에 설명됩니다.
Device-level 공통 sysfs file입니다.
IIO channel과 iio_chan_spec
66-90`struct iio_chan_spec`은 single channel specification입니다. IIO device channel은 data channel 하나를 표현하며 device에는 channel이 하나 또는 여러 개 있을 수 있습니다.
Thermometer는 temperature measurement channel 하나, light sensor는 visible·infrared spectrum channel 두 개, accelerometer는 X·Y·Z acceleration channel을 최대 세 개 가질 수 있습니다.
IIO channel은 `struct iio_chan_spec`으로 설명합니다. 예제 thermometer는 `IIO_TEMP` type이고 `IIO_CHAN_INFO_PROCESSED`를 channel-specific processed attribute로 노출합니다.
static const struct iio_chan_spec temp_channel[] = {
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
},
};
Sensor 종류별 channel 구성을 비교합니다.
Channel attribute mask와 식별
91-115Userspace에 노출하는 channel sysfs attribute는 bitmask로 지정합니다. Shared 범위에 따라 `info_mask_separate`는 특정 channel만, `info_mask_shared_by_type`은 같은 type의 모든 channel, `info_mask_shared_by_dir`은 같은 direction의 모든 channel, `info_mask_shared_by_all`은 모든 channel이 공유합니다.
한 channel type에 data channel이 여러 개면 두 방식으로 구분합니다. 첫째, `iio_chan_spec.modified = 1`로 두고 같은 structure의 `.channel2`에 modifier를 지정합니다. Modifier는 direction이나 spectral response처럼 물리적으로 unique한 특성을 나타냅니다. 예를 들어 light sensor는 infrared channel과 infrared+visible channel을 둘 수 있습니다.
둘째, `iio_chan_spec.indexed = 1`로 두고 `.channel` field에 index를 지정합니다. 이 경우 channel은 단순히 index가 다른 instance입니다.
Attribute가 공유되는 channel 범위입니다.
Modifier와 index를 쓰는 조건입니다.
Channel modifier와 생성 attribute
116-153예제 light sensor는 `IIO_INTENSITY` channel 두 개에 `IIO_MOD_LIGHT_IR`와 `IIO_MOD_LIGHT_BOTH` modifier를 적용하고 raw data를 channel별로, sampling frequency를 공유 attribute로 노출합니다. 별도의 `IIO_LIGHT` channel은 processed illuminance 값을 노출합니다.
static const struct iio_chan_spec light_channels[] = {
{
.type = IIO_INTENSITY,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_IR,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
{
.type = IIO_INTENSITY,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_BOTH,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
{
.type = IIO_LIGHT,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
}
이 정의는 raw data용 `/sys/bus/iio/devices/iio:device{X}/in_intensity_ir_raw`와 `in_intensity_both_raw`, processed data용 `in_illuminance_input`, 공유 sampling frequency용 `sampling_frequency` file을 생성합니다.
Channel type·modifier·info mask가 attribute path를 만듭니다.
Channel definition과 결과 sysfs attribute입니다.
Indexed channel과 생성 attribute
154-177Channel indexing 예제는 `IIO_VOLTAGE` type 두 channel에 `.indexed = 1`을 설정하고 `.channel`을 0과 1로 지정합니다.
static const struct iio_chan_spec light_channels[] = {
{
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
},
{
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
},
}
그 결과 `/sys/bus/iio/devices/iio:device{X}/in_voltage0_raw`는 channel 0 voltage measurement를, `in_voltage1_raw`는 channel 1 measurement를 나타냅니다.
Channel number가 sysfs file 이름에 들어갑니다.
IIO core kernel API source
178-182IIO public core declaration은 `include/linux/iio/iio.h`, exported core implementation은 `drivers/iio/industrialio-core.c`의 kernel-doc에서 가져옵니다.
.. kernel-doc:: include/linux/iio/iio.h
.. kernel-doc:: drivers/iio/industrialio-core.c
:export:
Public header와 exported implementation입니다.
요약과 해설
core.rst:1-182IIO core는 sensor 하나를 iio_dev로, 측정 축·spectrum·instance를 iio_chan_spec으로 표현합니다. Probe와 remove는 allocation·registration을 정확히 역순으로 수행하고 mask·modifier·index가 생성될 sysfs attribute 이름과 공유 범위를 결정합니다.