zoukankan      html  css  js  c++  java
  • Linux 自定义总线类型

    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/device.h>
    
    // 按照 platform_device 格式定义
    struct test_dev {
      char *name;
      // 必须要有父类,注册时会将父类注册到链表
      struct device dev;
      // 其他成员自定义
    };
    
    // 按照 platform_driver 格式定义
    struct test_drv {
      // 必须要有父类,注册时会将父类注册到链表
      struct device_driver driver;
      // 其他成员自定义
    };
    
    void mydev_release(struct device *dev)
    {
      // 防止 rmmod 时报错
    }
    
    // 匹配函数
    int my_bus_match(struct device *dev, struct device_driver *drv)
    {
      struct test_dev *testdev;
    
      // 优先使用 drv 父类中的 name 和 dev 中的 name 比较匹配
      testdev = container_of(dev, struct test_dev, dev);
    
      if (strcmp(drv->name, testdev->name) == 0)
      {
        printk("match ok!
    ");
        return 1;
      }
    
      // 如果 drv 父类中的 name 没有定义,再使用 drv 中的 name 比较匹配
      // 代码忽略
      return 0;
    }
    
    // 匹配成功后执行的函数
    int my_bus_probe(struct device *dev)
    {
      printk("-----%s-----
    ", __FUNCTION__);
    
      return 0;
    }
    
    // 初始化自定义总线
    struct bus_type my_bus= {
      .name = "my_bus",
      .match = my_bus_match,
    };
    
    struct test_dev mydev = {
      .name = "dev_drv",
      .dev = {
        .init_name = "test_bus",
        .bus = &my_bus,
        .release = mydev_release,
      },
    };
    
    struct test_drv mydrv= {
      .driver = {
        .name = "dev_drv",
        .bus = &my_bus,
        .probe = my_bus_probe,
      },
    };
    
    static int __init my_bus_init(void)
    {
      // 注册总线
      bus_register(&my_bus);
    
      // 注册设备,注意是父类
      device_register(&mydev.dev);
    
      // 注册驱动,注意是父类
      driver_register(&mydrv.driver);
    
      return 0;
    }
    
    static void __exit my_bus_exit(void)
    {
      // 注销
      device_unregister(&mydev.dev);
      driver_unregister(&mydrv.driver);
      bus_unregister(&my_bus);
    }
    
    module_init(my_bus_init);
    module_exit(my_bus_exit);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Aaron Lee");

    注册和注销时一定要选用 device 和 driver 父类:

    device_register(&mydev.dev);

    driver_register(&mydrv.driver);

    device_unregister(&mydev.dev);

    driver_unregister(&mydrv.driver);

    ps:原因与平台总线相同,请参照下面文章中的“分离”。

    http://www.cnblogs.com/lialong1st/p/7756669.html

    自定义的总线在 /sys/bus 目录下

    struct test_dev 中的 init_name 在 /sys/bus/my_bus/device 目录下

  • 相关阅读:
    avalon.js 多级下拉框实现
    提取 ECharts 中的svg地图信息
    avalon.js实践 svg地图配置工具
    基于HTML Canvas实现“指纹识别”技术
    HTML5 Canvas指纹及反追踪介绍
    百度Openrasp开源的应用运行时自我保护产品,安装教程。
    浏览器指纹实现
    centos监控web目录www下的文件是否被黑、挂马的脚本
    Linux下文件完整性监控工具Tripwire详解
    在CentOS 7上使用Tripwire监控和检测修改的文件
  • 原文地址:https://www.cnblogs.com/lialong1st/p/7762571.html
Copyright © 2011-2022 走看看