日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

嵌入式Linux中I2C设备驱动程序的研究与实现

發布時間:2025/3/17 linux 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 嵌入式Linux中I2C设备驱动程序的研究与实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

I2CInter?Integrated?Circuit?Bus的縮寫,中文譯成內部集成電路總線,?它是Philips?公司于20?世紀80?年代研發成功的一種具有多端控制功能的雙線雙向串行數據總線標準,?其具有模塊化、電路結構簡單等優點。在嵌入式系統中,I2C總線已經成為器件接口的標準之一,?常用于連接RAMEEPROM?以及LCD?控制器等設備。另外,總線的數據傳輸是以字節為單位的。

目前,標準的I2C的傳輸速率可以達到100kbit/s,能支持128?個設備,增強型I2C傳輸速率可達400kbit/s,能支持多達1024?個設備,高速模式下的I2C?傳輸速率更高達3.4Mbit/s

?序就可以輕松地操作和驅動硬件架構的分層。

2?Linux?I2C?體系結構

2.1?Linux?I2C?體系結構分析

Linux?I2C?體系結構由3?大部分組成:

(1)I2C框架:I2C.h?I2C-core.c?I2C框架的主體,提供了核心數據結構的定義、I2C?適配器驅動和設備驅動的注冊、注銷方法,I2C?通信方法(algorithm)上層的、與具體適配器無關的代碼、以及檢測設備地址的上層代碼等。作為核心的I2C-core.c?還為總線驅動設備提供了一些統一的調用接口進行讀寫和設置操作,?另外它還提供了將各種支持的總線設備驅動添加到這個體系中的方法,?以及當不再使用這些總線驅動時從體系中刪除的方法。

(2)I2C?總線驅動I2C總線驅動是對I2C?硬件體系結構中適配器端的實現,I2C?總線驅動主要包含了I2C?適配器數據結構I2C_adapter,?以及描述在具體I2C?適配器上的總線通信方法i2c_algorithm?數據結構。

(3)I2C?設備驅動:I2C?設備驅動是對I2C?硬件體系結構中設備端的實現,?設備一般掛接在受CPU?控制的I2C?適配器上,?通過I2C?適配器與CPU?交換數據。I2C?設備驅動主要包含了數據結構i2c_driver?i2c_client

這三部分的關系如圖1?所示。

1Linux?I2C?體系結構

2.2?I2C驅動程序中的重要數據結構

I2C?框架的i2c.h?這個頭文件中對4?個關鍵的結構體進行了定義,?它們分別是i2c_adapteri2c_algorithmi2c_driver?i2c_client。結構體i2c_adapter?是一個I2C控制器的邏輯抽象,并且作為最核心的數據結構提供了I2C適配器的驅動。i2c_algorithm對應一套通信方法,?其封裝了對一個I2C?控制器的讀寫操作,?并且提供的通信函數可以控制適配器上產生特定的訪問周期,這套通信方法由驅動開發者來完成。i2c_driver?則是對應于一套驅動方法,用于輔助作用的數據結構,不對應任何物理實體,僅是提供了I2C?設備i2c_client?的驅動。而i2c_client?對應于真實的物理設備,描述具體設備可能的私有數據結構。

2.3I2C驅動程序中重要數據結構之間的關系

對于上述的4?個結構體來說,?其中的i2c_driver?i2c_client?是與具體I2C?設備相關的,i2c_adapter?i2c_algorithm則共同構成I2C?總線適配器驅動。一個algorithm?可以適用于多個I2C?總線上的不同adapters,?但具體的每個adapter?只能對應于一個algorithm。在i2c_adapter?數據結構中設計了clients指針數組,?用于記錄該總線上每個設備的i2c_client?數據結構。

另外,?定義內核中全局靜態指針數組adapters?drivers?分別記錄已注冊的I2C?適配器驅動和I2C?設備驅動程序。值得注意的是同一個i2c_adapter?中的不同的i2c_client?可能使用同一個i2c_driver,而分屬于不同i2c_adapter?中的兩個i2c_client?也可能使用同一個i2c_driver

3?一個具體的I2C?設備驅動程序的開發

AT24C08?是由ATMEL?公司出品的一款EEPROM?存儲器。

