天天看點

linux中關于i2c的指令,Linux I2C framework(1)_概述

Linux I2C framework(1)_概述

作者:wowo 釋出于:2016-2-14 22:01

分類:通信類協定

1. 前言

I2C協定是嵌入式系統中廣泛使用的一類通信協定,主要用于CPU和各種外設之間的低速資料通信。Linux kernel使用I2C framework抽象、管理相應的資源,并以各種形式,向各類使用者提供API。另外,作為總線(bus)的一種,I2C framework的實作展現了linux裝置模型的精髓,值得研究與學習。這就是攥寫“Linux I2C framework”系列文章的緣由和目的。

按照分析各類framework的老規矩,蝸蝸會從4個角度分4篇文章介紹I2C framework: 1)Linux I2C framework的整體介紹,包括基礎知識、軟體架構、API彙整等。就是本文。

2)從Provider的角度,介紹怎麼借助I2C framework管理I2C相關的SOC資源。換句話說,就是怎麼編寫一個I2C driver。具體可參考“Linux I2C framework(2)_I2C provider”。

3)從Consumer的角度,介紹I2C framework為使用者提供了哪些功能、哪些API,以及怎樣利用I2C framework編寫程式。具體可參考“Linux I2C framework(3)_I2C consumer”。

4)從内部實作的角度,分析I2C framework的實作邏輯。具體可參考“Linux I2C framework(4)_I2C core”。

2. I2C的總線拓撲

I2C是總線的一種,其硬體拓撲如下圖所示:

linux中關于i2c的指令,Linux I2C framework(1)_概述

圖檔1 I2C H/W topology

關于I2C的硬體拓撲,相信驅動工程師都很熟悉,這裡就不過多描述了,但有一點要強調: 我們都知道,I2C協定是主從式的,包括master(主裝置)和slave(從裝置),而Linux kernel的I2C framework隻抽象了I2C master有關的功能,換句話說,linux kernel有這樣的一個假設:

所有運作linux kernel的裝置,在I2C總線裡面,都是I2C master(至于I2C slave,抱歉,kernel不管!)。

正是基于這樣的假設,linux I2C framework才成為目前的樣子,具體可參考本文後續的描述。

linux kernel I2C framework使用如下的軟體拓撲抽象I2C硬體(我們可以一起領會一下其中的“裝置模型”思想):

linux中關于i2c的指令,Linux I2C framework(1)_概述

圖檔2 I2C S/W topology 1)platform bus(/sys/bus/platform)是驅動工程師常見的bus,用于挂載和CPU通過系統總線連接配接的各類外設。在I2C framework中,I2C控制器直接從屬于platform bus,我們在linux kernel中常說的I2C driver,都是指I2C controller driver,都是以platform driver的形式存在,當然,對應的控制器是platform device。

2)與此同時,kernel抽象出I2C bus(/sys/bus/i2c),用于挂載和I2C controller通過I2C總線連接配接的各個I2C slave device。

3)比較特殊的地方是,I2C core使用一個虛拟實體----I2C adapter,抽象I2C controller有關的功能(主要是資料的收發),I2C adapter也挂載在I2C bus上。

4)I2C adapter和I2C slave device都挂載在I2C bus上,就可以友善的進行Master(I2C adapter)和Slave之間的比對操作,并通過I2C core提供的統一接口,通路I2C salve device,進行資料的收發。

5)以上各實體在sysfs中的位置,已經在“圖檔2”中通過紅色字型标注,大家可自行了解。

3. 軟體架構

基于第2章所述的總線拓撲,Linux kernel抽象出如下的軟體架構:

linux中關于i2c的指令,Linux I2C framework(1)_概述

圖檔3 I2C framework software architecture 1)I2C framework的最終目标,是提供一種“通路I2C slave devices”的方法。由于這些slave devices由I2C controller控制,因而主要由I2C controller驅動實作這一目标。

2)經過I2C framework的抽象,consumer可以不用關心I2C總線的技術細節,隻需要通過簡單的API,就可以與slave devices進行資料互動。正常情況下,consumer是位于核心态的其它driver(如HDMI driver、touch screen driver等等)。與此同時,I2C framework也通過字元裝置向使用者空間提供類似的接口,使用者空間程式可以通過該接口通路slave devices。

