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 核心函式。

執行 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”

int w1_process_callbacks(struct w1_master *dev)

執行每個 dev->async_list 回撥條目

引數

struct w1_master *dev

w1_master 裝置

描述

必須持有 w1 主控器 list_mutex。

返回

如果存在要執行的命令,則為 1,否則為 0

drivers/w1/w1_family.c

允許註冊裝置系列操作。

int w1_register_family(struct w1_family *newf)

註冊裝置系列驅動程式

引數

struct w1_family *newf

要註冊的系列

void w1_unregister_family(struct w1_family *fent)

登出裝置系列驅動程式

引數

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_io.c

W1 輸入/輸出。

u8 w1_touch_bit(struct w1_master *dev, int bit)

生成一個寫 0 或寫 1 週期,並採樣電平。

引數

struct w1_master *dev

主裝置

int bit

0 - 寫入 0,1 - 寫入 0 並讀取電平

void w1_write_8(struct w1_master *dev, u8 byte)

寫入 8 位。

引數

struct w1_master *dev

主裝置

u8 byte

要寫入的位元組

u8 w1_triplet(struct w1_master *dev, int bdir)
  • 執行三元組操作 - 用於搜尋 ROM 地址。

引數

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 都被設定,則應重新啟動搜尋。

返回

位域 - 請參閱上文

u8 w1_read_8(struct w1_master *dev)

讀取 8 位。

引數

struct w1_master *dev

主裝置

返回

讀取的位元組

void w1_write_block(struct w1_master *dev, const u8 *buf, int len)

寫入一系列位元組。

引數

struct w1_master *dev

主裝置

const u8 *buf

指向要寫入的資料的指標

int len

要寫入的位元組數

void w1_touch_block(struct w1_master *dev, u8 *buf, int len)

觸控一系列位元組。

引數

struct w1_master *dev

主裝置

u8 *buf

指向要寫入的資料的指標

int len

要寫入的位元組數

u8 w1_read_block(struct w1_master *dev, u8 *buf, int len)

讀取一系列位元組。

引數

struct w1_master *dev

主裝置

u8 *buf

指向要填充的緩衝區的指標

int len

要讀取的位元組數

返回

讀取的位元組數

int w1_reset_bus(struct w1_master *dev)

發出匯流排復位序列。

引數

struct w1_master *dev

主裝置

返回

0 = 裝置存在,1 = 裝置不存在或出錯

int w1_reset_select_slave(struct w1_slave *sl)

復位並選擇從裝置

引數

struct w1_slave *sl

要選擇的從裝置

描述

復位匯流排,然後透過傳送跳過 ROM 命令或匹配 ROM 命令來選擇從裝置。如果總線上只註冊了一個裝置,則傳送跳過 ROM 命令。必須持有 w1 主裝置鎖。

返回

0 = 成功,其他任何值 = 錯誤

int w1_reset_resume_command(struct w1_master *dev)

恢復,而不是另一個匹配 ROM

引數

struct w1_master *dev

主裝置

描述

當多個從裝置中的一個從裝置的工作流程需要幾個連續的命令,並且每個命令之間需要復位時,此函式類似於對上次匹配的 ROM 執行復位,然後執行匹配 ROM。優點是跳過了匹配 ROM 步驟,而使用恢復命令。當然,從裝置必須支援該命令。

如果匯流排只有一個從裝置,傳統上跳過匹配 ROM 並執行 “跳過 ROM” 以提高效率。在多從裝置總線上,這當然不起作用,但恢復命令是次好的選擇。

必須持有 w1 主裝置鎖。

void w1_next_pullup(struct w1_master *dev, int delay)

註冊強上拉

引數

struct w1_master *dev

主裝置

int delay

以毫秒為單位的時間

描述

在下一次寫入操作後,輸出指定持續時間的強上拉。並非所有硬體都支援強上拉。不支援強上拉的硬體將在寫入操作後休眠給定的時間,而沒有強上拉。這是下一次寫入的單次請求,指定零將清除先前的請求。必須持有 w1 主裝置鎖。

返回

0 = 成功,其他任何值 = 錯誤

void w1_write_bit(struct w1_master *dev, int bit)

生成寫 0 或寫 1 週期。

引數

struct w1_master *dev

主裝置

int bit

要寫入的位

描述

僅當 dev->bus_master->touch_bit 為 NULL 時才呼叫

void w1_pre_write(struct w1_master *dev)

寫入前操作

引數

struct w1_master *dev

主裝置

描述

寫入前操作,目前僅支援強上拉。如果已請求強上拉並且硬體支援,則為強上拉配置硬體。

void w1_post_write(struct w1_master *dev)

寫入後選項

引數

struct w1_master *dev

主裝置

描述

寫入後操作,目前僅支援強上拉。如果請求了強上拉,則清除它(如果硬體支援),否則執行延遲。在任何一種情況下,都要清除請求。

u8 w1_read_bit(struct w1_master *dev)

生成寫 1 週期,並採樣電平。

引數

struct w1_master *dev

主裝置

描述

僅當 dev->bus_master->touch_bit 為 NULL 時才呼叫