i2c總線是一種十分常見的板級總線,本文以linux3.14.0為參考, 討論Linux中的i2c驅動模型并利用這個模型寫一個mpu6050的驅動, 最后在應用層將mpu6050中的原始數(shù)據(jù)讀取出來
i2c子系統(tǒng)框架
下圖就是我理解的i2c驅動框架示意圖, 類似中斷子系統(tǒng), i2c子系統(tǒng)中也使用一個對象來描述一個物理實體, 設備對象與驅動分離, 驅動結合設備對象對硬件設備的描述才可以驅動一個具體的物理設備, 體現(xiàn)了分離的設計思想, 實現(xiàn)了代碼的復用, 比如:
一個i2c控制器就對應一個i2c_board_info, 它驅動就是s3c2410_i2c_driver, 他們通過platform_bus_type協(xié)調工作。
一個i2c總線上的設備就對應內核中的一個i2c_client類型的對象, 它的驅動就是的i2c_driver, 二者通過i2c_bus_type協(xié)調工作。
同樣是抽象的思路, 對于i2c總線本身, 內核也使用i2c_bus_type來描述。
事實上, 對于任何一種總線, 內核都有一個bus_type類型的對象與之對應, 但是platform_bus_type并沒有對應的實際的物理總線, 這也就是platform總線也叫虛擬總線的原因.
除了分離,i2c子系統(tǒng)也體現(xiàn)的軟件分層的設計思想, 整個i2c子系統(tǒng)由3層構成:設備驅動層--i2c核心--控制器驅動
除了經典的分層與分離模型,我們也可以看到一個有意思的現(xiàn)象——Linux 的應用程序不但可以通過設備驅動來訪問i2c從設備,還可以通過一個并沒有直接掛接到i2c_bus_type的i2c_cleint來找到主機控制器進而訪問任意一個i2c設備, 這是怎么回事呢? 我會在下一篇說^-^
核心結構和方法簡述
核心結構
i2c_adapter對象實現(xiàn)了一組通過一個i2c控制器發(fā)送消息的所有信息, 包括時序, 地址等等, 它被i2c主機驅動創(chuàng)建, 通過i2c-core.c和i2c_client和i2c_driver聯(lián)系到一起, 這樣設備端驅動就可以通過其中的方法以及i2c物理控制器來和一個i2c總線的物理設備進行交互
i2c_algorithm描述一個i2c主機的發(fā)送時序的信息,該類的對象algo是i2c_adapter的一個域
i2c_client描述一個掛接在硬件i2c總線上的設備的設備信息,即i2c設備的設備對象
i2c_driver描述一個掛接在硬件i2c總線上的設備的驅動方法,即i2c設備的驅動對象,通過i2c_bus_type和設備對象相連
i2c_msg描述一個在設備端和主機端之間進行流動的數(shù)據(jù), 在設備驅動中打包并通過i2c_transfer()發(fā)送。相當于skbuf之于網(wǎng)絡設備,urb之于USB設備。