3)在I2C framework内部,有I2C core、I2C busses、I2C algos和I2C muxes四個子產品。

4)I2C core使用I2C adapter和I2C algorithm兩個子子產品抽象I2C controller的功能,使用I2C client和I2C driver抽象I2C slave device的功能(對應裝置模型中的device和device driver)。另外,基于I2C協定,通過smbus子產品實作SMBus(System Management Bus,系統管理總線)的功能。

5)I2C busses是各個I2C controller drivers的集合,位于drivers/i2c/busses/目錄下,驅動工程師常說的“I2C driver”就是指它們。

6)I2C algos包含了一些通用的I2C algorithm,所謂的algorithm,是指I2C協定包的生成方法,進而組合成I2C的read/write指令,一般情況下,都是由硬體實作,不需要特别關注該目錄。

7)I2C muxes用于實作I2C bus的多路複用功能,屬于奇葩的冷門功能,暫不過多介紹。

4. I2C有關的軟體流程總結

TODO(會在後續文章完成之後再回來補充)。

原創文章,轉發請注明出處。蝸窩科技,www.wowotech.net。

linux中關于i2c的指令,Linux I2C framework(1)_概述

評論:

x

2019-01-09 17:49

咨詢一下各位大神,Linux kernel 4.1.15,兩個程序A和B同時通路同一個SPI總線,會導緻這兩個程序退出嗎?同一個SPI總線 但是有主和從

是不是有可能A通路主SPI,B通路從SPI,然後B再請求主的,A再請求從的 兩邊都沒釋放,導緻的程序僵死了?

2019-01-10 19:26

@x:這和SPI driver的實作有關,當然,一個好的driver不會出現這種問題。

2016-03-28 19:31

I2C slave device driver和I2C client driver在核心代碼中有不同的含義,圖檔3中使用的術語似乎和核心不一緻

2016-03-28 21:58

@hello_world:kernel中有“I2C slave device driver”這個概念嗎?這篇文章中我有意回避了I2C client這個概念,因為覺得它不直覺,不好了解。從本質上來說,I2C client應該是I2C slave device在本地的一個“映像”(這讓我想起了bluez中device的概念)。

2016-03-29 09:01

@wowo:對的i2c client driver其實是驅動I2C 總線上的slave裝置的,是以其實i2c slave driver更順一些,但是,核心代碼其實都是用i2c client的概念。是以,我覺得圖檔3應該表述這一部分的内容的:即i2c client driver子產品應該和i2c slave HW block之間有虛線,表示這兩個子產品之間的關系。BTW,我覺的圖檔3應該可以有更好的表達。

即便是有了I2C slave device的支援(類似USB 的gadget driver),實際上仍然用struct i2c_client來抽象這個slave裝置。

最後:我們覺得我們還是鎖定一個核心版本好了,我建議是4.4.y的核心版本,大家都圍繞這個版本讨論。

2016-03-28 19:19

探讨一個問題啊,我說的也不一定對。

我感覺I2C algos和I2C buses子產品的關系不是平行關系,毫無疑問,I2C buses子產品(I2C controller driver)子產品是和底層硬體相關的,所有和具體的I2C controller的互動都是通過I2C busses子產品進行,I2C algos是和硬體無關的(也不能這麼說,應該說是和硬體操作序列有關)。I2C algos對底層硬體的操作都是通過I2C busses中的adapter的callback完成的,或者說,adapter提供了最底層的通信機制,不同的algos可以利用它實作具體的I2C的資料傳輸服務。

2016-03-28 21:52

@hello_world:這個還真不一定,我覺得kernel的設計初衷,是盡可能的複用I2C algos,也就是說,将adapter和algos分離。當然,現狀是,adapter和algos基本上一一對應了,因而algos似乎變成adapter的一個屬性(從屬關系)了。

2016-03-29 09:04

@wowo:的确,algos像是adapter的一個lib,不過反正在嵌入式的場景中,每一個adapter都有自己獨特的algos,我們沒有必要争論它們之間的關系,algos,就讓它随風飄散吧,^_^

2016-03-28 18:54

