I2C(Inter-Integrated Circuit)總線是一種由PHILIPS公司開發的兩線式串行總線,用於鏈接微控制器及其外圍設備。I2C總線產生於在80年代,最初爲音頻和視頻設 備開發,現在主要在服務器管理中使用,其中包括單個組件狀態的通訊。例如管理員可對各個組件進行查詢,以管理系統的配置或掌握組件的功能狀態,如電源和系 統風扇。可隨時監控內存、硬盤、網絡、系統溫度等多個參數,增長了系統的安全性,方便了管理。
簡單的I2C協議理解
一. 技術性能:
工做速率有100Kbit/s、400Kbit/s和3.4Mbit/s三種;
支持多機通信;
支持多主控模塊,但同一時刻只容許有一個主控;
由數據線SDA和時鐘SCL構成的串行總線;
每一個電路和模塊都有惟一的地址;
每一個器件可使用獨立電源;
鏈接到總線的接口數量只由總線電容是400pF的限制決定;
二. 基本工做原理:
SDA和SCL都是雙向線路,都經過一個電流源或上拉電阻鏈接到正的電源電壓。當總線空閒時,這兩條線路都是高電平。鏈接到總線的器件輸出級必須是漏極開路或集電極開路才能執行線與的功能。
以啓動信號START來掌管總線,以中止信號STOP來釋放總線;
每次通信以START開始,以STOP結束;
啓動信號START後緊接着發送一個地址字節,其中7位爲被控器件的地址碼,一位爲讀/寫控制位R/W,R/W位爲0表示由主控向被控器件寫數據,R/W爲1表示由主控從被控器件讀數據;
當主機發送了一個地址後,系統中的每一個器件都在起始條件後將頭7位與本身的地址比較,若是被控器件檢測到收到的地址與本身的地址相同,在第9個時鐘期間反饋應答信號;
每一個數據字節在傳送時都是高位(MSB)在前;
寫通信過程:
1. 主控在檢測到總線空閒的情況下,首先發送一個START信號掌管總線;
2. 發送一個地址字節(包括7位地址碼和一位R/W);
3. 當被控器件檢測到主控發送的地址與本身的地址相同時發送一個應答信號(ACK);
4. 主控收到ACK後開始發送第一個數據字節;
5. 被控器收到數據字節後發送一個ACK表示繼續傳送數據,發送NACK表示傳送數據結束;
6. 主控發送徹底部數據後,發送一箇中止位STOP,結束整個通信而且釋放總線;
讀通信過程:
1. 主控在檢測到總線空閒的情況下,首先發送一個START信號掌管總線;
2. 發送一個地址字節(包括7位地址碼和一位R/W);
3. 當被控器件檢測到主控發送的地址與本身的地址相同時發送一個應答信號(ACK);
4. 主控收到ACK後釋放數據總線,開始接收第一個數據字節;
5. 主控收到數據後發送ACK表示繼續傳送數據,發送NACK表示傳送數據結束;
6. 主控發送徹底部數據後,發送一箇中止位STOP,結束整個通信而且釋放總線;
四. 總線信號時序分析
1. 總線空閒狀態
SDA和SCL兩條信號線都處於高電平,即總線上全部的器件都釋放總線,兩條信號線各自的上拉電阻把電平拉高;
2. 啓動信號START
時鐘信號SCL保持高電平,數據信號SDA的電平被拉低(即負跳變)。啓動信號必須是跳變信號,並且在創建該信號前必修保證總線處於空閒狀態;
3. 中止信號STOP
時鐘信號SCL保持高電平,數據線被釋放,使得SDA返回高電平(即正跳變),中止信號也必須是跳變信號。
4. 數據傳送
SCL線呈現高電平期間,SDA線上的電平必須保持穩定,低電平表示0(此時的線電壓爲地電壓),高電平表示1(此時的電壓由元器件的VDD決定)。只有在SCL線爲低電平期間,SDA上的電平容許變化。
5. 應答信號ACK
I2C總線的數據都是以字節(8位)的方式傳送的,發送器件每發送一個字節以後,在時鐘的第9個脈衝期間釋放數據總線,由接收器發送一個ACK(把數據總線的電平拉低)來表示數據成功接收。
6. 無應答信號NACK
在時鐘的第9個脈衝期間發送器釋放數據總線,接收器不拉低數據總線表示一個NACK,NACK有兩種用途:
a. 通常表示接收器未成功接收數據字節;
b. 當接收器是主控器時,它收到最後一個字節後,應發送一個NACK信號,以通知被控發送器結束數據發送,並釋放總線,以便主控接收器發送一箇中止信號STOP。
五. 尋址約定
地址的分配方法有兩種:
1. 含CPU的智能器件,地址由軟件初始化時定義,但不能與其它的器件有衝突;
2. 不含CPU的非智能器件,由廠家在器件內部固化,不可改變。
高7位爲地址碼,其分爲兩部分:
1. 固定部分,不可改變,由廠家固化的統一地址;
2. 可編程部分,此部分由器件可以使用的管腳決定。例如,若是器件有4個固定的和3個可編程的地址位,那麼相同的總線上共能夠鏈接8個相同的器件(並不是全部器件均可以設定)。
若是有不懂的也能夠讀i2c規範,附件在文章末。
---------------------------------------------------------------------------------------------------------
註冊過程:
drivers/i2c/busses/i2c-qup.c(這是適配器的驅動)
platform_driver_register
qup_i2c_probe //在arch/arm/mach-msm/devices-msm8x60.c中定義了多少個gsbix_qup_i2c_resources就有多少個I2C Adapter,這個probe函數就會執行多少次
i2c_add_numbered_adapter
i2c_register_adapter
i2c_scan_static_board_info
i2c_new_device //arch/arm/mach-msm/board-xxx.c裏面定義的i2c設備在此註冊(這就是靜態註冊)
device_register //從這句開始便是設備模型的東西
device_add
bus_probe_device
device_attach
__device_attach //每註冊一個設備都會調用此函數,每註冊一個驅動也會調用__driver_attach,先註冊設備仍是驅動無硬性規定,不過驅動和設備是相偎相依的
driver_match_device //會根據device的name字段和bus上掛載的drivers鏈表中每個driver的id_table的name字段比較,若是相等即找到了本身的driver
driver_probe_device //若是相等調用此函數,不相等返回0。接下來會調用具體設備驅動的probe函數
drivers/i2c/i2c-dev.c
調用到的__process_new_driver-->i2c_do_add_adapter-->attach_adapter會真正執行,其餘地方調用此函數均不執行。每個i2c adapter會在/dev下生成一個字符設備。
這裏只寫了大概的流程,有興趣的讀者可自行跟蹤代碼流程。
---------------------------------------------------------------------------------------------------------
I2C Adapter/I2C BUS
gsbi是物理上實際存在的部件,它能夠模擬成i2c、gpio、spi、uart、sdio等,此i2c便是gsbi模擬的。這裏順便提下i2c adapter和i2c總線,二者都是物理上必須存在的,哪怕是其餘部件模擬的,例如GSBI模擬I2C,那麼GSBI這個部件是實際存在的。GSBI的 走線會與全部i2c設備互連,GSBI的接口便是i2c adapter,與其餘i2c設備互連的走線便是i2c總線。若是GSBI模擬成uart,那麼與uart的rx/tx pin鏈接的走線便是uart串口線。這是高通平臺的設計,換做其餘平臺,也必定會有一個i2c adapter或者說能夠模擬成i2c adapter的物理部件存在。猜想i2c adapter位於片上系統中,相似I/O接口的東西,沒有固件,驅動它的代碼便是各平臺相關的i2c adapter driver。GSBI的地址以及模擬成的qup i2c/uart的地址都是編址好的,在arch/arm/mach-msm/devices-msm8x60.c最開頭能夠看到這些物理地址。咱們知道 ARM是統一編址的,在代碼中要用ioremap把它映射到虛擬內存,這樣就能夠訪問了。
I2C規範.pdf