【驱动】I2C驱动分析(二)-驱动框架
I2C驅(qū)動框架簡介
I2C 驅(qū)動屬于總線-設(shè)備-驅(qū)動模型的,與I2C總線設(shè)備驅(qū)動模型相比,大體框架是一樣,系統(tǒng)的整體框架如下所示。
- 最上層是應(yīng)用層,在應(yīng)用層用戶可以直接用open read write對設(shè)備進行操作,
- 往下是設(shè)備驅(qū)動層,這個就是外圍的比如一些用I2C總線連接到SOC的傳感器或者EEPROM的驅(qū)動程序,這個一般由普通驅(qū)動工程師負責,
- 再往下的I2C-Core是核心層,這個是Linux內(nèi)核源碼里面本來就有的,這里面主要是一些驅(qū)動和設(shè)備的注冊函數(shù)以及i2c_transfer函數(shù),
- 再往下就是I2C控制器驅(qū)動,這個一般是由芯片原廠的程序員負責編寫,
- 再往下就是具體的硬件了。
用戶空間
/dev/i2c-*提供了用戶空間與內(nèi)核空間之間的接口,允許用戶空間應(yīng)用程序通過設(shè)備文件(如)與I2C驅(qū)動進行通信。用戶空間應(yīng)用程序可以使用標準的I2C系統(tǒng)調(diào)用(如ioctl())來發(fā)送和接收I2C消息。
在Linux內(nèi)核代碼文件/include/linux/i2c-dev.c中針對每個適配器生成一個主設(shè)備號為89的設(shè)備節(jié)點,實現(xiàn)了文件操作接口,用戶空間可以通過i2c設(shè)備節(jié)點訪問i2c適配器。適配器的編號從0開始,和適配器的設(shè)備節(jié)點的次設(shè)備號相同。
i2c適配器的設(shè)備節(jié)點是/dev/i2c-x,其中x是數(shù)字,代表適配器的編號。由于適配器編號是動態(tài)分配的(和注冊次序有關(guān)),所以想了解哪一個適配器對應(yīng)什么編號,可以查看/sys/class/i2c-dev/目錄下的文件內(nèi)容。
內(nèi)核空間
I2C driver
I2C設(shè)備驅(qū)動層是Linux內(nèi)核中負責管理和控制特定I2C設(shè)備的關(guān)鍵組件。它通過與I2C核心層協(xié)同工作,提供了與I2C設(shè)備進行通信、注冊、注銷、探測、移除等功能的接口。驅(qū)動程序負責初始化設(shè)備、處理設(shè)備的讀寫操作、響應(yīng)中斷事件等,以實現(xiàn)對I2C設(shè)備的控制和管理。通過I2C設(shè)備驅(qū)動層,用戶空間應(yīng)用程序和其他內(nèi)核組件可以方便地與I2C設(shè)備進行交互,并實現(xiàn)各種應(yīng)用需求。
下面詳細介紹I2C設(shè)備驅(qū)動層的主要組成和功能:
-
設(shè)備注冊和注銷:
I2C設(shè)備驅(qū)動層提供了函數(shù)接口,允許驅(qū)動程序注冊和注銷I2C設(shè)備。注冊過程中,驅(qū)動程序需要提供設(shè)備的描述信息,如設(shè)備名、設(shè)備地址等,以便核心層能夠識別和管理設(shè)備。通過注冊,驅(qū)動程序?qū)⒃O(shè)備與I2C總線關(guān)聯(lián)起來,并為設(shè)備分配唯一的設(shè)備編號。注銷過程中,驅(qū)動程序通知核心層不再需要管理該設(shè)備。 -
設(shè)備探測和移除:
當I2C總線上連接的設(shè)備被插入或移除時,I2C設(shè)備驅(qū)動層的探測和移除函數(shù)將被調(diào)用。探測函數(shù)負責初始化設(shè)備并準備設(shè)備進行通信。它接收一個i2c_client結(jié)構(gòu)體指針作為參數(shù),該結(jié)構(gòu)體包含設(shè)備的地址、適配器指針等信息。探測函數(shù)通常會執(zhí)行設(shè)備的初始化和配置操作,并將設(shè)備添加到設(shè)備模型中,以便其他組件可以訪問設(shè)備。移除函數(shù)在設(shè)備被移除時執(zhí)行,它負責清理設(shè)備和相關(guān)資源,并從設(shè)備模型中注銷設(shè)備。 -
設(shè)備操作接口:
I2C設(shè)備驅(qū)動層提供了一組函數(shù)接口,允許用戶空間應(yīng)用程序或其他內(nèi)核組件與I2C設(shè)備進行通信和操作。這些接口包括讀取寄存器、寫入寄存器、發(fā)送和接收數(shù)據(jù)等操作。驅(qū)動程序通過這些接口與設(shè)備進行交互,讀取或?qū)懭朐O(shè)備的寄存器,發(fā)送和接收設(shè)備的數(shù)據(jù)。 -
設(shè)備節(jié)點和文件系統(tǒng)接口:
在Linux內(nèi)核中,I2C設(shè)備通過設(shè)備節(jié)點(Device Node)在文件系統(tǒng)中表示。I2C設(shè)備驅(qū)動層負責創(chuàng)建和管理設(shè)備節(jié)點,使用戶空間應(yīng)用程序可以通過文件系統(tǒng)接口來訪問和控制設(shè)備。設(shè)備節(jié)點通常位于/sys/bus/i2c/devices目錄下,每個設(shè)備節(jié)點對應(yīng)一個已注冊的I2C設(shè)備。用戶空間應(yīng)用程序可以打開設(shè)備節(jié)點,并使用標準的讀寫操作來與設(shè)備進行通信。 -
中斷和工作隊列:
I2C設(shè)備驅(qū)動層還提供了處理中斷和異步操作的機制,以滿足實時性要求。當設(shè)備產(chǎn)生中斷時,驅(qū)動程序可以注冊中斷處理函數(shù)來響應(yīng)中斷事件,并進行相應(yīng)的處理。此外,驅(qū)動程序還可以使用工作隊列(Work Queue)機制,在延遲執(zhí)行的上下文中處理任務(wù),以避免阻塞關(guān)鍵代碼路徑。
I2Ccore
I2C core是Linux內(nèi)核中負責管理和控制I2C總線的基礎(chǔ)層,提供了一組API和數(shù)據(jù)結(jié)構(gòu),用于注冊、注銷和管理I2C控制器、適配器以及與其連接的I2C設(shè)備。
-
I2C控制器注冊:I2C核心層允許I2C控制器驅(qū)動程序在系統(tǒng)啟動時注冊。控制器驅(qū)動程序通過向I2C核心層提供適當?shù)男畔⒑突卣{(diào)函數(shù)來完成注冊過程。一旦注冊成功,核心層將管理該控制器的狀態(tài)并提供相應(yīng)的接口。
-
I2C適配器管理:I2C核心層負責管理系統(tǒng)中的所有I2C適配器。它提供了適配器的注冊和注銷接口,以便適配器驅(qū)動程序可以將適配器添加到系統(tǒng)中或?qū)⑵湟瞥:诵膶舆€維護了適配器的狀態(tài)信息,例如適配器的名稱、地址范圍等。
-
I2C設(shè)備注冊和管理:I2C核心層允許I2C設(shè)備驅(qū)動程序注冊與I2C總線連接的設(shè)備。設(shè)備驅(qū)動程序通過提供設(shè)備地址、設(shè)備ID等信息來完成注冊過程。一旦注冊成功,核心層將為該設(shè)備分配一個唯一的設(shè)備編號,并提供一組函數(shù)接口,使驅(qū)動程序能夠與該設(shè)備進行通信。
-
I2C消息傳輸:I2C核心層提供了用于發(fā)送和接收I2C消息的函數(shù)接口。驅(qū)動程序可以使用這些接口來創(chuàng)建和配置I2C消息,包括設(shè)備地址、寄存器地址、數(shù)據(jù)等信息,并通過適配器驅(qū)動程序?qū)⑾l(fā)送到I2C總線上。核心層還處理I2C消息的ACK/NACK響應(yīng),并提供錯誤處理機制。
-
I2C設(shè)備節(jié)點:I2C核心層通過
/sys/bus/i2c/devices目錄下的設(shè)備節(jié)點來表示已注冊的I2C設(shè)備。每個設(shè)備節(jié)點包含設(shè)備的唯一編號、設(shè)備地址等信息,驅(qū)動程序可以使用這些設(shè)備節(jié)點來訪問和控制對應(yīng)的I2C設(shè)備。
I2C algorithm
I2C algorithm是在軟件層面上實現(xiàn)I2C總線通信的一系列步驟和流程。它通過初始化、發(fā)起通信、傳輸數(shù)據(jù)、等待應(yīng)答、終止通信等操作來實現(xiàn)與I2C設(shè)備的通信和控制。在Linux內(nèi)核中,I2C算法提供了通用的接口和函數(shù),使驅(qū)動程序可以方便地使用和擴展I2C功能。
以下是I2C算法的主要步驟和流程:
-
初始化:
在使用I2C總線之前,需要初始化I2C控制器和相關(guān)的硬件資源。這包括設(shè)置I2C控制器的時鐘頻率、配置引腳和電氣特性等。在Linux內(nèi)核中,通常通過I2C子系統(tǒng)的初始化函數(shù)來完成這些操作。 -
選擇總線:
在多個I2C總線存在的情況下,需要選擇要使用的I2C總線。通常,每個I2C總線都由一個獨立的控制器和相關(guān)的硬件資源管理。選擇總線的方法可以是根據(jù)硬件連接關(guān)系,或者根據(jù)設(shè)備的地址范圍等。 -
發(fā)起通信:
在進行I2C通信之前,需要發(fā)起通信請求。通信請求包括設(shè)備地址、讀寫操作、寄存器地址(如果適用)以及數(shù)據(jù)長度等信息。在Linux內(nèi)核中,可以使用i2c_transfer()函數(shù)發(fā)起通信請求。 -
生成起始信號:
為了開始一次I2C通信,主設(shè)備(通常是控制器)需要發(fā)送起始信號。起始信號表示一次新的通信開始,并引導(dǎo)設(shè)備進行相應(yīng)的響應(yīng)。 -
傳輸數(shù)據(jù):
在I2C通信中,數(shù)據(jù)傳輸通過時鐘信號和數(shù)據(jù)信號線進行。主設(shè)備通過時鐘信號控制數(shù)據(jù)的傳輸速率,而數(shù)據(jù)信號線上的電平則表示傳輸?shù)亩M制數(shù)據(jù)。主設(shè)備和從設(shè)備通過時鐘同步進行數(shù)據(jù)的傳輸。 -
等待應(yīng)答:
在主設(shè)備發(fā)送數(shù)據(jù)字節(jié)后,它會等待從設(shè)備的應(yīng)答信號。應(yīng)答信號可以是從設(shè)備拉低數(shù)據(jù)線,表示準備接收下一個字節(jié);或者釋放數(shù)據(jù)線,表示拒絕接收數(shù)據(jù)。 -
終止通信:
在完成一次I2C通信后,需要發(fā)送終止信號來結(jié)束通信。終止信號表示一次通信的結(jié)束,并將總線釋放給其他設(shè)備。 -
錯誤處理:
在I2C通信過程中,可能會發(fā)生錯誤,如設(shè)備無響應(yīng)、數(shù)據(jù)傳輸失敗等。在Linux內(nèi)核中,I2C算法提供了相應(yīng)的錯誤處理機制,允許驅(qū)動程序檢測和處理通信錯誤。
I2C adapter
I2C適配器是一種硬件設(shè)備,用于在計算機系統(tǒng)中提供I2C總線的物理接口和信號轉(zhuǎn)換功能。它充當I2C主控制器的角色,負責管理和控制連接在I2C總線上的從設(shè)備。適配器提供物理接口、信號轉(zhuǎn)換、主控制器功能、多總線支持等特點和功能,通過相應(yīng)的驅(qū)動程序與操作系統(tǒng)進行通信。簡單來說,一根i2c總線就是一個I2C adapter。
I2C適配器的作用如下:
-
物理接口:
I2C適配器提供了計算機系統(tǒng)與I2C總線之間的物理接口。它通常包括多個I2C總線連接點,每個連接點可以連接一個或多個I2C設(shè)備。I2C適配器的物理接口可以是標準的I2C引腳,如SDA(Serial Data Line)和SCL(Serial Clock Line),也可以是其他物理接口,如GPIO(General Purpose Input/Output)引腳。 -
信號轉(zhuǎn)換:
I2C適配器負責將計算機系統(tǒng)的電平和信號轉(zhuǎn)換為符合I2C總線規(guī)范的電平和信號。它可以將計算機系統(tǒng)的電平轉(zhuǎn)換為I2C總線所需的電平,如將3.3V或5V電平轉(zhuǎn)換為I2C的標準電平(通常為3.3V)。此外,適配器還負責將計算機系統(tǒng)的時鐘信號和數(shù)據(jù)信號轉(zhuǎn)換為I2C總線所需的時鐘和數(shù)據(jù)信號。 -
主控制器功能:
I2C適配器充當I2C總線的主控制器,負責發(fā)起和管理I2C通信。它可以向從設(shè)備發(fā)送讀取和寫入命令,接收從設(shè)備的應(yīng)答信號,并控制數(shù)據(jù)的傳輸速率和時序。適配器還負責生成起始信號和終止信號,以標識一次通信的開始和結(jié)束。 -
多總線支持:
一些I2C適配器支持多個獨立的I2C總線。這允許在同一個計算機系統(tǒng)上連接多個I2C總線,并通過適配器進行獨立的控制和管理。每個總線可以具有不同的時鐘頻率、地址范圍和連接設(shè)備。 -
驅(qū)動程序支持:
I2C適配器通常需要相應(yīng)的驅(qū)動程序來與操作系統(tǒng)進行通信。驅(qū)動程序負責將適配器的功能暴露給操作系統(tǒng),并提供對適配器的控制和配置接口。在Linux內(nèi)核中,提供了一組通用的I2C適配器驅(qū)動程序接口,使開發(fā)人員能夠編寫適配器特定的驅(qū)動程序。 -
軟件工具支持:
為了方便使用和調(diào)試,一些I2C適配器提供了相應(yīng)的軟件工具。這些工具可以用于掃描和探測已連接的I2C設(shè)備、讀取和寫入設(shè)備的寄存器、顯示設(shè)備的狀態(tài)和信息等。
硬件層
I2C device
I2C設(shè)備是連接在I2C總線上的從設(shè)備,通過I2C總線與主控制器進行通信和控制。每個設(shè)備都有一個唯一的地址,并支持讀取和寫入操作。設(shè)備具有寄存器和功能,可以存儲配置參數(shù)、狀態(tài)信息和數(shù)據(jù)。不同類型的設(shè)備具有不同的功能和特性,主控制器可以通過適當?shù)尿?qū)動程序與設(shè)備進行交互。
在使用I2C設(shè)備時,主控制器通過發(fā)送設(shè)備地址、讀取或?qū)懭朊钜约跋嚓P(guān)的數(shù)據(jù)來與設(shè)備進行通信。設(shè)備根據(jù)接收到的命令和數(shù)據(jù)執(zhí)行相應(yīng)的操作,并將結(jié)果返回給主控制器。主控制器可以通過適當?shù)能浖?qū)動程序和庫函數(shù)來管理和控制連接的I2C設(shè)備。
本文參考
https://blog.csdn.net/u013171226/article/details/131761869
https://zhuanlan.zhihu.com/p/645018040
https://www.zhihu.com/tardis/bd/ans/3056478847?source_id=1001
https://www.jianshu.com/p/6d162195f4a7
總結(jié)
以上是生活随笔為你收集整理的【驱动】I2C驱动分析(二)-驱动框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CPLEX通过Python API获取G
- 下一篇: java信息管理系统总结_java实现科