天天看點

linux裝置驅動開發詳解_Linux裝置驅動開發 - 平台裝置驅動

linux裝置驅動開發詳解_Linux裝置驅動開發 - 平台裝置驅動

Linux2.6的核心中引入了一種新的裝置驅動模型-平台(platform)裝置驅動,平台裝置驅動分為平台裝置(platform_device)和平台驅動(platform_driver),平台裝置的引入使得Linux裝置驅動更加便于移植。

一、平台裝置

平台裝置結構體:

struct platform_device {

const char * name;

int id;

struct device dev;

u32 num_resources;

struct resource * resource;

const struct platform_device_id *id_entry;

struct pdev_archdata archdata;

};

平台裝置主要是提供裝置資源和平台資料給平台驅動,resource為裝置資源數組,類型有IORESOURCE_IO、IORESOURCE_MEM、IORESOURCE_IRQ、IORESOURCE_DMA、IORESOURCE_DMA。下面是一個網卡晶片DM9000的外設資源:

static struct resource dm9000_resources[] = {

[0] = {

.start = S3C64XX_PA_DM9000,

.end = S3C64XX_PA_DM9000 + 3,

.flags = IORESOURCE_MEM,

},

[1] = {

.start = S3C64XX_PA_DM9000 + 4,

.end = S3C64XX_PA_DM9000 + S3C64XX_SZ_DM9000 - 1,

.flags = IORESOURCE_MEM,

},

[2] = {

.start = IRQ_EINT(7),

.end = IRQ_EINT(7),

.flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,

},

};

dm9000_resources裡面有三個裝置資源,第一個為IORESOURCE_MEM類型,指明了第一個資源記憶體的起始位址為S3C64XX_PA_DM9000結束位址為S3C64XX_PA_DM9000 + 3,第二個同樣為IORESOURCE_MEM類型,指明了第二個資源記憶體的起始位址為S3C64XX_PA_DM9000 + 4結束位址為S3C64XX_PA_DM9000 + S3C64XX_SZ_DM9000 - 1,第三個為IORESOURCE_IRQ類型,指明了中斷号為IRQ_EINT(7)。

struct device {

struct device *parent;

struct device_private *p;

struct kobject kobj;

const char *init_name;

struct device_type *type;

struct mutex mutex;

struct bus_type *bus;

struct device_driver *driver;

void *platform_data;

...

};

struct device結構體裡面有一個重要成員platform_data,它是平台裝置和平台驅動進行資料傳遞的重要成員。

平台裝置注冊:

1 int platform_device_register(struct platform_device *pdev);

platform_device_register()會對平台裝置進行相應的初始化之後調用platform_device_register()函數把它添加到子系統中。

平台裝置登出:

1 void platform_device_unregister(struct platform_device *pdev);

platform_device_unregister()函數釋放裝置資源之後從子系統中将其移除。

平台裝置模闆:

static struct resource xxx_resource =

{

[0] =

{

.start = ...,

.end = ...,

.flags = ...,

},

[1] =

{

...

}

...

};

static struct xxx_plat_data xxx_data =

{

...

};

static struct platform_device xxx_platform_device =

{

.name = NAME,

.num_resources = ARRAY_SIZE(xxx_resource),

.resource = xxx_resource,

.dev =

{

.platform_data = &xxx_data,

}

};

static int __init xxx_device_init(void)

{

...

platform_device_register(&xxx_platform_device);

...

}

static void __exit xxx_device_exit(void)

{

...

platform_device_unregister(&xxx_platform_device);

...

}

二、平台驅動

平台驅動結構體:

struct platform_driver {

int (*probe)(struct platform_device *);

int (*remove)(struct platform_device *);

void (*shutdown)(struct platform_device *);

int (*suspend)(struct platform_device *, pm_message_t state);

int (*resume)(struct platform_device *);

struct device_driver driver;

const struct platform_device_id *id_table;

};

平台驅動結構體driver成員裡面的name必須與平台裝置結構體裡面的name成員一緻,在系統注冊一個裝置的時候,會通過裝置結構體裡面的name成員和平台驅動driver裡面的name成員比對,當比對成功則調用平台驅動的probe函數,

通常在probe函數中擷取平台裝置的資源和私有資料并進行裝置的初始化。

擷取裝置資源:

1 struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);

platform_get_resource()函數用于擷取平台裝置的資源,dev為要平台裝置,type為平台裝置資源類型,num為平台資源号(比如同一個資源有兩個則資源号為0,1)。

平台驅動注冊:

1 int platform_driver_register(struct platform_driver *drv);

platform_driver_register()函數完成平台驅動的注冊,在驅動子產品加載時調用。

平台驅動登出:

1 void platform_driver_unregister(struct platform_driver *drv);

platform_driver_unregister()函數完成平台驅動的登出,在驅動子產品解除安裝時調用。

平台驅動模闆:

static int __devinit xxx_probe(struct platform_device *pdev)

{

struct xxx_plat_data *pdata = pdev->dev.platform_data;

platform_get_resource(pdev,xxx,x);

...

}

static struct platform_driver xxx_platform_driver =

{

.probe = xxx_probe,

.remove = __devexit_p(xxx_remove),

.driver =

{

.name = NAME,

...

},

...

};

static int __init xxx_driver_init(void)

{

...

platform_driver_register(&xxx_platform_driver);

...

}

static void __exit xxx_driver_exit(void)

{

...

platform_driver_unregister(&xxx_platform_driver);

...

}

嵌入式物聯網資料分享交流群:707159742 入群有全套學習視訊資料電子書免費贈送!

參考資料:

嵌入式開發直播課 - 精通Linux裝置驅動模型-Kobject​www.makeru.com.cn 嵌入式Linux驅動 - linux裝置驅動開發必備技能 - 裝置樹​www.makeru.com.cn 嵌入式底層開發 - linux驅動開發必備:全面認識裝置樹​www.makeru.com.cn

繼續閱讀