Linux Platform Device and Driver

 

參考資料:

linux-2.6.24/Documentation/driver-model/platform.txt

http://blog.chinaunix.net/u2/60011/showart_1018502.html

《platform _device platform_driver 註冊過程》

http://www.eetop.cn/blog/html/45/11145-676.html

http://blog.csdn.net/unbutun/archive/2009/03/25/4023313.aspx

 

    從 Linux 2.6 起引入了一套新的驅動管理和註冊機制 :platform_device platform_driver Linux 中大部分的設備驅動,都可以使用這套機制 , 設備用 platform_device 表示,驅動用 platform_driver 進行註冊。   

      Linux platform driver 機制和傳統的 device driver 機制 ( 通過 driver_register 函數進行註冊 ) 相比,一個十分明顯的優勢在於 platform 機制將設備本身的資源註冊進內核,由內核統一管理,在驅動程序中使用這些資源時通過 platform device 提供的標準接口進行申請並使用 。這樣提高了驅動和資源管理的獨立性,並且擁有較好的可移植性和安全性 ( 這些標準接口是安全的 )

    platform 機制的本身並不複雜,由兩部分組成: platform _ device 和  platform _ driver

    通過 Platform 機制開發發底層驅動的大致流程爲 定義 platform_device -> 註冊 platform_device -> 定義 platform_driver -> 註冊 platform_driver

 

數據結構


2.6 內核中 platform 設備用結構體 platform_device 來描述,

該結構一個重要的元素是 resource ,該元素存入了最爲重要的設備資源信息,

實際上是對地址範圍及其屬性的一個描述。最後幾個用於樹型結構的指針是內核用於管理所有資源的。

 

定義resource


下面舉 s3c2410 平臺的 i2c 驅動作爲例子來說明:

       這裏定義了兩組resource,它描述了一個I2C設備的資源,第1組描述了這個I2C設備所佔用的總線地址範圍,IORESOURCE_MEM表示第 1組描述的是內存類型的資源信息,第2組描述了這個I2C設備的中斷號,IORESOURCE_IRQ表示第2組描述的是中斷資源信息。設備驅動會根據 flags來獲取相應的資源。

 

platform_device

 

 

        定義好了platform_device結構體後就可以調用函數platform_add_devices向系統中添加該設備 了,之後可以調用 platform_driver_register()進行設備註冊 。要注意的是,這裏的platform_device設備的註冊過程必須在相應設備驅動加載之前被調用,即執行platform_driver_register之前,原因是因爲驅動註冊時需要匹配內核中所以已註冊的設備名

 

platform_driver

 

       在驅動初始化函數中調用函數platform_driver_register()註冊platform_driver,需要注意的是 s3c_device_i2c結構中name元素和s3c2410_i2c_driver結構中driver.name必須是相同的,這樣在 platform_driver_register()註冊時會對所有已註冊的所有platform_device中的name和當前註冊的 platform_driver的driver.name進行比較,只有找到相同的名稱的platfomr_device才能註冊成功,當註冊成功時會調用platform_driver結構元素probe函數指針,這裏就是s3c24xx_i2c_probe,當進入probe函數後,需要獲取設備的資源信息,常用獲取資源的函數主要是:


struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
根據參數type所指定類型,例如IORESOURCE_MEM,來獲取指定的資源。

 

那什麼情況使用 platform driver 機制編寫驅動


     我的理解是隻要和內核本身運行依賴性不大的外圍設備 ( 換句話說只要不在內核運行所需的一個最小系統之內的設備 ), 相對獨立的 , 擁有各自獨自的資源 (addresses and IRQs) 都可以用 platform_driver 實現。如: lcd,usb,uart 等,都可以用 platfrom_driver 寫,而 timer,irq 等最小系統之內的設備則最好不用 platfrom_driver 機制,實際上內核實現也是這樣的。

 

/* 以下爲本人註解:

1、更多的概況瞭解,可參考文檔 Documentation/driver-model/platform.txt

2、在 Understanding the Linux Kernel一書的第13.1.1.1節中有這樣一段話

      “... 儘管訪問I/O端口很容易, 檢測哪個I/O端口已被分配給I/O設備卻並非易事. 對基於ISA總線(譯註:原始IBM PC採用的總線)的系統來說尤其如此. 通常設備驅動必須盲目地寫數據到一些I/O端口來探測設備的存在, 然而,如果該端口已經被另外一種設備佔用, 這樣的操作就可能導致系統崩潰...

        以下爲文檔platform.txt中的話:

        “... 不提倡這種驅動方式. 假如你在升級這樣一個驅動, 請盡力把設備列舉從驅動中轉移到更合適的地方. 這樣做很賺, 因爲驅動程序一開始就處在"正常模式", 可以直接使用由即插即用(PNP)設置或平臺設備設置代碼所創建的設備..

struct platform_ device *platform_device_alloc(const char *name, int id);

你可以用 platform_device_alloc _alloc( )來動態地給設備分配空間, 然後在用platform_device_register()加上一些資源來初始化該設備.

經常也用另外一個更好的解決辦法:

struct platform_device *platform_device_register_simple(const char *name, int id,struct resource *res, unsigned int nres);

你可以用platform_device_register_simple()一次完成分配空間和註冊設備的任務, 設備命名和驅動綁定

        所以,比較老的現成的較多的驅動中,我們可以看到 request_mem_region()和 request_irq()等申請device資源,而看到上面的話後,在最新的驅動中,應儘量的採用platform_device_alloc等platform機制的函數實現。

   

 

發佈了10 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章