作為一個標準的I2C?設備AT24C08?4?個塊存儲區,?一個塊有256?個數據存儲單元,整個AT24C08?具有1024?個存儲單元。由于每個數據存儲單元可存1?字節的數據,所以整塊AT24C08?的存儲能力為1KB

3.1?I2C?設備驅動程序的一般結構及運行流程圖

開發一個具體的I2C?設備驅動需要一個完整、標準的結構,而該結構的實現是通過編寫兩個方面的接口而完成的,?一個是用以掛接I2C?adapter?層來實現對I2C?總線及I2C設備具體的訪問方法,?I2C?核心層的接口,?主要實現attach_adapter,detach_client,command?等接口函數。另一個是對用戶應用層的接口,?提供用戶程序訪問I2C設備的接口,?包括實現open,release,read,write?以及ioctl?等標準文件操作的接口函數。下面將通過對核心層接口和應用層接口的分析來說明I2C?設備驅動程序的運行機制。圖2?I2C?設備驅動程序運行流程圖(圖中at?代表具體的設備AT24C08):

3.2?I2C?設備驅動的I2C?核心層接口分析

如圖2?的用戶空間在通過insmod?命令加載設備驅動程序時,?設備驅動將通過使用動態模塊的方式加載并指向設備初始化函數at_init(),在初始化函數中使用register_chrdev()進行字符型設備的注冊,?并可以通過靜態和動態兩種方法來申請注冊到系統中的設備號。另外將調用核心i2c?-core.c?中提供的i2c_add_driver()函數注冊由at_driver?數據結構描述的驅動方法,該數據結構中完成了對驅動程序的標示,?并包含了兩個重要的成員函數at_attach_adapter()at_detach_client()

i2c_add_driver?()?注冊at_driver?數據結構后,at_attach_adapter()函數就會被自動調用,其遍歷系統中的每個i2c?總線驅動,?探測想要訪問的設備,?連接符合i2c?driver?特定條件的i2c?adapter,并通過i2c?adapter?實現對I2C?總線及其設備的訪問。

at_attach_adapter()的功能則是依靠調用i2c-core.c?核心中的i2c_probe()函數來實現的,通過i2c_probe()函數可以認領adapter所指向的適配器上的所有合適的設備。設備可能使用的地址由addr_data?數組指出。通過設備地址每次檢測到新設備后,i2c_probe()將使用它的第三個參數即回調函數初始化設備的數據結構i2c_client,并用i2c_check_functionality()確定I2C?適配器所支持的通信方法。另外再使用i2c_attach_client()知會I2C?核心系統中包含了一個新的I2C?設備。

通過rmmod?命令對設備驅動進行卸載時,?在卸載函數at_exit()中將使用i2c_del_driver(),其調用會引起與數據結構at_driver?關聯的每個i2c_client?與之解除關聯,?隨后at_detach_client()函數也將因此而被調用,at_detach_client()中的i2c_detach_client()又完成與i2c_attach_client()相反的過程,并使用kfree?釋放由client?所占的內存。另外卸載函數at_exit()中還將使用unregister_chrdev()對字符型設備進行注銷。

3.3I2C設備驅動用戶應用層接口分析

在注冊字符型設備時,?設備驅動中初始化了一個structfile_operations?文件操作結構體變量用于鏈接字符設備驅動程序和用戶應用程序,在該結構中定義了一組函數指針。系統就是通過這組函數指針對AT24C08?進行具體的操作,系統首先通過設備文件的主設備號找到相應的設備驅動程序,?然后讀取這個數據結構相應的函數指針,找到相關的功能函數,接著把控制權交給該函數,從而就在上層屏蔽了設備驅動的具體實現細節,提供給用戶一個方便快捷的接口。該結構中的at_open(),對應于用戶應用層的open()接口函數,其通過mknod?創建的設備節點對設備文件進行打開操作。而對應用戶層release?()?接口函數的at_release?()?則負責設備文件的釋放操作。file_operations?中的at_ioctl()則主要是為用戶提供一些控制該AT24C08?的命令。對一塊具體設備進行讀寫操作是編寫驅動要達到目的,file_operations結構體中所指向的讀寫函數at_read(),at_write()完成了對AT24C08?的寫入和讀出操作。

