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 目录下

  • 相关阅读:
    17、Semantic-UI之分页插件
    16、Semantic-UI之模态窗口
    15、Semantic-UI之导航
    14、Semantic-UI之菜单样式
    13、Semantic-UI之表格与表单
    12、Semantic-UI之输入框
    11、Semantic-UI之分割线
    10、Semantic-UI之图片的使用
    9、Semantic-UI之标题
    8、Semantic-UI之其他按钮样式
  • 原文地址:https://www.cnblogs.com/lialong1st/p/7762571.html
Copyright © 2011-2022 走看看