www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > 嵌入式IoT

1.基本概念

總線

總線代表著同類設(shè)備需要共同遵守的工作時序,不同的總線對于物理電平的要求是不一樣的,對于每個比特的電平維持寬度也是不一樣,而總線上傳遞的命令也會有自己的格式約束。如I2C總線、USB總線、PCI總線等等。以I2C總線為例,在同一組I2C總線上連接著不同的I2C設(shè)備。

設(shè)備

設(shè)備代表真實的、具體的物理器件,在軟件上用器件的獨特的參數(shù)屬性來代表該器件。如I2C總線上連接的I2C從設(shè)備都有一個標識自己的設(shè)備地址,由這個設(shè)備地址來確定主設(shè)備發(fā)過來的命令是否該由它來響應(yīng)。

驅(qū)動

簡單的說驅(qū)動代表著操作設(shè)備的方式和流程。

Linux總線設(shè)備框架的工作原理

如果想要弄清楚I2C驅(qū)動框架,必須深刻的理解Linux的總線設(shè)備框架。之所以會形成這樣的框架,很重要的原因是為了代碼的復(fù)用性。因為驅(qū)動和設(shè)備的關(guān)系是一對多的,對于相同類型的不同的設(shè)備,可共用同一套驅(qū)動程序接口。為了提高驅(qū)動的可移植性,Linux抽象出一套管理資源的函數(shù)。設(shè)備是存在的硬件,在設(shè)備里包含自己的屬性,也包含需要用到的資源。

總線的作用就是在軟件層面上對設(shè)備和驅(qū)動進行管理,設(shè)備要讓系統(tǒng)感知到自己的存在,所以需要向總線去注冊設(shè)備,驅(qū)動同樣也要向總線去注冊。對于總線,有I2C總線,Platform總線等等。但是Platform是虛擬總線。

對于總線上設(shè)備與驅(qū)動的匹配,由總線負責(zé),設(shè)備在注冊的時候,總線會遍歷注冊在總線上的驅(qū)動,如果名字相同,則匹配上了,此時調(diào)用驅(qū)動程序的probe函數(shù)。同樣的驅(qū)動在注冊的時候,也會遍歷總線上的設(shè)備,如果匹配上(名字一樣),則也會調(diào)用驅(qū)動程序的probe函數(shù)。


2.I2C傳輸協(xié)議



對于I2C來說,有如下的特點:

1.一條串行數(shù)據(jù)線(SDA),一條串行時鐘線(SCL)

2.每個接到總線上的器件都可以使用軟件根據(jù)它的唯一地址來識別。

3.串行的8位雙向數(shù)據(jù)傳輸,位速率在標志模式下可達100kbit/s,在快速模式下可達400kbit/s。在高速模式下可達3.4Mbit/s。

下面來看一下具體的硬件連接

以上是TFS上的攝像頭I2C的連接方式,只有兩根線即可實現(xiàn)數(shù)據(jù)的傳輸。在傳輸過程中,需要注意以下三種類型的信號:

(1)開始信號(S):SCL為高電平時,SDA由高向低電平跳變,開始傳輸數(shù)據(jù)

(2)結(jié)束信號(P):SCL為高電平時,SDA由低向高電平跳變,結(jié)束傳輸數(shù)據(jù)

(3)響應(yīng)信號(ACK):接收器在接收到8位數(shù)據(jù)后,在第9個時鐘周期,拉低SDA的電平

以上就是I2C的硬件層與協(xié)議層的基本概述,這部分可以作為基本認知。


3.Linux下I2C驅(qū)動程序的體系結(jié)構(gòu)



對于Linux下的I2C驅(qū)動,其體系結(jié)構(gòu)的組成主要分為三個部分

(1)I2C核心:I2C核心提供了I2C總線驅(qū)動和設(shè)備驅(qū)動的注冊,注銷方法,I2C通信方法(”algorithm”)上層的,與具體適配器無關(guān)的代碼以及探測設(shè)備,檢測設(shè)備地址的上層代碼等。

(2)I2C總線驅(qū)動:I2C總線驅(qū)動是對I2C硬件體系結(jié)構(gòu)中適配器端的實現(xiàn),適配器可由CPU控制,甚至可以直接集成在CPU內(nèi)部。

