LINUX I2C設備驅動模塊分析之一 總體框架分析

從本文開始,我們分析LINUX I2C驅動模型,在LINUX系統中,I2C作為一個單獨的驅動模塊存在,而針對I2C驅動模型而言,主要涉及I2C總線、I2C設備、I2C適配器、I2C驅動共四個模塊,相對於前面介紹的LINUX設備驅動模型而言,多了一個I2C適配器,稍後我們對這幾個概念進行分析說明(閱讀本系列文章,需對linux設備驅動模型有一定的瞭解,不熟悉的朋友可參看我之前寫的設備驅動模型相關分析的文章)。

本專題大致劃分為如下幾個方向:

I2C總體框架分析

I2C總線分析

I2C adapter分析

I2C device-driver分析

I2C 通用字符設備分析

I2C通用接口分析(讀寫接口供其他模塊調用)

本篇文章則主要分析I2C總線框架,主要包括I2C相關的一些概念以及I2C驅動模型相關的結構體分析以及結構體之間的關聯分析等內容。

I2C控制器-CPU-I2C設備間的關係

在前面的文章中,我們分析的LINUX設備驅動模型以及PLATFORM驅動模型,均只涉及

總線-設備-驅動,而i2c驅動模型則多了i2c適配器抽象,為什麼會多個i2c適配器呢,它和i2c設備、i2c驅動、i2c總線的關係是怎樣的呢,我們下面通過如下邏輯圖進行說明。

如下圖所示,CPU通過片間總線與I2C控制器通信,而各I2C設備則通過I2C總線與I2C控制器銅線。具體說明如下:

  1. CPU與I2C控制器之間主要是通過片間總線進行通信(如APB總線),但針對驅動工程師而言,對CPU與I2C控制器之間的片間總線是無感知的,驅動工程師只需要通過映射至CPU地址空間的寄存器地址,通過對寄存器進行讀寫即可與I2C控制器通信;
  2. I2C控制器與I2C設備之間則通過I2C總線進行通信,而I2C控制器作為主模式時,則實現用於產生時序、啟動或停止傳輸等功能。而我們可以為該I2C控制器編寫相應的驅動,實現時序產生、啟動或停止傳輸時序,建立數據通信渠道,實現CPU與具體的I2C設備間的數據通信。
  3. 而針對具體的I2C設備,由於其實現的功能不同(rtc設備、風扇、溫度傳感器等),因此若要驅動具體的I2C設備,則需要針對具體的I2C設備編寫相應的驅動程序。
LINUX I2C設備驅動模塊分析之一 總體框架分析

針對上面CPU-I2C控制器-I2C設備,我們也可以進行相應的抽象,如I2C控制器及其驅動、I2C

設備及其設備、I2C設備依附於具體的I2C控制器(需要藉助具體I2C控制器的方法,才可以與掛載其上的I2C設備通信)、I2C控制器提供產生I2C通信相關的時序等。

以上為我們抽象出的設備與驅動,而在LINUX的I2C驅動模型中,與我們上面的抽象基本一

致:

  1. 在LINUX的I2C驅動模型中,其抽象了I2C adapter對應I2C controller,同時需要為每一個I2C控制器編寫驅動程序
  2. LINUX定義了I2C client對應I2C設備;
  3. LINUX定義了I2C 的i2c_algorithm,該方法主要由具體的I2C adapter來實現產生I2C控制器與I2C設備間通信的機制(實現時序產生、啟動或停止傳輸時序,建立數據通信渠道)。
  4. LINUX定義了I2C driver,作為對應I2C設備的驅動方法。

由以上的分析,我們可以看到,LINUX I2C模塊通過抽象出I2C adapter、I2C client、I2C

driver、i2c_algorithm,實現了I2C總線通信,而I2C模塊也是對LINUX設備驅動模型的繼承,自然也定義了總線類型的變量(bus_type類型的變量)。如下就是這幾個結構體變量的邏輯關聯圖(該圖不是太嚴謹,等下我們通過結構體間的關聯進行詳細的描述)

LINUX I2C設備驅動模塊分析之一 總體框架分析

I2C模型相關的結構體分析

既然i2c模型也是對linux 設備-總線-驅動模型的繼承,因此i2c模塊相關的結構體中一定存在bus_type、driver、

