Linux I2C匯流排(一)I2C驅動框架

2022-08-28 12:57:11 字數 4470 閱讀 2114

copy from:

文章目錄

linux i2c匯流排(一)i2c驅動框架

一、linux i2c驅動的主要物件

1.1 i2c匯流排

1.2 i2c裝置

1.3 i2c驅動

1.4 i2c介面卡

二、linux i2c驅動框架

三、i2c驅動框架原始碼剖析

3.1 註冊i2c裝置

3.2 註冊i2c驅動

3.3 i2c介面卡的構建

3.4 i2c資料傳輸

一、linux i2c驅動的主要物件

1.1 i2c匯流排

i2c匯流排用於管理i2c裝置和i2c驅動,維護乙個裝置鍊錶和驅動鏈表,定義了裝置和驅動的匹配規則,定義了匹配成功後的行為,其在核心中的定義如下

struct bus_type i2c_bus_type = ;

1.2 i2c裝置

i2c裝置描述了i2c裝置的硬體資訊,例如i2c裝置的位址、i2c裝置在接在哪乙個i2c控制器上,其結構體定義如下

struct i2c_client ;

1.3 i2c驅動

i2c驅動是i2c裝置的驅動程式,用於匹配i2c裝置,其結構體定義如下

struct i2c_driver ;

1.4 i2c介面卡

i2c介面卡是soc上的i2c控制器的軟體抽象,可以通過其定義的演算法向硬體裝置傳輸資料,其結構體定義如下

struct i2c_adapter ;

其中的i2c_algorithm表示演算法,用於向硬體裝置傳輸資料,其定義如下

struct i2c_algorithm ;12

3456

78總結一下:i2c驅動的主要物件是i2c匯流排、i2c裝置、i2c驅動、i2c介面卡

i2c匯流排用於管理i2c裝置和i2c驅動

i2c裝置描述了i2c裝置的硬體資訊

i2c驅動是i2c裝置對應的驅動程式

i2c介面卡是soc上的i2c控制器,其定義了演算法,可以向i2c硬體裝置傳輸資料

其中直接面向編寫i2c裝置驅動的開發者的是i2c裝置和i2c驅動,i2c匯流排和i2c介面卡是幕後工作者

二、linux i2c驅動框架

i2c驅動框架可以分為四部分,i2c核心、i2c裝置、i2c驅動、i2c介面卡,其中i2c匯流排位於i2c核心中

可以用下圖來總結

i2c核心維護著一條i2c匯流排,提供了註冊i2c裝置、i2c驅動、i2c介面卡的介面

i2c匯流排維護著一條裝置鍊錶和驅動鏈表,當向i2c核心層註冊裝置時,會將其新增到匯流排的裝置鍊錶中,然後遍歷匯流排上的驅動鏈表,檢視二者是否匹配,如果匹配就呼叫驅動的probe函式

當註冊i2c驅動時,也會將其新增到i2c匯流排的驅動鏈表中,然後遍歷匯流排的裝置鍊錶,檢視二者是否匹配,如果匹配就呼叫驅動的probe函式

在i2c驅動程式中,通過i2c介面卡中的演算法向i2c硬體裝置傳輸資料

三、i2c驅動框架原始碼剖析

3.1 註冊i2c裝置

註冊i2c適配可以通過i2c_new_device,此函式會生成乙個i2c_client,指定對應的匯流排為i2c匯流排,然後向匯流排註冊裝置

struct i2c_client *

i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)

看一下其中的i2c_bus_type物件,其表示i2c匯流排,定義了裝置和驅動的匹配規則還有匹配成功後的行為

struct bus_type i2c_bus_type = ;

下面再來看看device_register向匯流排註冊裝置過程中會發生什麼

device_register首先會將裝置新增到匯流排的裝置鍊錶中,然後遍歷匯流排的驅動鏈表,判斷裝置和驅動是否匹配,如果匹配就呼叫驅動的probe函式,下面看一看原始碼分析

int device_register(struct device *dev)

int device_add(struct device *dev)

其中bus_add_device函式會將裝置新增到匯流排的裝置鍊錶中,如下

int bus_add_device(struct device *dev)12

34bus_probe_device函式會遍歷匯流排的驅動鏈表,如下

void bus_probe_device(struct device *dev)

1int device_attach(struct device *dev)