(3)I2C設(shè)備驅(qū)動:I2C設(shè)備驅(qū)動(也稱為客戶驅(qū)動)是對I2C硬件體系結(jié)構(gòu)中設(shè)備端的實現(xiàn),設(shè)備一般掛接在受CPU控制的I2C適配器上,通過I2C適配器與CPU交換數(shù)據(jù)。

比較重要的文件

\kernel\drivers\i2c\i2c-core.c

這個文件實現(xiàn)了 I2C 核心的功能以及/proc/bus/i2c*接口。同時對I2C底層的收發(fā)函數(shù)進行封裝。會調(diào)用i2c_transfer ,里面實現(xiàn)了adap->algo->master_xfer(adap, msgs, num)

kernel\drivers\i2c\i2c-dev.c

該函數(shù)注冊了一個設(shè)備文件的功能,也就是注冊了一個字符設(shè)備驅(qū)動程序,可以通過/dev/i2c-0(i2c-0, i2c-1,…, i2c-10,…)找到具體的I2C適配器,這個I2C設(shè)備的主設(shè)備號為89,次設(shè)備號0~255。通過訪問這個接口,可以通過open()、 write()、 read()、 ioctl()和 close()等來訪問這個設(shè)備。

kernel\drivers\i2c\busses\i2c-v12-jz.c

該函數(shù)對君正的x1000底層的I2C操作控制函數(shù),通過設(shè)置寄存器來進行I2C的控制。其最底層的收發(fā)函數(shù)都在該文件里定義。重要的是i2c_jz_algorithm,其中algorithm實現(xiàn)了對底層寄存器的操作。

比較重要的結(jié)構(gòu)體

i2c_driver、 i2c_client、 i2c_adapter 和 i2c_algorithm這四個結(jié)構(gòu)體十分的關(guān)鍵

i2c_driver

對應(yīng)一套驅(qū)動方法,是純粹的用于輔助作用的數(shù)據(jù)結(jié)構(gòu),它不對應(yīng)于任何的物理實體。

i2c_client

對應(yīng)于真實的物理設(shè)備,每個 I2C 設(shè)備都需要一個 i2c_client 來描述。i2c_client 一般被包含在 I2C 字符設(shè)備的私有信息結(jié)構(gòu)體中。

i2c_adpater

用來匹配i2c_driver與i2c_client。即 i2c_client 依附于 i2c_adpater。由于一個適配器上可以連接多個 I2C 設(shè)備, 所以一個 i2c_adpater 也可以被多個 i2c_client 依附, i2c_adpater 中包括依附于它的 i2c_client 的鏈表 。

i2c_algorithm

struct i2c_algorithm{
 //i2c模式下,收發(fā)函數(shù)接口
 int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,int num);
 //用于SMBUS模式下,收發(fā)函數(shù)接口
 int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,  unsigned short flags, char read_write,  u8 command, int size, union i2c_smbus_data *data);
 //用于檢查I2C主控制器所支持訪問接口,如I2C_FUNC_SMBUS_BYTE,查看是否支持smbus單字節(jié)讀取和寫操作
 u32 (*functionality) (struct i2c_adapter *);
}

該函數(shù)主要實現(xiàn)其I2C底層的操作


4.GC0328攝像頭I2C實例分析



對于攝像頭驅(qū)動程序,首先要知道如何讓攝像頭能夠正常工作。

第一步:攝像頭上電

在這一步的工作中,可以控制相關(guān)的GPIO進行攝像頭使能,控制RESET及POWERON來讓攝像頭正常工作。

GC0328的上電時序如下圖所示:

第二步:給攝像頭提供時鐘

這一步也比較的關(guān)鍵,對于攝像頭來說,其時鐘就是心跳,如果要讓攝像頭正常的工作,則需要x1000的CIM提供24MHz的時鐘給攝像頭。

第三步:配置攝像頭的寄存器

對于一個攝像頭sensor,需要其輸出指定大小及指定格式的圖片,則需要配置攝像頭的寄存器。而配置攝像頭寄存器就是需要通過I2C來進行配置。

第四步:配置CIM

x1000內(nèi)部的攝像頭接口控制模塊,可以將攝像頭數(shù)據(jù)進行處理,可以進行幀錯誤檢查以及數(shù)據(jù)的傳輸。這部分的控制需要那些CIM相關(guān)的寄存器來完成。

第五步:啟動CIM