device-driver這三種類型的變量,否則其將無法使用linux設備-總線-驅動模型。只要是linux系統中使用設備-總線-驅動模型的子模塊,基本上其結構體都要包含bus_type、driver、device_driver這三種類型的變量。在i2c中定義了bus_type類型的總線變量,命名為i2c_bus_type。而i2c_client結構體是對一個i2c硬件設備的邏輯抽象,其中包含了device類型的成員變量;i2c_adapter結構體是對一個i2c控制器的邏輯抽象,其中也包含了device類型的成員變量;i2c_driver結構體是對i2c硬件設備的驅動的邏輯抽象,其中包含了device_driver類型的成員變量。(這其中存在一個可能的衝突為i2c_client、i2c_adapter均包含了device類型的變量,那當調用設備-總線-驅動模型中的設備/驅動的註冊函數時,設備與驅動進行綁定時,i2c_driver會綁定至i2c_adapter對應的device嗎?不會的,因為i2c總線的match接口,對i2c client、i2c adapter做了區分,保證i2c_driver只會綁定i2c_client)。下面我們分析下i2c_client、i2c_adapter、i2c_driver這三個結構體變量

i2c_client結構體

該結構體是i2c硬件設備的邏輯抽象,包括了該i2c設備的地址類型、i2c設備地址、其所依附的adapter指針、其所綁定的i2c驅動、device類型的成員變量、鏈接至i2c驅動的鏈接頭等信息,其通過adapter、driver指針連接了i2c適配器與驅動

LINUX I2C設備驅動模塊分析之一 總體框架分析

i2c_adapter結構體

該結構體的定義如下,主要包括了該adapter提供的方法,該adapter支持的類型(class變量主要用於自動探測尚未註冊到i2c總線上的i2c client,需要adapter和i2c driver有共同的類型,且i2c driver支持detect方法時才會自動探測)

LINUX I2C設備驅動模塊分析之一 總體框架分析

i2c_driver結構體

該結構體的定義如下,其中class的含義與i2c_adapter中的含義相同,而detect函數指針就是上面所說對未註冊進i2c總線的I2c設備進行自動探測,並註冊進i2c總線中;而probe、remove等接口則主要是對設備驅動模型中device_driver中對應函數指針的實例;而attach_adapter接口則是在adapter註冊進i2c總線時,對adapter下所有未註冊的設備進行探測與匹配註冊的操作,目前該接口已不推薦使用;而id_table主要用於說明該驅動支持哪些i2c client;address_list主要是配置detect函數指針使用,當探測尚未註冊的i2c 設備時,僅對該變量中定義的i2c設備地址進行探測操作。

LINUX I2C設備驅動模塊分析之一 總體框架分析

i2c模塊各結構體間的關聯

在分析具體的實現前,我們先分析i2c模塊的結構體間的關聯,當我們對結構體間的關聯熟悉後,再分析實現就簡單很多。

我們主要從以下幾個方面進行說明:

I2c各結構體之間設備驅動模型的關聯、i2c adapter與i2c client的關聯、i2c adapter與i2c client、i2c driver的關聯

I2c各結構體之間設備驅動模型的關聯

本模塊主要用於說明i2c adapter、 i2c driver、i2c client、i2c_bus是如何通過設備-總線-驅動模型間的結構體進行關聯的。

  1. I2c driver通過device_driver類型的成員變量,完成與i2c_bus的關聯,主要通過i2c bus的driver_kset、klist_drivers這兩個變量實現不同的關聯;
  2. I2c client/adapter通過device類型變量,完成與i2c bus的關聯,主要通過klist_devices變量實現關聯。特別的是i2c client通過device類型變量完成與i2c_driver的device_driver類型的成員變量的關聯,通過knode_driver以及device_driver的klist_drivers的關聯。

而device_driver、device、bus_type的關聯以及驅動與設備綁定及探測,是通過設備驅動模型的接口device_register、driver_register實現的。

LINUX I2C設備驅動模塊分析之一 總體框架分析

I2c client與i2c adapter之間的關聯

上面已經說明了i2c client、i2c adapter、i2c driver之間通過設備-驅動模型的結構體進行關聯,此處僅說明i2c client、i2c adapter這兩個結構體本身成員的關聯,如下圖所示:

I2c adapter對應的device變量成員,是所有依附在該adapter上的i2c client的父設備,它們之間通過klist完成了關聯(圖中黑色箭頭流向為此種關聯);

I2c client通過其i2c_adapter類型的指針,完成對其所依附i2c adapter的指定。

LINUX I2C設備驅動模塊分析之一 總體框架分析

I2c adapter、i2c client、i2c driver之間的關聯

此處主要說明這三個結構體體間的關聯,它們三個通過i2c client為橋樑實現了鏈接,其中i2c client、 i2c adapter之間的關聯上面已經說明,而i2c client與i2c driver之間,通過i2c driver的clients鏈表頭,將該driver所探測到的i2c client鏈接在一起。

LINUX I2C設備驅動模塊分析之一 總體框架分析

以上說明了linux i2c模塊的總體框架,以及i2c模塊主要結構體之間的關聯,相信通過本篇文章的介紹,對linux i2c模塊的實現有一個感性的認識,下面幾篇文章進行具體實現的分析。


分享到:


相關文章: