요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
===============================================
Userspace communication protocol over connector
===============================================
Message types
=============
There are three types of messages between w1 core and userspace:
1. Events. They are generated each time a new master or slave device
is found either due to automatic or requested search.
2. Userspace commands.
3. Replies to userspace commands.
Protocol
========
::
[struct cn_msg] - connector header.
Its length field is equal to size of the attached data
[struct w1_netlink_msg] - w1 netlink header.
__u8 type - message type.
W1_LIST_MASTERS
list current bus masters
W1_SLAVE_ADD/W1_SLAVE_REMOVE
slave add/remove events
W1_MASTER_ADD/W1_MASTER_REMOVE
master add/remove events
W1_MASTER_CMD
userspace command for bus master
device (search/alarm search)
W1_SLAVE_CMD
userspace command for slave device
(read/write/touch)
__u8 status - error indication from kernel
__u16 len - size of data attached to this header data
union {
__u8 id[8]; - slave unique device id
struct w1_mst {
__u32 id; - master's id
__u32 res; - reserved
} mst;
} id;
[struct w1_netlink_cmd] - command for given master or slave device.
__u8 cmd - command opcode.
W1_CMD_READ - read command
W1_CMD_WRITE - write command
W1_CMD_SEARCH - search command
W1_CMD_ALARM_SEARCH - alarm search command
W1_CMD_TOUCH - touch command
(write and sample data back to userspace)
W1_CMD_RESET - send bus reset
W1_CMD_SLAVE_ADD - add slave to kernel list
W1_CMD_SLAVE_REMOVE - remove slave from kernel list
W1_CMD_LIST_SLAVES - get slaves list from kernel
__u8 res - reserved
__u16 len - length of data for this command
For read command data must be allocated like for write command
__u8 data[0] - data for this command
Each connector message can include one or more w1_netlink_msg with
zero or more attached w1_netlink_cmd messages.
For event messages there are no w1_netlink_cmd embedded structures,
only connector header and w1_netlink_msg structure with "len" field
being zero and filled type (one of event types) and id:
either 8 bytes of slave unique id in host order,
or master's id, which is assigned to bus master device
when it is added to w1 core.
Currently replies to userspace commands are only generated for read
command request. One reply is generated exactly for one w1_netlink_cmd
read request. Replies are not combined when sent - i.e. typical reply
messages looks like the following::
[cn_msg][w1_netlink_msg][w1_netlink_cmd]
cn_msg.len = sizeof(struct w1_netlink_msg) +
sizeof(struct w1_netlink_cmd) +
cmd->len;
w1_netlink_msg.len = sizeof(struct w1_netlink_cmd) + cmd->len;
w1_netlink_cmd.len = cmd->len;
Replies to W1_LIST_MASTERS should send a message back to the userspace
which will contain list of all registered master ids in the following
format::
cn_msg (CN_W1_IDX.CN_W1_VAL as id, len is equal to sizeof(struct
w1_netlink_msg) plus number of masters multiplied by 4)
w1_netlink_msg (type: W1_LIST_MASTERS, len is equal to
number of masters multiplied by 4 (u32 size))
id0 ... idN
Each message is at most 4k in size, so if number of master devices
exceeds this, it will be split into several messages.
W1 search and alarm search commands.
request::
[cn_msg]
[w1_netlink_msg type = W1_MASTER_CMD
id is equal to the bus master id to use for searching]
[w1_netlink_cmd cmd = W1_CMD_SEARCH or W1_CMD_ALARM_SEARCH]
reply::
[cn_msg, ack = 1 and increasing, 0 means the last message,
seq is equal to the request seq]
[w1_netlink_msg type = W1_MASTER_CMD]
[w1_netlink_cmd cmd = W1_CMD_SEARCH or W1_CMD_ALARM_SEARCH
len is equal to number of IDs multiplied by 8]
[64bit-id0 ... 64bit-idN]
Length in each header corresponds to the size of the data behind it, so
w1_netlink_cmd->len = N * 8; where N is number of IDs in this message.
Can be zero.
::
w1_netlink_msg->len = sizeof(struct w1_netlink_cmd) + N * 8;
cn_msg->len = sizeof(struct w1_netlink_msg) +
sizeof(struct w1_netlink_cmd) +
N*8;
W1 reset command::
[cn_msg]
[w1_netlink_msg type = W1_MASTER_CMD
id is equal to the bus master id to use for searching]
[w1_netlink_cmd cmd = W1_CMD_RESET]
Command status replies
======================
Each command (either root, master or slave with or without w1_netlink_cmd
structure) will be 'acked' by the w1 core. Format of the reply is the same
as request message except that length parameters do not account for data
requested by the user, i.e. read/write/touch IO requests will not contain
data, so w1_netlink_cmd.len will be 0, w1_netlink_msg.len will be size
of the w1_netlink_cmd structure and cn_msg.len will be equal to the sum
of the sizeof(struct w1_netlink_msg) and sizeof(struct w1_netlink_cmd).
If reply is generated for master or root command (which do not have
w1_netlink_cmd attached), reply will contain only cn_msg and w1_netlink_msg
structures.
w1_netlink_msg.status field will carry positive error value
(EINVAL for example) or zero in case of success.
All other fields in every structure will mirror the same parameters in the
request message (except lengths as described above).
Status reply is generated for every w1_netlink_cmd embedded in the
w1_netlink_msg, if there are no w1_netlink_cmd structures,
reply will be generated for the w1_netlink_msg.
All w1_netlink_cmd command structures are handled in every w1_netlink_msg,
even if there were errors, only length mismatch interrupts message processing.
Operation steps in w1 core when new command is received
=======================================================
When new message (w1_netlink_msg) is received w1 core detects if it is
master or slave request, according to w1_netlink_msg.type field.
Then master or slave device is searched for.
When found, master device (requested or those one on where slave device
is found) is locked. If slave command is requested, then reset/select
procedure is started to select given device.
Then all requested in w1_netlink_msg operations are performed one by one.
If command requires reply (like read command) it is sent on command completion.
When all commands (w1_netlink_cmd) are processed master device is unlocked
and next w1_netlink_msg header processing started.
Connector [1] specific documentation
====================================
Each connector message includes two u32 fields as "address".
w1 uses CN_W1_IDX and CN_W1_VAL defined in include/linux/connector.h header.
Each message also includes sequence and acknowledge numbers.
Sequence number for event messages is appropriate bus master sequence number
increased with each event message sent "through" this master.
Sequence number for userspace requests is set by userspace application.
Sequence number for reply is the same as was in request, and
acknowledge number is set to seq+1.
Additional documentation, source code examples
==============================================
1. Documentation/driver-api/connector.rst
2. http://www.ioremap.net/archive/w1
This archive includes userspace application w1d.c which uses
read/write/search commands for all master/slave devices found on the bus.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
세 가지 메시지 유형
1-15W1 core와 사용자 공간 사이에는 세 종류의 메시지가 있습니다. 자동 또는 요청 검색으로 새 master·slave를 찾을 때 만드는 이벤트, 사용자 공간 명령, 사용자 공간 명령에 대한 응답입니다.
발신 원인과 역할입니다.
===============================================
Userspace communication protocol over connector
===============================================
Message types
=============
There are three types of messages between w1 core and userspace:
1. Events. They are generated each time a new master or slave device
is found either due to automatic or requested search.
2. Userspace commands.
3. Replies to userspace commands.
메시지 헤더·명령·검색 응답
16-136Connector 메시지는 `struct cn_msg` 헤더로 시작하며 `length`는 뒤에 붙은 데이터 크기입니다. 다음 `struct w1_netlink_msg`에는 메시지 `type`, 커널 오류를 나타내는 `status`, 이 헤더 뒤 데이터 크기 `len`, 그리고 slave의 8바이트 고유 ID 또는 master의 32비트 ID와 예약 필드가 있습니다.
메시지 type은 master 목록 `W1_LIST_MASTERS`, slave 추가·제거 이벤트, master 추가·제거 이벤트, 검색·경보 검색을 위한 `W1_MASTER_CMD`, 읽기·쓰기·touch를 위한 `W1_SLAVE_CMD`를 구분합니다.
`struct w1_netlink_cmd`는 명령 opcode, 예약 필드, 명령 데이터 길이, 가변 데이터로 구성됩니다. opcode는 READ, WRITE, SEARCH, ALARM_SEARCH, TOUCH, RESET, SLAVE_ADD, SLAVE_REMOVE, LIST_SLAVES입니다. READ도 WRITE와 같은 방식으로 데이터 공간을 할당해야 합니다.
Connector 메시지 하나에는 `w1_netlink_msg`가 하나 이상 들어갈 수 있고 각 메시지에는 `w1_netlink_cmd`가 0개 이상 붙습니다. 이벤트에는 command 구조체가 없고 netlink header의 `len`은 0이며 event type과 host byte order의 slave ID 또는 core 등록 때 배정한 master ID만 채웁니다.
현재 사용자 명령 응답은 READ 요청에 대해서만 생성하고 READ command 하나마다 응답 하나를 보냅니다. 응답은 합치지 않으며 `cn_msg.len`, `w1_netlink_msg.len`, `w1_netlink_cmd.len`은 각자 바로 뒤 데이터 크기를 반영합니다.
`W1_LIST_MASTERS` 응답은 모든 등록 master ID를 32비트 값 배열로 보냅니다. 메시지 최대 크기는 4KiB이므로 master가 많으면 여러 메시지로 나눕니다.
SEARCH와 ALARM_SEARCH 요청은 `W1_MASTER_CMD`에 사용할 bus master ID와 해당 command를 담습니다. 응답은 요청과 같은 `seq`를 쓰고 `ack`는 1부터 증가하며 마지막 메시지는 0입니다. 데이터는 64비트 ID 배열이고 command 길이는 `N * 8`입니다. ID가 없어 N이 0일 수도 있습니다.
RESET은 사용할 master ID를 가진 `W1_MASTER_CMD`와 `W1_CMD_RESET` command로 구성합니다.
헤더 type이 선택하는 작업입니다.
command 구조체가 표현하는 저수준 작업입니다.
길이 필드는 각 헤더 바로 뒤 데이터 크기를 나타냅니다.
Protocol
========
::
[struct cn_msg] - connector header.
Its length field is equal to size of the attached data
[struct w1_netlink_msg] - w1 netlink header.
__u8 type - message type.
W1_LIST_MASTERS
list current bus masters
W1_SLAVE_ADD/W1_SLAVE_REMOVE
slave add/remove events
W1_MASTER_ADD/W1_MASTER_REMOVE
master add/remove events
W1_MASTER_CMD
userspace command for bus master
device (search/alarm search)
W1_SLAVE_CMD
userspace command for slave device
(read/write/touch)
__u8 status - error indication from kernel
__u16 len - size of data attached to this header data
union {
__u8 id[8]; - slave unique device id
struct w1_mst {
__u32 id; - master's id
__u32 res; - reserved
} mst;
} id;
[struct w1_netlink_cmd] - command for given master or slave device.
__u8 cmd - command opcode.
W1_CMD_READ - read command
W1_CMD_WRITE - write command
W1_CMD_SEARCH - search command
W1_CMD_ALARM_SEARCH - alarm search command
W1_CMD_TOUCH - touch command
(write and sample data back to userspace)
W1_CMD_RESET - send bus reset
W1_CMD_SLAVE_ADD - add slave to kernel list
W1_CMD_SLAVE_REMOVE - remove slave from kernel list
W1_CMD_LIST_SLAVES - get slaves list from kernel
__u8 res - reserved
__u16 len - length of data for this command
For read command data must be allocated like for write command
__u8 data[0] - data for this command
Each connector message can include one or more w1_netlink_msg with
zero or more attached w1_netlink_cmd messages.
For event messages there are no w1_netlink_cmd embedded structures,
only connector header and w1_netlink_msg structure with "len" field
being zero and filled type (one of event types) and id:
either 8 bytes of slave unique id in host order,
or master's id, which is assigned to bus master device
when it is added to w1 core.
Currently replies to userspace commands are only generated for read
command request. One reply is generated exactly for one w1_netlink_cmd
read request. Replies are not combined when sent - i.e. typical reply
messages looks like the following::
[cn_msg][w1_netlink_msg][w1_netlink_cmd]
cn_msg.len = sizeof(struct w1_netlink_msg) +
sizeof(struct w1_netlink_cmd) +
cmd->len;
w1_netlink_msg.len = sizeof(struct w1_netlink_cmd) + cmd->len;
w1_netlink_cmd.len = cmd->len;
Replies to W1_LIST_MASTERS should send a message back to the userspace
which will contain list of all registered master ids in the following
format::
cn_msg (CN_W1_IDX.CN_W1_VAL as id, len is equal to sizeof(struct
w1_netlink_msg) plus number of masters multiplied by 4)
w1_netlink_msg (type: W1_LIST_MASTERS, len is equal to
number of masters multiplied by 4 (u32 size))
id0 ... idN
Each message is at most 4k in size, so if number of master devices
exceeds this, it will be split into several messages.
W1 search and alarm search commands.
request::
[cn_msg]
[w1_netlink_msg type = W1_MASTER_CMD
id is equal to the bus master id to use for searching]
[w1_netlink_cmd cmd = W1_CMD_SEARCH or W1_CMD_ALARM_SEARCH]
reply::
[cn_msg, ack = 1 and increasing, 0 means the last message,
seq is equal to the request seq]
[w1_netlink_msg type = W1_MASTER_CMD]
[w1_netlink_cmd cmd = W1_CMD_SEARCH or W1_CMD_ALARM_SEARCH
len is equal to number of IDs multiplied by 8]
[64bit-id0 ... 64bit-idN]
Length in each header corresponds to the size of the data behind it, so
w1_netlink_cmd->len = N * 8; where N is number of IDs in this message.
Can be zero.
::
w1_netlink_msg->len = sizeof(struct w1_netlink_cmd) + N * 8;
cn_msg->len = sizeof(struct w1_netlink_msg) +
sizeof(struct w1_netlink_cmd) +
N*8;
W1 reset command::
[cn_msg]
[w1_netlink_msg type = W1_MASTER_CMD
id is equal to the bus master id to use for searching]
[w1_netlink_cmd cmd = W1_CMD_RESET]
명령별 상태 응답
137-164W1 core는 root·master·slave command를 command 구조체 유무와 관계없이 acknowledge합니다. 응답 형식은 요청과 같지만 사용자가 요청한 read/write/touch 데이터는 길이에 포함하지 않습니다.
따라서 I/O 상태 응답의 `w1_netlink_cmd.len`은 0, `w1_netlink_msg.len`은 command 구조체 크기, `cn_msg.len`은 netlink header와 command 구조체 크기의 합입니다. command가 없는 master·root 응답은 `cn_msg`와 `w1_netlink_msg`만 포함합니다.
`w1_netlink_msg.status`는 성공이면 0, 실패면 `EINVAL` 같은 양의 오류 값을 담습니다. 길이를 제외한 나머지 필드는 요청 값을 그대로 반영합니다.
netlink message에 command가 여러 개 있으면 각각 상태 응답을 생성합니다. command가 하나도 없으면 netlink message 자체에 응답합니다. 오류가 발생해도 모든 command를 처리하며 길이 불일치만 메시지 처리를 중단합니다.
I/O 데이터가 빠진 acknowledge 구조입니다.
Command status replies
======================
Each command (either root, master or slave with or without w1_netlink_cmd
structure) will be 'acked' by the w1 core. Format of the reply is the same
as request message except that length parameters do not account for data
requested by the user, i.e. read/write/touch IO requests will not contain
data, so w1_netlink_cmd.len will be 0, w1_netlink_msg.len will be size
of the w1_netlink_cmd structure and cn_msg.len will be equal to the sum
of the sizeof(struct w1_netlink_msg) and sizeof(struct w1_netlink_cmd).
If reply is generated for master or root command (which do not have
w1_netlink_cmd attached), reply will contain only cn_msg and w1_netlink_msg
structures.
w1_netlink_msg.status field will carry positive error value
(EINVAL for example) or zero in case of success.
All other fields in every structure will mirror the same parameters in the
request message (except lengths as described above).
Status reply is generated for every w1_netlink_cmd embedded in the
w1_netlink_msg, if there are no w1_netlink_cmd structures,
reply will be generated for the w1_netlink_msg.
All w1_netlink_cmd command structures are handled in every w1_netlink_msg,
even if there were errors, only length mismatch interrupts message processing.
core의 명령 처리 순서
165-181새 `w1_netlink_msg`를 받으면 core는 type으로 master 요청인지 slave 요청인지 판단하고 대상 장치를 찾습니다.
대상을 찾으면 요청한 master 또는 slave가 연결된 master를 잠급니다. slave command라면 해당 장치를 선택하기 위한 reset/select 절차를 시작합니다.
메시지에 담긴 작업을 순서대로 실행하고 READ처럼 응답이 필요한 명령은 완료 시 보냅니다. 모든 command를 처리한 뒤 master 잠금을 풀고 다음 netlink header를 처리합니다.
한 master 잠금 안에서 메시지의 command를 직렬 실행합니다.
Operation steps in w1 core when new command is received
=======================================================
When new message (w1_netlink_msg) is received w1 core detects if it is
master or slave request, according to w1_netlink_msg.type field.
Then master or slave device is searched for.
When found, master device (requested or those one on where slave device
is found) is locked. If slave command is requested, then reset/select
procedure is started to select given device.
Then all requested in w1_netlink_msg operations are performed one by one.
If command requires reply (like read command) it is sent on command completion.
When all commands (w1_netlink_cmd) are processed master device is unlocked
and next w1_netlink_msg header processing started.
Connector 주소·seq·ack
182-194Connector 메시지는 주소 역할을 하는 두 `u32` 필드를 가지며 W1은 `include/linux/connector.h`의 `CN_W1_IDX`와 `CN_W1_VAL`을 사용합니다.
각 메시지는 sequence와 acknowledge 번호도 포함합니다. 이벤트 seq는 해당 bus master의 sequence를 사용하고 이벤트마다 증가합니다. 사용자 요청 seq는 사용자 애플리케이션이 정합니다. 응답 seq는 요청과 같고 ack는 `seq + 1`입니다.
메시지 종류별 sequence 규칙입니다.
Connector [1] specific documentation
====================================
Each connector message includes two u32 fields as "address".
w1 uses CN_W1_IDX and CN_W1_VAL defined in include/linux/connector.h header.
Each message also includes sequence and acknowledge numbers.
Sequence number for event messages is appropriate bus master sequence number
increased with each event message sent "through" this master.
Sequence number for userspace requests is set by userspace application.
Sequence number for reply is the same as was in request, and
acknowledge number is set to seq+1.
추가 문서와 예제
195-202추가 설명은 `Documentation/driver-api/connector.rst`와 원문에 적힌 ioremap.net W1 archive에서 찾을 수 있습니다. archive에는 발견한 모든 master·slave에 READ, WRITE, SEARCH 명령을 사용하는 사용자 공간 애플리케이션 `w1d.c`가 포함되어 있습니다.
Additional documentation, source code examples
==============================================
1. Documentation/driver-api/connector.rst
2. http://www.ioremap.net/archive/w1
This archive includes userspace application w1d.c which uses
read/write/search commands for all master/slave devices found on the bus.
요약·해설
w1-netlink.rst:1-202W1 connector 메시지 구조, 명령·응답 길이, 검색과 상태 처리 순서를 설명합니다.