配置及初始化完成后就可以啟動攝像頭了,CIM負責(zé)數(shù)據(jù)傳輸及產(chǎn)生相應(yīng)的中斷。

以上是攝像頭初始化的一個完整的過程,對于攝像頭初始化部分,I2C又是如何進行初始化及設(shè)置的呢?這也是本文的重點。

根據(jù)前面的總線設(shè)備驅(qū)動的框架,有driver那么肯定會有device。這兩者的匹配靠的是.id_table

對于gc0308,具體可以通過kernel/arch/mips/xburst/soc-x1000/chip-x1000/halley2/common/i2c_bus.c

可以看到向I2C總線注冊的device的是gc0308

如果匹配上了,則調(diào)用driver的.probe函數(shù)。下面我們來看一下該函數(shù)具體做了什么事情。

在probe函數(shù)中,主要向v412_i2c_subdev提供了一個可操作的client,也就是相當(dāng)于I2C的操作函數(shù)的接口交給V4L2視頻驅(qū)動框架來進行管理。向V4L2視頻驅(qū)動框架提供的函數(shù)如下:

第一個結(jié)構(gòu)體是有關(guān)視頻操作的接口,比如設(shè)備gc0328的輸出格式,得到當(dāng)前的視頻輸出格式等等

第二個結(jié)構(gòu)體是控制camera上電與斷電,以及控制白平衡,對焦的其他的參數(shù)

通過V4L2的I2C子設(shè)備控制來進行設(shè)置。下面來基本分析一下其調(diào)用過程:

當(dāng)應(yīng)用程序通過ioctl傳遞VIDIO_S_FMT,是可以設(shè)置攝像頭輸出的格式

然后看一下寫寄存器的過程

調(diào)用了i2c_smbus_write_byte_data該函數(shù)在kernel\drivers\i2c\i2c-core.c,這樣就進入了i2c總線操作函數(shù)中。

該函數(shù)會調(diào)用i2c_smbus_xfer

為什么不滿足條件,可以看注冊的i2c的平臺設(shè)備,在kernel\drivers\i2c\busses\i2c-v12-jz.c路徑下

有個i2c_algorithm的結(jié)構(gòu)體

struct i2c_algorithm{
 //i2c模式下,收發(fā)函數(shù)接口
 int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,int num);
 //用于SMBUS模式下,收發(fā)函數(shù)接口
 int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,  unsigned short flags, char read_write,  u8 command, int size, union i2c_smbus_data *data);
 //用于檢查I2C主控制器所支持訪問接口,如I2C_FUNC_SMBUS_BYTE,查看是否支持smbus單字節(jié)讀取和寫操作
 u32 (*functionality) (struct i2c_adapter *);
}

所以只會向下執(zhí)行,當(dāng)執(zhí)行到i2c_smbus_xfer_emulated ,會調(diào)用

該函數(shù)會調(diào)用

最后調(diào)用到kernel\drivers\i2c\busses\i2c-v12-jz.c的最底層的實現(xiàn)

在kernel\drivers\i2c\busses\i2c-v12-jz.c函數(shù)中

這個函數(shù)指向i2c_jz_xfer

在這個函數(shù)中,實現(xiàn)了I2C的讀寫,可以根據(jù)傳遞的flag進行判斷是讀操作函數(shù)寫操作

最底層操作寄存器來實現(xiàn)其讀寫函數(shù)

到這里,一個I2C完整的傳輸流程就完成了。


5.總結(jié)



對于I2C完整的傳輸協(xié)議,最重要的是弄清楚總線驅(qū)動程序的框架,因為I2C也是屬于總線框架。對于I2C總線設(shè)備框架的模型,可以用下圖來說明:

也就是device與driver同時向i2c總線上注冊。當(dāng)注冊在總線上時,可以通過id_table進行匹配,匹配上之后會調(diào)用driver的.probe函數(shù)。對于一般的I2C設(shè)備,可以在probe函數(shù)中注冊一個字符設(shè)備驅(qū)動,從而應(yīng)用層可以通過open函數(shù)打開/dev/i2c-0等設(shè)備節(jié)點。從而對I2C設(shè)備進行讀寫操作。而攝像頭部分,直接將控制接口傳遞給V4L2進行管理,這樣通過視頻設(shè)備驅(qū)動框架進行攝像頭調(diào)節(jié),從而達到控制的目的。


本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