bus_for_each_drv(dev->bus, null, dev, __device_attach);會遍歷匯流排的驅動鏈表的每一項,然後呼叫__device_attach

static int __device_attach(struct device_driver *drv, void *data)

driver_match_device函式會判斷裝置和驅動是否匹配,如果匹配就呼叫driver_probe_device

首先來看一看driver_match_device函式的定義

static inline int driver_match_device(struct device_driver *drv,

struct device *dev)

發現它呼叫了匯流排的match函式,這裡的匯流排在註冊i2c裝置的時候已經被設定為i2c匯流排了,定義如下

struct bus_type i2c_bus_type = ;

所以這裡會呼叫到i2c_device_match函式,i2c_device_match會通過i2c驅動的id_table中每一的name和i2c裝置的name進行匹配

static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,

const struct i2c_client *client)

return null;

}static int i2c_device_match(struct device *dev, struct device_driver *drv)

如果匹配成功會呼叫driver_probe_device,下面再來看看driver_probe_device

driver_probe_device函式最終會先呼叫到i2c匯流排的probe函式,然後再呼叫i2c驅動的probe函式

int driver_probe_device(struct device_driver *drv, struct device *dev)

static int really_probe(struct device *dev, struct device_driver *drv)

匯流排的probe函式為i2c_device_probe,此函式會呼叫驅動的probe函式

static int i2c_device_probe(struct device *dev)

3.2 註冊i2c驅動

可以通過i2c_add_driver註冊i2c驅動,該函式會指定驅動對應的匯流排為i2c匯流排,然後向匯流排註冊驅動,

int i2c_register_driver(struct module *owner, struct i2c_driver *driver)

i2c_bus_type的定義如下

struct bus_type i2c_bus_type = ;

driver_register函式遍歷匯流排的裝置鍊錶進行操作,然後將驅動新增到匯流排的驅動鏈表中

int driver_register(struct device_driver *drv)

int bus_add_driver(struct device_driver *drv)

int driver_attach(struct device_driver *drv)

下面來看一看__driver_attach函式,此函式會判斷裝置和驅動是否匹配,如果匹配就呼叫驅動的probe函式

static int __driver_attach(struct device *dev, void *data)

這個過程和註冊裝置的過程是一樣的,這裡不再分析

3.3 i2c介面卡的構建

對於i2c介面卡,我們不討論它的註冊細節,我們看它是如何構建的

對於三星平台,在drivers\i2c\busses\i2c-s3c2410.c檔案中構建並註冊了i2c介面卡,這是三星平台i2c控制器的驅動

static const struct i2c_algorithm s3c24xx_i2c_algorithm = ;

static int s3c24xx_i2c_probe(struct platform_device *pdev)

其中的s3c24xx_i2c_algorithm中的s3c24xx_i2c_xfer就是通過操作暫存器來通過i2c控制器傳輸資料

3.4 i2c資料傳輸

上面介紹i2c資料傳輸是通過i2c介面卡完成的,下面來分析一下原始碼

在i2c驅動中,使用i2c_transfer來傳輸i2c資料,此函式肯定是通過i2c介面卡的演算法進行操作的,如下

linux i2c匯流排驅動

技術就是這樣,看一百遍不如做十遍。在對i2c做了乙個簡單的記錄之後發現比單看要理解更深刻,當然在記錄完i2c驅動之後,最希望自己能夠堅持自己實現at24c02的讀寫驅動與測試應用程式。由於是做記錄,少不了借用網路各種優秀資源,下圖是某部落格中找到的i2c框架。1 hardware層,cpu的i2c ...

Linux I2C匯流排框架 學習筆記

i2c框架結構 linux 核心中的 i2c 框架分為 3 部分,分別是 core bus driver devicedriver 其中 core 部分是框架中的框架,會呼叫 bus driver 和 device driver 中的函式和結構體進行 i2c 註冊 資料讀寫。我將其整理成為下面這張框...

i2c匯流排時序

一心想踏入linux device driver的世界,想著i2c匯流排相對於usb等其他匯流排較為簡單,就以i2c作為切入點,希望可以逐步理解ldd的設計思想,並能理解其裝置模型的概念。在此對近期於i2c匯流排及驅動原始碼的理解做備忘,以免徒勞。平台友善之臂s70 tiny6410 cpusams...