所有運作linux kernel的裝置,在I2C總線裡面,都是I2C master(至于I2C slave,抱歉,kernel不管!)。

------------------------------------------

為什麼不管呢?其實隻要有需求,就應該提供支援的。在4.4.6的核心中,已經增加了對I2C slave的支援,同時也複用了目前的I2C framework的代碼。

另外,I2C實體拓撲(圖檔1)以及關于I2C和裝置模型那部分(圖檔2),基本上四着眼于嵌入式平台,其實可以更通用一些。另外,圖檔2中的CPU block的出現容易誤導的,或者建議增加更多的文字描述,對于I2C和裝置模型之間的關系可以多寫一些。

2016-03-28 21:47

@hello_world:4.4.6是3/16才釋出啊,我還沒看呢!已經支援I2C slave了嗎?看來kernel還是妥協了。其實我覺得,一個跑linux kernel的裝置,當做I2C slave的可能性不大,還真不需要管它。

通用一些具體指什麼意思呢?加入slave?還是其它?

2016-03-29 08:50

@wowo:具體是哪一個版本加上的我沒有查證,不過這不重要,重要的是開源社群增加i2c slave的支援也是很糾結的(就像你說的,其實大部分的運作linux的裝置應該都是I2C master),在log中有這樣的描述:最終,我們還是增加了slave的支援......

增加slave的支援是指其他的子產品可以調用i2c core提供的i2c_slave_register/i2c_slave_unregister來注冊一個或者登出一個i2c的slave裝置。一旦注冊了slave裝置,底層的adapter要切換到slave mode。完成這些操作之後,該i2c slave裝置可以響應來自對端i2c master裝置的各種指令和資料了。

2016-03-04 22:05

确實i2c是一個比較清晰的framework,記得第一個接觸的驅動就是i2c slave,清晰的記得當時的迷茫,對各種資料結構的不解,現在看來感覺清楚了不少。

2016-03-05 17:55

@electrlife:是啊,I2C相對比較簡單,不用當做了解裝置模型的一個例子,也挺不錯的。

Jordon Wu

2016-02-19 15:05

@wowo,

請教下,對于I2C,可以在userspace的application裡進行中斷嗎?謝謝

2016-02-19 15:34

@Jordon Wu:我不太明白您的意思,對I2C來說,它負責資料接收,中斷是在Kernel處理的。

我們講的在使用者空間通路,隻是應用程式通過I2C Framework提供的字元裝置接口,通路I2C slave device(資料收發)而已,應該不需要關心中斷。

2016-02-19 16:52

@wowo:@wowo,

是的,是在應用程式中通過字元裝置接口open/read/write資料到slave device,這樣做發資料沒問題,但是收資料需要while循環去讀或者poll去查詢是否有資料可讀。我想知道有沒有辦法把kernel的有資料可接受這個中斷暴露給userspace的應用程式?這樣應用程式隻在這個中斷來了之後才去度slave device的資料。

2016-02-19 17:06

@jordonwu:我大概了解的你的想法。

1.首先中斷隻能在kenerl空間處理,這個是必須的。如果想實作此類模型,一個途徑是應用程式調用read/write,在kernel空間中用諸如wait_even_xx()陷入睡眠,當有中斷來臨時,在ISR中wake_up_xx()來喚醒之前陷入睡眠的程序。

2.i2c的bus驅動已經實作了上述模型,你可以參考drivers/i2c/busess/下的各種driver。也就是說,在應用程式中位元組裝置接口的read/write/ioctl都是同步的。

2016-02-19 17:13

@jordonwu:建議不這樣做,poll已經夠用了,如果poll解決不了,估計是應用層的設計有待商榷。

2016-02-15 10:26

Linux下的i2c framework還是比較直覺的。。不像usb mmc那樣“蕩氣回腸” ;)

這篇比較概括淺顯,期待後續

情人節還在發文章,wowo你可以啊,不擔心跪鍵盤?哈哈

2016-02-15 13:09

@雲:是的,I2C Framework還是比較清晰易懂的。

哈哈,感情好的話哪天都是節,不怕不怕~~~

發表評論:

昵稱

郵件位址 (選填)

個人首頁 (選填)

linux中關于i2c的指令,Linux I2C framework(1)_概述