zoukankan      html  css  js  c++  java
  • 内核中的 platform总线

        一个现实的Linux 设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI、USB、I2C、SPI 等的设备而言,这自然不是问题,但是在嵌入式系统里面,SoC 系统中集成的独立的外设控制器、挂接在SoC 内存空间的外设等确不依附于此类总线。基于这一背景,Linux 发明了一种虚拟的总线,称为platform 总线
            SOC系统中集成的独立外设单元(I2C,LCD,SPI,RTC等)都被当作平台设备来处理,而它们本身是字符型设备。
            从Linux2.6内核起,引入一套新的驱动管理和注册机制:platform_device 和 platform_driver 。Linux 中大部分的设备驱动,都可以使用这套机制,设备用 platform_device 表示;驱动用platform_driver 进行注册

          

    一.platform_device

        在2.6内核中platform设备用结构体platform_device来描述,

        该结构体定义在kernelincludelinuxplatform_device.h中,
        

        struct platform_device {

               const char      * name;  //名

               int           id;    

               struct device   dev;      //内嵌设备

               u32         num_resources;   //资源个数

               struct resource       * resource;   //资源结构体

               struct platform_device_id      *id_entry;

               struct pdev_archdata     archdata;

        };

     

     在使用platform设备之前需要注册和使用完之后需要注销:platform_driver 的注册与注销:

         platform_driver_register()
         platform_driver_unregister()

        device文件模块代码:

          

      1 #include <linux/init.h>
      2 #include <linux/thread_info.h>
      3 #include <linux/module.h>
      4 #include <linux/sched.h>
      5 #include <linux/errno.h>
      6 #include <linux/kernel.h>
      7 #include <linux/module.h>
      8 #include <linux/slab.h>
      9 #include <linux/input.h>
     10 #include <linux/init.h>
     11 #include <linux/serio.h>
     12 #include <linux/delay.h>
     13 #include <linux/clk.h>
     14 #include <linux/miscdevice.h>
     15 #include <linux/io.h>
     16 #include <linux/ioport.h>
     17 #include <linux/vmalloc.h>
     18 #include <linux/dma-mapping.h>
     19 #include <linux/export.h>
     20 #include <linux/gfp.h>
     21 #include <linux/cdev.h>
     22 
     23 #include <asm/dma-mapping.h>
     24 #include <asm/uaccess.h>
     25 
     26 #include <linux/gpio.h>
     27 #include <mach/gpio.h>
     28 #include <plat/gpio-cfg.h>
     29 #include <linux/completion.h>
     30 #include <linux/miscdevice.h>
     31 #include <linux/platform_device.h>
     32 
     33 MODULE_LICENSE("GPL");
     34 MODULE_AUTHOR("bunfly");
     35 
     36 void test_release(struct device *dev)
     37 {
     38 }
     39 
     40 struct platform_device  test_device = {
     41     .name = "test_platform",
     42     .dev = {
     43         .release =  test_release,
     44     },
     45 };
     46 
     47 int test_init(void)
     48 {
     49     printk("device had regiser!
    ");
     50     return platform_device_register(&test_device);
     51     //注册platform设备
     52 }
     53 
     54 void test_exit(void)
     55 {
     56     platform_device_unregister(&test_device);
     57 }
     58 
     59 module_init(test_init);
     60 module_exit(test_exit);
     61 
    ~                                                                                                                                                                                                            
    ~                                                                                                                                                                                                            
    ~                                                                                                                                                                                                            
    ~                                                                                                                                                                                                            
    ~     

    二.paltform_driver

         platform_driver 结构体     在  include/linux/platform_device.h目录下

        

        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;        //内嵌设备驱动

               struct platform_device_id *id_table;  //驱动支持项

          };

        其中,比较重要的就是probe和remove函数。

        driver代码如下:

          

     1 #include <linux/init.h>
      2 #include <linux/thread_info.h>
      3 #include <linux/module.h>
      4 #include <linux/sched.h>
      5 #include <linux/errno.h>
      6 #include <linux/kernel.h>
      7 #include <linux/module.h>
      8 #include <linux/slab.h>
      9 #include <linux/input.h>
     10 #include <linux/init.h>
     11 #include <linux/serio.h>
     12 #include <linux/delay.h>
     13 #include <linux/clk.h>
     14 #include <linux/miscdevice.h>
     15 #include <linux/io.h>
     16 #include <linux/ioport.h>
     17 #include <linux/vmalloc.h>
     18 #include <linux/dma-mapping.h>
     19 #include <linux/export.h>
     20 #include <linux/gfp.h>
     21 #include <linux/cdev.h>
     22 
     23 #include <asm/dma-mapping.h>
     24 #include <asm/uaccess.h>
     25 
     26 #include <linux/gpio.h>
     27 #include <mach/gpio.h>
     28 #include <plat/gpio-cfg.h>
     29 #include <linux/completion.h>
     30 #include <linux/miscdevice.h>
     31 #include <linux/platform_device.h>
     32 
     33 MODULE_LICENSE("GPL");
     34 MODULE_AUTHOR("bunfly");
     35 
     36 
     37 
     38 int myopen(struct inode *no, struct file *fp)
     39 {
     40     return 0;
     41 }
     42 
     43 int myrelease(struct inode *no, struct file *fp)
     44 {
     45     return 0;
     46 }
     47 
     48 
     49 int mywrite(struct file *fp, char *buf, int size, int *off)
     50 {
     51 
     52     printk("KERNEL: write....
    ");
     53 
     54     return 0;
     55 }
     56 
     57 int myread(struct file *fp, char *buf, int size, int *off)
     58 {
     59 
     60     return 0;
     61 }
     62 
     63 struct file_operations  myfops = {
     64     .open = myopen,
     65     .release = myrelease,
     66     .write = mywrite,
     67     .read = myread,
     68 };
     69 
     70 struct miscdevice  mymisc = {
     71     .minor = 22,
     72     .name = "mymisc",
     73     .fops = &myfops,
     74 };
     75 
     76 int test_probe(struct platform_device *pdev)
     77 {
     78     int ret = 0;
     79     misc_register(&mymisc);
     80     printk("match sucessed!
    ");
     81     return 0;
     82 }
     83 //注册设备驱动
     84 int test_remove(struct platform_device *pdev)
     85 {
     86     misc_deregister(&mymisc);
     87     return 0;
     88 }
     89 
     90 struct platform_driver  test_driver = {
     91     .driver = {
     92             .owner = THIS_MODULE,
     93             .name = "test_platform",
     94     },
     95     .probe = test_probe,
     96     .remove = test_remove,
     97 };
     98 int test_init(void)
     99 {
    100     return platform_driver_register(&test_driver);
    101     //驱动注册
    102 }
    103 
    104 void test_exit(void)
    105 {
    106     platform_driver_unregister(&test_driver);
    107     //驱动注销
    108 }
    109 
    110 module_init(test_init);
    111 module_exit(test_exit);
    112 

    三.platform 匹配

        platform通过device和driver的name名字来匹配,所以,device和driver的name一定要一样才可以匹配成功,当匹配成功之后,就会到驱动的probe函数里面区探测设备;

         起到的左右大概是:

          

        在这里,我们先插入driver模块,再插入device模块,可以在   

                /sys/bus/platform/devices/目录下查看到设备的插入情况:

        

            

        接下来:插入driver模块:

        

        发现,插入驱动模块的时候,自动调用了probe函数,打印出了里面的一句话;

     总结:

          platform总线是虚拟总线,通过name,起到platform_device和platform_driver的匹配工作

       ,当匹配成功之后就会调用driver里面的probe函数添加设备!          

  • 相关阅读:
    HTML 5 使用 FileReader、FormData实现文件上传
    【JS深入学习】——事件代理/事件委托
    【JS深入学习】——函数创建和重载
    Yii
    YII简单的基于角色的访问控制
    怎样在Yii中显示静态页
    Yii framework 应用总结小窍门(转)
    Yii PHP 框架分析(四)
    Yii PHP 框架分析(三)
    Yii PHP 框架分析(二)
  • 原文地址:https://www.cnblogs.com/hongzhunzhun/p/4539306.html
Copyright © 2011-2022 走看看