新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 嵌入式Linux下的I2C設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)

嵌入式Linux下的I2C設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)

作者: 時(shí)間:2014-01-22 來源:網(wǎng)絡(luò) 收藏

  0 引言

  由于I2C總線的通用性,作為一款優(yōu)秀的操作系統(tǒng),也必須要對(duì)其要有很好的支持。在內(nèi)核源碼中對(duì)I2C總線的驅(qū)動(dòng)是基于總線設(shè)備驅(qū)動(dòng)模型的,其用到了特殊的幾個(gè)數(shù)據(jù)結(jié)構(gòu),對(duì)I2C總線協(xié)議進(jìn)行了更抽象更通用的定義,極大的增加了設(shè)備驅(qū)動(dòng)的可移植性。要編寫出自己的I2C 設(shè)備,必須對(duì)這種內(nèi)核I2C總線驅(qū)動(dòng)的架構(gòu)有深刻的理解。

  1 I2C總線的硬件構(gòu)成

  I2C 總線協(xié)議只有兩條總線線路,一條是串行數(shù)據(jù)線(SDA),一條是串行時(shí)鐘線(SCL)。SDA 負(fù)責(zé)數(shù)據(jù)的傳輸,SCL 負(fù)責(zé)數(shù)據(jù)傳輸?shù)臅r(shí)鐘同步。I2C 設(shè)備通過這兩條總線連接到處理器的I2C總線控制器上,不同設(shè)備之間通過7 位地址來區(qū)別,而且數(shù)據(jù)的傳輸是雙向的,方向的確定由1位二進(jìn)制數(shù)確定,地址位加方向位是操作I2C 設(shè)備的惟一標(biāo)示,I2C 設(shè)備與CPU 的連接如圖1所示。

嵌入式Linux下的I2C設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)

  I2C 總線上有3 種類型的信號(hào),分別是:開始信號(hào),結(jié)束信號(hào)和應(yīng)答信號(hào)。這些信號(hào)都是由SDA和SCL上的電平變化來表示的。

  開始信號(hào)(S):當(dāng)SCL為高電平時(shí),SDA由高電平向低電平跳變,表示開始傳輸數(shù)據(jù)。

  結(jié)束信號(hào)(P):當(dāng)SCL為高電平時(shí),SDAY由低電平向高電平跳變,表示結(jié)束傳輸數(shù)據(jù)。

  相應(yīng)信號(hào)(ACK):從機(jī)接收到8位數(shù)據(jù)后,在第9個(gè)時(shí)鐘周期,拉低SDA電平,表示已經(jīng)接收到數(shù)據(jù)。

  當(dāng)總線空閑時(shí),SDA 和SCL 都處于高電平,主機(jī)檢測(cè)到總線空閑就可以向從機(jī)發(fā)送數(shù)據(jù)。主機(jī)首先發(fā)送開始信號(hào)S,接著發(fā)出8位數(shù)據(jù)(包括前7位的從機(jī)地址和1 為的方向位),然后等待從機(jī)發(fā)回確認(rèn)信號(hào)ACK.

  當(dāng)?shù)?位為0時(shí),表示向從機(jī)傳輸數(shù)據(jù),主機(jī)收到確認(rèn)信號(hào)后就可以連續(xù)的向從機(jī)寫入8 位數(shù)據(jù);當(dāng)?shù)? 位為1時(shí),表示向從讀取數(shù)據(jù),這時(shí)主機(jī)就可以接收來自從機(jī)的一系列數(shù)據(jù)。最后當(dāng)總個(gè)數(shù)據(jù)傳輸過程完成后,由主機(jī)發(fā)送結(jié)束信號(hào)P,表示本次的數(shù)據(jù)傳輸完成。

  2 的層次結(jié)構(gòu)

  因?yàn)?a class="contentlabel" href="http://butianyuan.cn/news/listbylabel/label/I2C設(shè)備">I2C設(shè)備的種類繁多,如果為每一款都編寫一個(gè)驅(qū)動(dòng)程序,顯然不太現(xiàn)實(shí)也不太可能做到。所以,Linux中是對(duì)I2C 設(shè)備驅(qū)動(dòng)采取了層次化處理,分為總線層和設(shè)備層。將I2C設(shè)備驅(qū)動(dòng)的一些共同屬性抽象起來歸結(jié)起來作為總線層,而將具體I2C設(shè)備特殊操作作為設(shè)備層。在Linux中I2C設(shè)備驅(qū)動(dòng)中用到的數(shù)據(jù)結(jié)構(gòu)[4,7-8]的關(guān)系如圖2 所示。關(guān)于這部分代碼位于Linux內(nèi)核源碼樹的/driver/i2c中。

嵌入式Linux下的I2C設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)

  理解這層次結(jié)構(gòu)重點(diǎn)是要理解4個(gè)數(shù)據(jù)結(jié)構(gòu),分別是屬于設(shè)備層的i2c_driver 與i2c_client,屬于總線層的i2c_adapter與i2c_algorithm.下面分別對(duì)這四個(gè)數(shù)據(jù)結(jié)構(gòu)做簡(jiǎn)要的說明。

  struct i2c_driver:具體的每一個(gè)I2C設(shè)備都應(yīng)該對(duì)應(yīng)著的一個(gè)驅(qū)動(dòng),這個(gè)結(jié)構(gòu)體里面定義了Linux設(shè)備模型中用于I2C 總線管理的一系列函數(shù)指針和I2C 設(shè)備的信息。其中最重要的兩個(gè)成員是適配器檢測(cè)函數(shù)指針at-tach_adapter,和設(shè)備ID表id_table.

  struct i2c_client:一個(gè)連接在SDA 和SCL 總線上的具體設(shè)備是由i2c_client結(jié)構(gòu)體描述的,定義了兩個(gè)成員變量表示這個(gè)具體設(shè)備所對(duì)應(yīng)的適配器和驅(qū)動(dòng)。

  struct i2c_adapter:此結(jié)構(gòu)體表示CPU 里面具體的I2C控制器,本質(zhì)上也是對(duì)應(yīng)著一個(gè)物理設(shè)備,其中最要的成員變量是指向適配器驅(qū)動(dòng)的程序的algo 結(jié)構(gòu)體指針。

  struct i2c_algorithm:里面定義了具體適配器驅(qū)動(dòng)程序的函數(shù)指針。特別是master_xfer函數(shù)指針,這個(gè)函數(shù)實(shí)現(xiàn)了適配器最底層的操作方法,也是I2C設(shè)備驅(qū)動(dòng)中總線層里面要編寫的重要函數(shù)。

linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

上一頁(yè) 1 2 下一頁(yè)

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