首先介紹一下註冊乙個驅動的步驟:
1、定義乙個platform_driver結構
2、初始化這個結構,指定其probe、remove等函式,並初始化其中的driver變數
3、實現其probe、remove等函式
看platform_driver結構,定義於include/linux/platform_device.h檔案中:
struct platform_driver
;
可見,它包含了裝置操作的幾個功能函式,同樣重要的是,它還包含了乙個device_driver結構。剛才提到了驅動程式中需要初始化這個變數。下面看一下這個變數的定義,位於include/linux/device.h中:
struct device_driver
;
需要注意這兩個變數:name和owner。那麼的作用主要是為了和相關的platform_device關聯起來,owner的作用是說明模組的所有者,驅動程式中一般初始化為this_module。
下面是乙個platform_driver的初始化例項:
static
struct platform_driver s3c2410iis_driver =,}
;
上面的初始化是乙個音訊驅動的例項。注意其中的driver這個結構體,只初始化了其name和owner兩個量。接著看一下和driver相關的另乙個結構,定義如下:
struct platform_device
;
該結構中也有乙個name變數。platform_driver從字面上來看就知道是裝置驅動。裝置驅動是為誰服務的呢?當然是裝置了。platform_device就描述了裝置物件。下面是乙個具體的例項:
struct platform_device s3c_device_iis =};
它的name變數和剛才上面的platform_driver的name變數是一致的,核心正是通過這個一致性來為驅動程式找到資源,即platform_device中的resource。這個結構的定義如下,位於include/linux/ioport.h中:
struct resource
;
下面是乙個具體的例項:
static
struct resource s3c_iis_resource=
};
這個結構的作用就是告訴驅動程式裝置的起始位址和終止位址和裝置的埠型別。這裡的位址指的是實體地址。
另外還需要注意platform_device中的device結構,它詳細描述了裝置的情況,定義如下:
struct device
;
上面把驅動程式中涉及到的主要結構都介紹了,下面主要說一下驅動程式中怎樣對這個結構進行處理,以使驅動程式能執行。
緊接上面介紹的資料結構,介紹驅動程式的具體實現過程。
相信大家都知道module_init()這個巨集。驅動模組載入的時候會呼叫這個巨集。它接收乙個函式為引數,作為它的引數的函式將會對上面提到的platform_driver進行處理。看乙個例項:假如這裡module_init要接收的引數為s3c2410_uda1341_init這個函式,下面是這個函式的定義:
static
int __init s3c2410_uda1341_init(
void
)
注意函式體的最後一行,它呼叫的是platform_driver_register這個函式。這個函式定義於driver/base/platform.c中,原型如下:
int platform_driver_register(struct platform_driver *drv)
它的功能就是為上面提到的plarform_driver中的driver這個結構中的probe、remove這些變數指定功能函式。
到目前為止,核心就已經知道了有這麼乙個驅動模組。核心啟動的時候,就會呼叫與該驅動相關的probe函式。我們來看一下probe函式實現了什麼功能。
probe函式的原型為
int ***_probe(struct platform_device *pdev)
即它的返回型別為int,接收乙個platform_device型別的指標作為引數。返回型別就是我們熟悉的錯誤**了,而接收的這個引數呢,我們上面已經說過,驅動程式為裝置服務,就需要知道裝置的資訊。而這個引數,就包含了與裝置相關的資訊。
probe函式接收到plarform_device這個引數後,就需要從中提取出需要的資訊。它一般會通過呼叫核心提供的platform_get_resource和platform_get_irq等函式來獲得相關資訊。如通過platform_get_resource獲得裝置的起始位址後,可以對其進行request_mem_region和ioremap等操作,以便應用程式對其進行操作。通過platform_get_irq得到裝置的中斷號以後,就可以呼叫request_irq函式來向系統申請中斷。這些操作在裝置驅動程式中一般都要完成。
在完成了上面這些工作和一些其他必須的初始化操作後,就可以向系統註冊我們在/dev目錄下能看在的裝置檔案了。舉乙個例子,在音訊晶元的驅動中,就可以呼叫register_sound_dsp來註冊乙個dsp裝置檔案,lcd的驅動中就可以呼叫register_framebuffer來註冊fb裝置檔案。這個工作完成以後,系統中就有我們需要的裝置檔案了。而和裝置檔案相關的操作都是通過乙個file_operations 來實現的。在呼叫register_sound_dsp等函式的時候,就需要傳遞乙個file_operations 型別的指標。這個指標就提供了可以供使用者空間呼叫的write、read等函式。file_operations結構的定義位於include/linux/fs.h中,列出如下:
struct file_operations
;
到目前為止,probe函式的功能就完成了。
當使用者開啟乙個裝置,並呼叫其read、write等函式的時候,就可以通過上面的file_operations來找到相關的函式。所以,使用者驅動程式還需要實現這些函式,具體實現和相關的裝置有密切的關係,這裡就不再介紹了。
Linux 平台裝置驅動模型
linux 平台裝置驅動模型 一。平台匯流排概述 1.平台匯流排 platform bus 是linux2.6核心加入的一種虛擬匯流排,其優勢在於採用了匯流排的模型對裝置與驅動進行了管理,這樣提高了程式的可移植性 二。平台裝置 1.平台裝置使用structplatform device來描述 str...
linux 驅動 7 平台裝置驅動
目錄7.2 平台裝置 7.3 平台驅動 參考區分裝置驅動模型和平台裝置驅動模型。裝置驅動模型可以理解為匯流排 裝置 驅動。平台裝置驅動模型就是那些 linux 核心管理沒有物理匯流排 即是不需要特殊時序控制的裝置 也是linux核心沒有自動建立相應驅動匯流排的裝置型別 的裝置的一套 linux平台匯...
Linux平台匯流排驅動裝置模型
platform匯流排是一種虛擬的匯流排,相應的裝置則為platform device,而驅動則為platform driver。linux 2.6的裝置驅動模型中,把i2c rtc lcd等都歸納為platform device。匯流排將裝置和驅動繫結,在系統每註冊乙個裝置的時候,會尋找與之匹配的...