嵌入式Linux下的I2C設備驅動程序設計
i2c_dev 里面定義了讀寫I2C 設備應用層的讀寫接口,但由于其缺少通用性,一般很少用到所以并不做詳細的介紹。
i2c_core在驅動框架中起到了承上啟下的作用,里面定義了許多重要的函數。例如:adapter注冊/注銷函數,增加/刪除設備驅動函數,增加/刪除I2C設備的函數,I2C傳輸,發送和接收函數。這些函數都是在編寫I2C設備驅動程序中必須要用到的接口函數,正是由于這些通用的接口函數才使得代碼具有很強的可移植性和重用性。
3 編寫I2C設備驅動的思路
在了解Linux中I2C設備驅動的基本框架后,要編寫自己的設備驅動首先要弄清楚的一個問題是到底內核已經實現了那部分,需要實現的又是那部分。因為I2C設備驅動是基于總線設備驅動模型的,一般而言在移植Linux操作系統中,Linux內核已經對總線部分已經有了很好的實現,所以總線部分的驅動一般可以不必關心。
在此需要實現的是設備層的i2c_driver與i2c_client結構體,并利用I2C 子系統提供的接口函數掛接到I2C 總線上。
每一個I2C設備驅動,必須首先創造一個i2c_driver結構體對象,該結構體包含了I2C設備探測和注銷的一些基本方法和信息。其中包括設備驅動的名字,適配器的掛接/取消函數指針等。一個例子如下所示,name字段標識本驅動的名稱(不要超過31 個字符),at-tach_adapter和detach_client字段為函數指針,這兩個函數在I2C設備注冊的時候會自動調用,需要自己實現這兩個函數。
上面定義的i2c_driver對象,抽象為一個I2C的驅動模型,提供對I2C設備的探測和注銷方法,接下來就是要定義i2c_client 結構體,其代表著一個具體的I2C 設備,該結構體有一個data指針,可以指向任何私有的設備數據,在復雜點的驅動中可能會用到。
每一個I2C設備芯片,都通過硬件連接設定好了該設備的I2C設備地址。因此,I2C設備的探測一般是靠設備地址來完成的。那么,首先要在驅動代碼中聲明你要探測的I2C設備地址列表以及一個宏,示例如下:
有了i2c_client結構體代表了具體的設備和設備ID后就可以實現attach_adapter 和detach_client 函數。這兩個函數是系統自動調用的,它的實現是有一定的框架的,可以在linux內核源碼的驅動例子中找到,由于代碼過長這里不做具體的分析。針對不同的設備函數的實現會略有不同,一般attach_adapte需要完成的工作是對i2c_client結構體成員賦值和調用接口函i2c_attach_cli-ent把設備掛接到適配其中。而detach_client 函數則是完成相反的工作。
最后的一步是編寫模塊的初始化與退出函數把驅動加進I2C驅動子系統中,示例可以是:
至此,I2C設備的驅動已經完成了,但是到了這一步本驅動并沒有實際的用處,它僅僅提供的是一個設備驅動程序的管理框架,所以必須還要進行兩方面的補充。
第一方面是,利用I2C總線讀寫外部芯片的控制/狀態寄存器;第二方面是,向應用層提供I2C設備的讀寫接口,令應用程序可以對設備節點的讀寫實現對I2C具體物理設備的讀寫。為了實現I2C 設備寄存器的讀寫操作,必須要用到Linux的I2C子系統提供的讀寫接口函數:
利用這兩個函數根據芯片的讀寫時序進行封裝,就可以讀寫芯片內部的寄存器,以寫芯片寄存器為例,必須寫往總線上寫寄存器的地址,然后寫入要往寄存器里寫入的數據,示例代碼如下所示。讀寄存器的時序則是則是先寫入要讀寄存器的地址,然后接受總線上的數據,區別不大,不做示例。
要想向應用層提供讀寫接口,則必須再對I2C設備驅動進行一次簡單字符設備驅動的封裝,將I2C設備作為一個簡單字符設備,依次實現字符設備文件操作函數結構體file_operation 里面的函數指針所對應的接口函數,這里只給出了大體的框架,具體的實現對于不同的芯片有很大的不同。
定義一個字符設備結構體cdev,將I2C 設備當做一個普通的字符設備處理。
定義一個文件操作函數結構體,填寫里面函數指針,指出設備操作所對應的具體函數,一般的例子是:
接著就是編寫file_operations所對應的具體函數。
最后一步是在模塊的初始化和退出函數中增加對簡單字符設備的注冊和注銷操作,包括設備號申請與注銷,設備注冊與注銷兩方面。
至此,將編譯好的模塊加載進內核后就可以在用戶空間利用文件系統的API對設備文件進行各種操作。
4 結語
I2C總線在電子系統設計中是十分普遍的一種接口技術,而Linux又是十分流行的嵌入式操作系統。編寫嵌入式Linux下I2C總線設備的驅動驅動程序是嵌入式開發中十分重要的一項技術,不容忽視。本文首先講述了Linux系統I2C設備驅動程序的總體框架,然后給出了編寫I2C設備驅動的總體思路與框架,希望給讀者理清思路,加深對編寫I2C設備驅動的理解。總而言之,利用I2C總線通信可以達到很高的速率,而且總線上可以掛接多個節點,每個節點都由惟一的地址確定。
linux操作系統文章專題:linux操作系統詳解(linux不再難懂)
評論