W1:达拉斯的单总线¶
- 作者:
David Fries
内核 W1 API 内部¶
include/linux/w1.h¶
W1 内核 API 函数。
-
struct w1_reg_num¶
分解出的从设备 ID
定义:
struct w1_reg_num {
#if defined(__LITTLE_ENDIAN_BITFIELD);
__u64 family:8,id:48, crc:8;
#elif defined(__BIG_ENDIAN_BITFIELD);
__u64 crc:8,id:48, family:8;
#else;
#error "Please fix <asm/byteorder.h>";
#endif;
};
成员
family
标识设备类型
id
与 family 一起是唯一的设备 ID
crc
其他字节的校验和
crc
其他字节的校验和
id
与 family 一起是唯一的设备 ID
family
标识设备类型
-
struct w1_slave¶
保存总线上的单个从设备
定义:
struct w1_slave {
struct module *owner;
unsigned char name[W1_MAXNAMELEN];
struct list_head w1_slave_entry;
struct w1_reg_num reg_num;
atomic_t refcnt;
int ttl;
unsigned long flags;
struct w1_master *master;
struct w1_family *family;
void *family_data;
struct device dev;
struct device *hwmon;
};
成员
owner
指向单线 “wire” 内核模块。
name
设备 ID 是 ascii。
w1_slave_entry
链表的数据
reg_num
二进制的从设备 ID
refcnt
引用计数,当为 0 时删除
ttl
每次搜索此从设备未找到时递减,在 0 时分离
flags
W1_SLAVE_ACTIVE W1_SLAVE_DETACH 的位标志
master
此从设备所在的总线
family
设备系列类型的模块
family_data
供系列模块使用的指针
dev
内核设备标识符
hwmon
指向 hwmon 设备的指针
-
struct w1_bus_master¶
可在总线主控器上执行的操作
定义:
struct w1_bus_master {
void *data;
u8 (*read_bit)(void *);
void (*write_bit)(void *, u8);
u8 (*touch_bit)(void *, u8);
u8 (*read_byte)(void *);
void (*write_byte)(void *, u8);
u8 (*read_block)(void *, u8 *, int);
void (*write_block)(void *, const u8 *, int);
u8 (*triplet)(void *, u8);
u8 (*reset_bus)(void *);
u8 (*set_pullup)(void *, int);
void (*search)(void *, struct w1_master *, u8, w1_slave_found_callback);
char *dev_id;
};
成员
data
以下所有函数中的第一个参数
read_bit
采样线路电平并返回读取的电平(0 或 1)
write_bit
设置线路电平
touch_bit
用于真正支持单总线协议的设备的最低级别函数。 touch_bit(0) = write-0 周期 touch_bit(1) = write-1 / read 周期 返回读取的位(0 或 1)
read_byte
读取一个字节。与 8 次 touch_bit(1) 调用相同。返回读取的字节
write_byte
写入一个字节。与 8 次 touch_bit(x) 调用相同。
read_block
与一系列 read_byte() 调用相同 返回读取的字节数
write_block
与一系列 write_byte() 调用相同
triplet
组合两次读取和一个智能写入,用于 ROM 搜索 返回 bit0=Id bit1=comp_id bit2=dir_taken
reset_bus
长时间的 write-0,用于检测存在脉冲 返回 -1=错误,0=设备存在,1=没有设备存在
set_pullup
输出指定时长的强上拉脉冲。返回 -1=错误,0=完成
search
真正优秀的硬件可以处理不同类型的 ROM 搜索,w1_master* 传递给找到的从设备回调。u8 是 search_type,W1_SEARCH 或 W1_ALARM_SEARCH
dev_id
可选的设备 ID 字符串,w1 从设备可以使用它来创建名称,然后建立与 w1 主控器的连接
注意
read_bit 和 write_bit 是非常低级别的函数,只应与不支持真正单总线操作的硬件一起使用,例如并行/串行端口。要么定义 read_bit 和 write_bit,要么至少定义 touch_bit 和 reset_bus。
-
enum w1_master_flags¶
w1_master.flags 中使用的位域
常量
W1_ABORT_SEARCH
在关闭时提前中止搜索
W1_WARN_MAX_COUNT
达到最大计数时限制警告
-
struct w1_master¶
每个总线主控器一个
定义:
struct w1_master {
struct list_head w1_master_entry;
struct module *owner;
unsigned char name[W1_MAXNAMELEN];
struct mutex list_mutex;
struct list_head slist;
struct list_head async_list;
int max_slave_count, slave_count;
unsigned long attempts;
int slave_ttl;
int initialized;
u32 id;
int search_count;
u64 search_id;
atomic_t refcnt;
void *priv;
int enable_pullup;
int pullup_duration;
long flags;
struct task_struct *thread;
struct mutex mutex;
struct mutex bus_mutex;
struct device_driver *driver;
struct device dev;
struct w1_bus_master *bus_master;
u32 seq;
};
成员
w1_master_entry
主控器链表
owner
模块所有者
name
动态分配总线名称
list_mutex
保护 slist 和 async_list
slist
从设备链表
async_list
要执行的 netlink 命令的链表
max_slave_count
一次搜索的最大从设备数量
slave_count
当前已知的从设备数量
attempts
运行的搜索次数
slave_ttl
从设备超时前的搜索次数
initialized
防止初始化/删除竞争条件
id
w1 总线编号
search_count
要运行的自动搜索次数,-1 表示无限制
search_id
允许继续搜索
refcnt
引用计数
priv
私有数据存储
enable_pullup
允许强上拉
pullup_duration
下一次强上拉的时间
flags
w1_master_flags 之一
thread
用于总线搜索和 netlink 命令的线程
mutex
保护大多数 w1_master
bus_mutex
保护并发总线访问
driver
sysfs 驱动程序
dev
sysfs 设备
bus_master
可用的 IO 操作
seq
用于 netlink 广播的序列号
-
struct w1_family_ops¶
系列类型的操作
定义:
struct w1_family_ops {
int (*add_slave)(struct w1_slave *sl);
void (*remove_slave)(struct w1_slave *sl);
const struct attribute_group **groups;
const struct hwmon_chip_info *chip_info;
};
成员
add_slave
add_slave
remove_slave
remove_slave
groups
sysfs 组
chip_info
指向 struct hwmon_chip_info 的指针
-
struct w1_family¶
引用计数的系列结构。
定义:
struct w1_family {
struct list_head family_entry;
u8 fid;
const struct w1_family_ops *fops;
const struct of_device_id *of_match_table;
atomic_t refcnt;
};
成员
family_entry
系列链表
fid
8 位系列标识符
fops
此系列的操作
of_match_table
开放固件匹配表
refcnt
引用计数器
-
module_w1_family¶
module_w1_family (__w1_family)
用于注册单总线系列的辅助宏
参数
__w1_family
w1_family 结构
描述
用于在模块 init/exit 中不做任何特殊处理的单总线系列的辅助宏。这消除了大量样板代码。每个模块只能使用此宏一次,并且调用它会替换 module_init()
和 module_exit()
drivers/w1/w1.c¶
W1 核心函数。
-
void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb)¶
执行 ROM 搜索并注册找到的任何设备。
参数
struct w1_master *dev
要搜索的主控器设备
u8 search_type
W1_SEARCH 用于搜索所有设备,或 W1_ALARM_SEARCH 用于仅返回处于报警状态的设备
w1_slave_found_callback cb
找到设备时要调用的函数
描述
单总线搜索是一个简单的二叉树搜索。对于地址的每一位,我们读取两位并写入一位。写入的位将使所有与该位不匹配的设备进入睡眠状态。当两次读取不同时,方向选择是显而易见的。当两位均为 0 时,我们必须选择一条路径。当我们可以扫描所有 64 位而无需选择路径时,我们就完成了。
请参阅 www.maxim-ic.com 上的 “Application note 187 1-wire search algorithm”
参数
struct w1_master *dev
w1_master 设备
描述
必须持有 w1 主控器 list_mutex。
返回
如果存在要执行的命令,则为 1,否则为 0
drivers/w1/w1_family.c¶
允许注册设备系列操作。
参数
struct w1_family *newf
要注册的系列
参数
struct w1_family *fent
要注销的系列
drivers/w1/w1_internal.h¶
用于主控器设备的 W1 内部初始化。
-
struct w1_async_cmd¶
从 w1_process kthread 执行回调
定义:
struct w1_async_cmd {
struct list_head async_entry;
void (*cb)(struct w1_master *dev, struct w1_async_cmd *async_cmd);
};
成员
async_entry
链接条目
cb
回调函数,必须在返回之前 list_del 和销毁此列表
描述
当插入到 w1_master async_list 中时,w1_process 将执行回调。将此嵌入到具有命令详细信息的结构中。
drivers/w1/w1_int.c¶
用于主控器设备的 W1 内部初始化。
-
int w1_add_master_device(struct w1_bus_master *master)¶
注册新的主控器设备
参数
struct w1_bus_master *master
要注册的主控器总线设备
-
void w1_remove_master_device(struct w1_bus_master *bm)¶
注销主控器设备
参数
struct w1_bus_master *bm
要删除的主控器总线设备
drivers/w1/w1_netlink.h¶
W1 外部 netlink API 结构和命令。
-
enum w1_cn_msg_flags¶
struct cn_msg.flags 的位域标志
常量
W1_CN_BUNDLE
请求将回复捆绑到更少的消息中。准备好处理一个数据包中的多个 struct cn_msg、
struct w1_netlink_msg
和struct w1_netlink_cmd
。
-
enum w1_netlink_message_types¶
消息类型
常量
W1_SLAVE_ADD
从设备已添加的通知
W1_SLAVE_REMOVE
从设备已删除的通知
W1_MASTER_ADD
新的总线主控器已添加的通知
W1_MASTER_REMOVE
总线主控器已删除的通知
W1_MASTER_CMD
启动特定主控器上的操作
W1_SLAVE_CMD
发送复位,选择从设备,然后执行读/写/触摸操作
W1_LIST_MASTERS
用于确定总线主控器标识符
-
struct w1_netlink_msg¶
保存 w1 消息类型、ID 和结果
定义:
struct w1_netlink_msg {
__u8 type;
__u8 status;
__u16 len;
union {
__u8 id[8];
struct w1_mst {
__u32 id;
__u32 res;
} mst;
} id;
__u8 data[];
};
成员
type
status
内核反馈,成功为 0 或 errno 失败值
len
w1_netlink_msg 之后的数据长度
id
联合保存总线主控器 ID (msg.id) 和从设备 ID (id[8])。
id.id
从设备 ID (8 字节)
id.mst
总线主控器标识
id.mst.id
总线主控器 ID
id.mst.res
总线主控器保留
data
任何后续数据的起始地址
描述
通过 netlink 进行 w1 通信的基础消息结构。netlink 连接器的数据序列为:struct nlmsghdr
, struct cn_msg,然后是一个或多个 struct w1_netlink_msg
(每个结构体带有可选数据)。
-
enum w1_commands¶
可用于主设备或从设备操作的命令
常量
W1_CMD_READ
读取 len 字节
W1_CMD_WRITE
写入 len 字节
W1_CMD_SEARCH
启动标准搜索,仅返回在搜索期间找到的从设备
W1_CMD_ALARM_SEARCH
搜索当前正在报警的设备
W1_CMD_TOUCH
触摸一系列字节。
W1_CMD_RESET
在给定的主设备上发送总线复位信号
W1_CMD_SLAVE_ADD
将从设备添加到给定的主设备,从设备 ID (8 字节) 位于 data[0]
W1_CMD_SLAVE_REMOVE
从给定的主设备移除从设备,从设备 ID (8 字节) 位于 data[0]
W1_CMD_LIST_SLAVES
列出注册到此主设备上的从设备
W1_CMD_MAX
可用命令的数量
-
struct w1_netlink_cmd¶
保存命令和数据
定义:
struct w1_netlink_cmd {
__u8 cmd;
__u8 res;
__u16 len;
__u8 data[];
};
成员
cmd
enum w1_commands
中的一个res
保留
len
w1_netlink_cmd 之后的数据长度
data
任何后续数据的起始地址
描述
一个或多个 struct w1_netlink_cmd
从 w1_netlink_msg.data 开始放置,每个结构体带有可选数据。
drivers/w1/w1_io.c¶
W1 输入/输出。
参数
struct w1_master *dev
主设备
int bit
0 - 写入 0,1 - 写入 0 并读取电平
参数
struct w1_master *dev
主设备
u8 byte
要写入的字节
参数
struct w1_master *dev
主设备
int bdir
如果 id_bit 和 comp_bit 都为 0,则写入该位
描述
- 返回值
bit 0 = id_bit,bit 1 = comp_bit,bit 2 = dir_taken
如果 bit 0 和 bit 1 都被设置,则应重新启动搜索。
返回
位域 - 请参阅上文
参数
struct w1_master *dev
主设备
返回
读取的字节
参数
struct w1_master *dev
主设备
const u8 *buf
指向要写入的数据的指针
int len
要写入的字节数
参数
struct w1_master *dev
主设备
u8 *buf
指向要写入的数据的指针
int len
要写入的字节数
参数
struct w1_master *dev
主设备
u8 *buf
指向要填充的缓冲区的指针
int len
要读取的字节数
返回
读取的字节数
参数
struct w1_master *dev
主设备
返回
0 = 设备存在,1 = 设备不存在或出错
参数
struct w1_slave *sl
要选择的从设备
描述
复位总线,然后通过发送跳过 ROM 命令或匹配 ROM 命令来选择从设备。如果总线上只注册了一个设备,则发送跳过 ROM 命令。必须持有 w1 主设备锁。
返回
0 = 成功,其他任何值 = 错误
参数
struct w1_master *dev
主设备
描述
当多个从设备中的一个从设备的工作流程需要几个连续的命令,并且每个命令之间需要复位时,此函数类似于对上次匹配的 ROM 执行复位,然后执行匹配 ROM。优点是跳过了匹配 ROM 步骤,而使用恢复命令。当然,从设备必须支持该命令。
如果总线只有一个从设备,传统上跳过匹配 ROM 并执行 “跳过 ROM” 以提高效率。在多从设备总线上,这当然不起作用,但恢复命令是次好的选择。
必须持有 w1 主设备锁。
参数
struct w1_master *dev
主设备
int delay
以毫秒为单位的时间
描述
在下一次写入操作后,输出指定持续时间的强上拉。并非所有硬件都支持强上拉。不支持强上拉的硬件将在写入操作后休眠给定的时间,而没有强上拉。这是下一次写入的单次请求,指定零将清除先前的请求。必须持有 w1 主设备锁。
返回
0 = 成功,其他任何值 = 错误
参数
struct w1_master *dev
主设备
int bit
要写入的位
描述
仅当 dev->bus_master->touch_bit 为 NULL 时才调用
参数
struct w1_master *dev
主设备
描述
写入前操作,目前仅支持强上拉。如果已请求强上拉并且硬件支持,则为强上拉配置硬件。
参数
struct w1_master *dev
主设备
描述
写入后操作,目前仅支持强上拉。如果请求了强上拉,则清除它(如果硬件支持),否则执行延迟。在任何一种情况下,都要清除请求。
参数
struct w1_master *dev
主设备
描述
仅当 dev->bus_master->touch_bit 为 NULL 时才调用