就寫函數而言,?在寫數據之前必須先輸入測試單元的起始地址,?然后再對寫入的數據分配相應內存,?然后使用copy_from_user?命令把從用戶空間獲得的數據拷貝到內核空間,并構造I2C?消息數據,最終通過i2c-core.c?i2c-transfer()函數進行I2C消息數組的傳輸,i2c_transfer()將指向總線驅動中的算法i2c_algorithm?所對應的具體適配器的master_xfer()方法,這樣就借助i2c-core.c?作為紐帶連接了設備驅動和總線驅動,并完成了兩者之間的通信,其運行流程如圖2?的內核空間所示。

對于讀函數at_read(),同樣要對數據進行內存的分配,構造I2C消息,傳輸I2C?消息以及轉換數據空間等。兩者的主要區別則體現在對I2C?消息的構造上,在讀出數據之前,先要寫地址,根據寫入的地址來尋找將要讀出的數據的起始地址,?所以在讀函數中就需要構造兩條I2C?消息,一條用于寫地址操作,另一條用于讀數據操作。另外在轉換數據空間時,?讀函數將使用copy_to_user?把內核空間的數據拷貝到用戶空間。

3.4?AT24C08?的單設備多驅動的實現方式

單設備多驅動是本文的一個創新點。設計中實現了分3?個設備驅動一對1?AT24C08?進行操作。設備驅動1?AT24C08的第1?個塊操作,設備驅動2?對第2?個塊操作,設備驅動3?對第3?和第4?個塊進行操作。對塊的分開操作體現在對設備地址的探測上,由于保存設備地址信息的是二元數組addr_data,所以在多驅動對單一的AT24C08?操作時就需要在該二元數組中指明每個設備驅動程序所控制的設備地址。對于控制第1?個塊的設備驅動1,通過數組normal_addr?指出要進行操作的設備地址為0x50,如下所示:

static?unsigned?short?normal_addr[]={?0x50,I2C_CLIENT_END};

再通過其對數組addr_data?進行初始化,?這樣,?設備驅動1就能檢測到數組中所指出的AT24C08?的第1?個塊,而跳過其他的塊,?達到了只對單一特定塊操作的目的。對于設備驅動2?來說,?只需把數組normal_addr?中地址改為AT24C08?的第2?個塊的地址0x51?即可。同理,對設備驅動3,只需把normal_addr?中的單一地址改為兩個地址即可,如下所示:

static?unsigned?short?normal_addr?[]?=?{?0x52,0x53,?I2C_CLIENT_END};

這樣就可使設備驅動只探測到后兩個塊,而跳過其他塊,以達到對單一AT24C08?中多個塊操作的目的。然后再用insmod命令加載編譯好的三個.ko?驅動模塊,?獲得3?個不同的設備號后,接著根據所獲得的設備號使用mknod?命令創建3?個不同的字符型設備節點,?最后通過用戶層的3?個測試程序分別打開已創建的這3?個不同的設備節點就能分別對不同的塊進行讀寫操作,至此就實現了單設備多驅動的控制方式。

同樣除了分3?個驅動外,?驅動開發者也可以編寫4?個設備驅動分別對每1?個塊進行操作,?或者就只編寫1?個設備驅動對4?個塊一起操作,也適用于綁定非連續塊進行操作,比如用一個設備驅動控制第1?和第3?個塊。總之驅動開發人員可以根據不同的需要進行不同的組合方式。

3.5?AT24C08?設備驅動程序的驗證與測試

設備驅動程序的驗證,?需要通過用戶層的測試程序來實現,測試程序如下:

fd=open("/dev/at",?O_RDWR);?//打開設備文件,獲得設備文件的文件描述符。

scanf("%u",?&start_address);?//輸入測試單元起始地址。

write(fd,buf,sizeof(buf));?//把以頁寫入方式把輸入的16?個數據寫入內核空間。

?

轉載于:https://www.cnblogs.com/yuzaipiaofei/archive/2012/01/04/4124296.html

總結

以上是生活随笔為你收集整理的嵌入式Linux中I2C设备驱动程序的研究与实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。