platform驱动学习

来源:互联网 发布:sql查询命令 编辑:程序博客网 时间:2024/05/20 16:32


platform实现的是一种总线设备驱动模型,所谓的总线是虚拟的总线,挂在这个虚拟总线上的设备和驱动可以被内核以platform的机制探测到并使用probe进行初始化驱动。
platform的概念和字符设备驱动,块设备驱动,网卡驱动是两码事,前者是内核驱动的一种管理方式,后者是驱动的实现方式。字符设备驱动,块设备驱动,网卡驱动都可以以platform的机制交给内核来管理。


platform驱动模型三个对象:platform总线、platform设备、platform驱动。
platform总线对应的内核结构:struct bus_type-->它包含的最关键的函数:match()
platform设备对应的内核结构:struct platform_device-->注册:platform_device_register(unregiste)
platform驱动对应的内核结构:struct platform_driver-->注册:platform_driver_register(unregiste)


我们关心的是platform_device和platform_driver。
platform_device或platform_driver进行注册的时候,总线会用match函数来进行两者的匹配,如果两者都已经注册并name一样,则匹配成功并调用platform_driver里的probe函数初始化,否则不调用,等到两者都进行注册成功后并匹配成功,绑定成功后调用。


下面就先了解platform_device和platform_driver各包括哪些内容,然后看如何实现他完成一个设备驱动。


一,platform_device和platform_driver的定义和内容
1,platform_device


static struct resource mini2440_led_resource[] = {
        [0] = {
                .start = 0x56000010,//资源的起始地址,物理地址,如LED灯所在的gpio口的物理地址
                .end   = 0x56000010 + 12,
                .flags = IORESOURCE_MEM
        },
};
static struct platform_device mini2440_platform_device_led = {
        .name           = " mini2440_led_platform_device_driver ",//要和platform_driver里的name一致
        .id             = -1,//单个设备时为-1,多个设备时,体现为name.0,name.1.。。。,对于platform_driver来说,一个platform_driver对应多个id不同的platform_device工作。
注:设备名与id   The platform_device.dev.bus_id is the canonical name for the devices. It's built from two components:       * platform_device.name ... which is also used to for driver matching.         * platform_device.id ... the device instance number, or else "-1" to indicate there's only one.   These are concatenated, so name/id "serial"/0 indicates bus_id "serial.0", and "serial/3" indicates bus_id "serial.3"; both would use the platform_driver named "serial".  While "my_rtc"/-1 would be bus_id "my_rtc" (no instance id) and use the platform_driver called "my_rtc". 
        .num_resources  = ARRAY_SIZE(mini2440_led_resource),//资源数量
        .resource       =  mini2440_led_resource ,//代表着设备在物理上占有的资源,如物理地址,中断。在platform_driver里可以通过platform_get_resource获取来使用,但是一般要用ioremap映射到虚拟地址。
        .dev            = {
              .release  = mini2440_led_platform_device_release,
     .platform_data= uart8250_data,//一般是已经定义好的全局变量,是设备的私有数据,提供给platform_driver使用,如基本信息,名称
        },
};


2,platform_driver 
static struct platform_driver mini2440_led_platform_driver = {
.probe  = mini2440_led_probe,//platform_driver的最重要函数,用来实现一些初始化的内容,如注册设备节点,获取设备resource资源,注册file_operations,
.remove = __devexit_p(mini2440_led_remove),
.driver = {
.name = "mini2440_led_platform_device_driver",
.owner = THIS_MODULE,
}
};


二,platform设备驱动整体实现思路



1,注册platform_device:platform_device_register(unregiste),如果使用硬件资源(硬件的物理内存,中断),在resource里体现;如果要传递私有数据,在platform_data里添加。
    实现方式最好是编写单独模块,然后insmod加载。
2,注册platform_driver:platform_driver_register(unregiste),操作的对象是platform_device里注册的资源,内容。

3,调用。如有file_operations,像普通的字符设备驱动一样使用open,write,read。


参考文章
1,platform驱动模型编程总结(基于mini2440平台的LED驱动)  http://blog.sina.com.cn/s/blog_6b94d5680101cn0t.html
2,Linux Platform驱动程序框架解析  http://wenku.baidu.com/link?url=xFlYzkqnwlMnX44DDGVOiSQx7zf1R2cB8uX6JQEtf9LiRx6e3Y-QtKu1U9Oxwl49cNPbWSfpdNRQD6Just4rQzWJo8-YAnHQP6X6Bz76lLG
3,platform设备驱动精讲,例程详细  http://wenku.baidu.com/link?url=o-DEMNiAK3I-sew6TFy2ttQyJoPa_EcPPkJj5IlnH2VAdl_0fCXbhPGmrsZkzBxPcD_aXBom0KH5aGsN13nrH9PfZNkUtk6UHBaIELKMYJC

0 0
原创粉丝点击