《電子技術應用》
您所在的位置:首頁 > 模擬設計 > 設計應用 > 嵌入式Linux中I2C設備驅動程序的研究與實現
嵌入式Linux中I2C設備驅動程序的研究與實現
摘要: I2C 作為一種目前通用的總線技術,已廣泛應用于EEPROM、實時鐘、小型LCD 等設備與CPU 的接口中。分析了嵌入式Linux 中I2C 驅動程序的體系結構,I2C 驅動程序中一些重要數據結構之間的關系以及I2C 驅動程序的運行機制。最后,結合具體的EEPROM 芯片AT24C08 說明了在嵌入式Linux 下開發I2C設備驅動程序的一般流程。另外還創新了一般的驅動方法,實現了單設備多驅動的驅動模式。
Abstract:
Key words :

  引言

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

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

  1 Linux 驅動程序

  驅動程序是指系統內核與系統硬件之間的接口。Linux 中的每一個外圍物理設備等都有一個專門用于控制該設備的設備驅動程序" title="設備驅動程序" target="_blank">設備驅動程序。設備驅動可以完成初始化、釋放以及檢測硬件設備;差錯和故障處理;負責內核與硬件、應用程序與硬件之間的數據傳輸與通信的一些重要工作。在嵌入式系統中,設備驅動為嵌入式操作系統和應用程序訪問硬件設備提供統一的接口。通過它, 操作系統和應用程序就可以輕松地操作和驅動硬件架構的分層。

  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_adapter、i2c_algorithm、i2c_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 個數據寫入內核空間。

  4 結束語

  作為當前最流行的總線技術之一,I2C 總線具有結構小巧,使用簡單高效的特點,目前在各種設計中已得到廣泛的應用。本文分析了Linux 下I2C 的體系結構,較為詳盡的說明了I2C驅動程序中的一些重要數據結構以及這些數據結構之間的關系,并論述了I2C 驅動程序體系的運行機制, 最后以一個EEPROM 芯片AT24C08 為例,詳細的給出了一個具體設備驅動的基本開發過程, 并說明了設備驅動中的兩個重要接口,I2C 核心層接口和用戶應用層接口。更重要的是本文還提供了一種單設備多驅動的實現方式,這將帶給驅動開發人員一定的啟示。另外,本文還進行了設備驅動程序的測試與驗證工作, 保證了設備驅動程序編寫的正確性。本文的設備驅動設計方法也將對其他相關I2C設備驅動的設計提供良好的借鑒作用。

此內容為AET網站原創,未經授權禁止轉載。
主站蜘蛛池模板: 在线国产你懂的| 羞羞视频免费网站含羞草| 小说区亚洲自拍另类| 免费观看中文字幕| 日本免费一区二区在线观看| 日本大片在线播放在线| 免费精品99久久国产综合精品| www.中文字幕| 欧美成人另类人妖| 国产人久久人人人人爽| 91欧美一区二区三区综合在线| 日韩精品电影一区| 午夜视频在线观看按摩女| 99re热精品这里精品| 新版天堂中文在线8官网| 亚洲午夜爱爱香蕉片| 青青草97国产精品免费观看 | 欧美综合自拍亚洲综合图片区| 国产成人麻豆亚洲综合无码精品 | 综合图区亚洲欧美另类小说| 在线观看亚洲av每日更新| 丰满少妇人妻HD高清大乳在线 | 久久狠狠爱亚洲综合影院| 欧美挠脚心tickling免费| 免费a级毛片在线观看| 舌头伸进去里面吃小豆豆| 国产成人精品怡红院在线观看 | 丰满大白屁股ass| 性欧美xxxx乳| 亚洲国产精品无码久久| 粗大的内捧猛烈进出视频| 国产真人无码作爱免费视频| 中文字幕乱码一区二区免费| 欧美激情第1页| 八戒八戒神马影院在线观看4| 中国xxxxx高清免费看视频| 女人扒开腿让男生桶爽动漫| 亚洲Av无码一区二区二三区| 波多野结衣亚洲一区| 公用玩物(np双xing总受)by单唯安| 香蕉一区二区三区观|