用户空间通过连接器通信协议¶
消息类型¶
w1 核心和用户空间之间有三种类型的消息
事件。它们在每次由于自动或请求搜索而发现新的主设备或从设备时生成。
用户空间命令。
对用户空间命令的回复。
协议¶
[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
每个连接器消息可以包含一个或多个 w1_netlink_msg,并带有零个或多个附加的 w1_netlink_cmd 消息。
对于事件消息,没有嵌入的 w1_netlink_cmd 结构,只有连接器头和 w1_netlink_msg 结构,其中“len”字段为零,并填充了类型(事件类型之一)和 ID:可以是主机序的从设备唯一 ID 的 8 字节,或者是主设备的 ID(在添加到 w1 核心时分配给总线主设备)。
目前,对用户空间命令的回复只针对读取命令请求生成。一个回复精确地为一次 w1_netlink_cmd 读取请求生成。发送时不会组合回复 — 即典型的回复消息如下所示
[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;
对 W1_LIST_MASTERS 的回复应向用户空间发送一条消息,其中包含所有已注册主设备 ID 的列表,格式如下
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
每条消息最大为 4k 字节,因此如果主设备数量超过此限制,它将被拆分为多条消息。
W1 搜索和警报搜索命令。
请求
[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]
回复
[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]
每个头中的长度对应于其后数据的大小,因此 w1_netlink_cmd->len = N * 8;其中 N 是此消息中 ID 的数量。可以为零。
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 重置命令
[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]
命令状态回复¶
每个命令(无论是根命令、主命令还是带或不带 w1_netlink_cmd 结构的从命令)都将由 w1 核心进行“确认”。回复的格式与请求消息相同,只是长度参数不计入用户请求的数据,即读/写/触摸 IO 请求不包含数据,因此 w1_netlink_cmd.len 将为 0,w1_netlink_msg.len 将是 w1_netlink_cmd 结构的大小,cn_msg.len 将等于 struct w1_netlink_msg
和 struct w1_netlink_cmd
大小之和。如果回复是为不带 w1_netlink_cmd 的主命令或根命令生成的,则回复将只包含 cn_msg 和 w1_netlink_msg 结构。
w1_netlink_msg.status 字段将携带正错误值(例如 EINVAL)或成功时的零值。
每个结构中的所有其他字段将镜像请求消息中的相同参数(除了如上所述的长度)。
对于嵌入在 w1_netlink_msg 中的每个 w1_netlink_cmd,都会生成状态回复;如果没有 w1_netlink_cmd 结构,则为 w1_netlink_msg 生成回复。
每个 w1_netlink_msg 中的所有 w1_netlink_cmd 命令结构都将被处理,即使存在错误,也只有长度不匹配才会中断消息处理。
w1 核心收到新命令时的操作步骤¶
当收到新消息 (w1_netlink_msg) 时,w1 核心会根据 w1_netlink_msg.type 字段检测它是主请求还是从请求。然后搜索主设备或从设备。找到后,主设备(请求的或发现从设备的那个)会被锁定。如果请求从命令,则启动复位/选择过程以选择给定设备。
然后 w1_netlink_msg 中请求的所有操作都会逐一执行。如果命令需要回复(如读取命令),则在命令完成后发送。
当所有命令 (w1_netlink_cmd) 处理完毕后,主设备将被解锁,并开始处理下一个 w1_netlink_msg 头。
连接器 [1] 特定文档¶
每个连接器消息包含两个 u32 字段作为“地址”。w1 使用在 include/linux/connector.h 头文件中定义的 CN_W1_IDX 和 CN_W1_VAL。每条消息还包含序列号和确认号。事件消息的序列号是适当的总线主设备序列号,随着通过该主设备发送的每个事件消息而增加。用户空间请求的序列号由用户空间应用程序设置。回复的序列号与请求中的相同,确认号设置为 seq+1。
附加文档、源代码示例¶
http://www.ioremap.net/archive/w1
该归档文件包含用户空间应用程序 w1d.c,它使用读/写/搜索命令来操作总线上找到的所有主/从设备。