首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ok6410学习笔记(14.platform平台总线驱动模型)

ok6410学习笔记(14.platform平台总线驱动模型)

本节知识点:基础知识:1.把最近学的东西串串线,首先学的是kobject,这个东西是在sysfs文件系统中,创建一个目录的基类,在这点上linux有着面向对象的编程思想,也就是什么kset,总线,platform都是继承了kobject的特性,在sys目录中创建目录。
2.学习kobject和kset是为了学习总线设备驱动模型的,因为创建总线,设备,驱动实际就是在/sys/bus目录中创建kobject,其实质也是kobject和kset完成的。
3.platform平台总线驱动模型,其实就是linux内核把,上节那个总线设备驱动模型进行了封装。把本应该自己创建的一条总线,变成了linux替你创建好的一条platform总线而已。
4.这里有一个很迷茫的一点就是,这个platform平台总线驱动模型到底有什么用??我现在的理解是这样的,希望在读了宋宝华的linux设备驱动之后还有体会。
    第一:platform将设备本身的资源注册进入内核,由内核统一管理,在驱动程序使用这些资源的时候使用统一的接口,提高驱动的可移植性。
    第二:这是一个很常用的驱动模型,也叫框架吧,linux设备驱动  叫他是工程中的驱动。
    第三:这模型仅仅是将驱动和设备分开,然后当有新设备或者新驱动的时候,去匹配,匹配成功再调用driver模块中的probe函数,完成具体的驱动程序。也就是说platform仅仅是一个框架,功能驱动在probe函数里面,是字符驱动,还是块驱动啊 都是在probe函数里面完成。
驱动结构及重要函数:

在platform_device里面:
1.在struct platform_device结构体中  填写设备名称,id,设备资源结构,或者通过struct platform_device *platform_device_alloc(const char *name,int id)函数来定义platform_device
2.platform_device_register(&led_dev)注册平台设备进入内核
在platform_driver里面:
1.在struct platform_driver led_drv={

.probe=led_drv_probe,

.remove=led_drv_remove,

.driver={

.owner=THIS_MODULE,

.name="plat_led",  //platform总线  里面驱动的名字   这个名字要和设备的名字一样

}
};里面定义  驱动名字 ,probe函数等

2.利用platform_driver_register(&led_drv)  注册驱动进入内核

其实国嵌在这里的时候看了内核代码的,有几个结论如下:
1.platform总线,就是内核定义的一条总线,并且将他的设备和驱动进行了封装
2.找到了bus_for_each_dev,  这个函数是总线在不断的轮询总线中的dev设备,然后通过match函数,判断设备和驱动是否匹配
3.platform的match就是比较platform_device.name和platform_driver.driver.name

本节代码:plat-dev.c:
[cpp] view plaincopy


  • #include <linux/device.h>
  • #include <linux/module.h>
  • #include <linux/kernel.h>
  • #include <linux/init.h>
  • #include <linux/string.h>
  • #include <linux/init.h>
  • #include <linux/platform_device.h>

  • MODULE_AUTHOR("Hao");  
  • MODULE_LICENSE("Dual BSD/GPL");  

  • struct platform_device led_dev={  
  •     .name="plat_led",  //platform总线  里面设备的名字   这个名字要和驱动的名字一样
  •     .id=-1,   
  • };  

  • static
    int __init platform_led_dev_init(void)  
  • {  
  •         int ret=0;  
  •         ret=platform_device_register(&led_dev);  
  •         if(ret)  
  •         {  
  •                 printk("platform_device_register failed!!\n");  
  •         }  
  •         return ret;  
  • }  

  • static
    void __exit platform_led_dev_exit(void)  
  • {  
  •         platform_device_unregister(&led_dev);  
  • }  

  • module_init(platform_led_dev_init);  
  • module_exit(platform_led_dev_exit);  


plat-drv.c:
[cpp] view plaincopy


  • #include <linux/device.h>
  • #include <linux/module.h>
  • #include <linux/kernel.h>
  • #include <linux/init.h>
  • #include <linux/string.h>
  • #include <linux/init.h>
  • #include <linux/platform_device.h>

  • MODULE_AUTHOR("Hao");  
  • MODULE_LICENSE("Dual BSD/GPL");  


  • static
    int led_drv_probe(struct platform_device *dev)   //这里面写功能驱动
  • {  
  •         printk("Driver found device which my driver can handle!\n");  
  •     return 0;  
  • }  

  • static
    int led_drv_remove(struct platform_device *dev)  
  • {  
  •         printk("Driver found device unpluged!\n");  
  •     return 0;  
  • }  

  • struct platform_driver led_drv={  
  •         .probe=led_drv_probe,  
  •         .remove=led_drv_remove,  
  •         .driver={  
  •                     .owner=THIS_MODULE,  
  •                     .name="plat_led",  //platform总线  里面驱动的名字   这个名字要和设备的名字一样
  •             }  
  • };  


  • static
    int __init platform_led_drv_int(void)  
  • {  
  •         return platform_driver_register(&led_drv);  
  • }  


  • static
    void __exit platform_led_drv_exit(void)  
  • {  
  •         platform_driver_unregister(&led_drv);  
  • }  


  • module_init(platform_led_drv_int);  
  • module_exit(platform_led_drv_exit);  

返回列表