用一个.c文件来理解bus,driver,device,sysfs的关系和driver&device的bind过程

发布于 2022-09-22 11:19:49 字数 7270 浏览 8 评论 0

忙了一个下午,调成功了一个module.写出来可能对驱动新手有一定帮助。我本人就是新手,所以从源码中理解这些概念花了一定的功夫。
以下module可以验证device,driver,bus的关系及在sysfs的体系,及bus先match,driver再probe的过程。
同时追求代码最小化,可见bus,device,driver等对象在注册时哪些信息是必须的。

  1. #include <linux/module.h>
  2. #include <linux/kobject.h>
  3. #include <linux/device.h>
  4. /*未实现设备文件创建和文件系统驱动*/
  5. static int my_bus_match(struct device* device, struct device_driver* driver);
  6. static int my_driver_probe(struct device* dev);
  7. static void unregister_all(void);
  8. static int register_all(void);
  9. MODULE_LICENSE("GPL");
  10. struct bus_type my_bus_type =
  11. {
  12.   .name = "my_bus_type",
  13.   .match= my_bus_match
  14. };
  15. struct my_device
  16. {
  17.   int id;
  18.   struct device dev;
  19.   int drv_id;
  20. };
  21. struct my_device_driver
  22. {
  23. int id;
  24. struct device_driver drv;
  25. };
  26. struct my_device_driver my_driver_1 =
  27. {
  28.   .drv =
  29.   {
  30.     .name = "my_bus_driver_1",
  31.     .probe = my_driver_probe,
  32.     .bus = &my_bus_type,
  33.   },
  34.   .id = 1,
  35. };
  36. struct my_device_driver my_driver_2 =
  37. {
  38.   .drv =
  39.   {
  40.     .name = "my_bus_driver_2",
  41.     .probe = my_driver_probe,
  42.     .bus = &my_bus_type
  43.   },
  44.   .id = 2
  45. };
  46. struct my_device my_device_1 =
  47. {
  48.   .id=001,
  49.   .drv_id = 1,
  50.   .dev =
  51.   {
  52.     .bus = &my_bus_type,   
  53.     .bus_id = "my_bus_id_1"
  54.   }
  55.   
  56. };
  57. struct my_device my_device_2 =
  58. {
  59.   .id=002,
  60.   .drv_id = 2,
  61.   .dev =
  62.   {
  63.     .bus = &my_bus_type,
  64.     .bus_id = "my_bus_id_2"
  65.   }
  66. };
  67. static int device_match_driver(struct my_device* mydev, struct my_device_driver* mydrv)
  68. {
  69.   printk("one match tested: dev_id=%d, dev.drv_id=%d, drv_id=%d, drv_name=%s\n", mydev->id,
  70.          mydev->drv_id, mydrv->id, mydrv->drv.name );
  71.   if(mydev->drv_id != mydrv->id)
  72.        return 0;
  73.   return 1;
  74. }
  75. static int my_bus_match(struct device* device, struct device_driver* driver)
  76. {
  77.   struct my_device* mydev = container_of(device, struct  my_device, dev);
  78.   struct my_device_driver* mydrv = container_of(driver, struct my_device_driver, drv);
  79.   printk("my_bus_match called\n");
  80.   if(device_match_driver(mydev, mydrv))
  81.   {
  82.         printk("one matched group:dev_id=%d drv_id=%d\n", mydev->id, mydrv->id);
  83.         return 1;
  84.   }
  85.   printk("device %d and driver %d not match\n", mydev->id, mydrv->id);
  86.   return 0;
  87. }
  88. static int my_driver_probe(struct device* dev)
  89. {
  90.   struct my_device_driver* mydrv = container_of(dev->driver, struct my_device_driver, drv);
  91.   struct my_device* mydev = container_of(dev, struct my_device, dev);
  92.   printk("my_driver %s drive probe called\n", mydrv->drv.name);
  93.   if(device_match_driver(mydev, mydrv))
  94.       return 0;
  95.   return 1;
  96. }
  97. const int errExist = -17;
  98. int bus_is_registered = 0;
  99. static int register_all()
  100. {
  101.   int res;
  102.   res = bus_register(&my_bus_type);
  103.   if(res)
  104.   {
  105.      printk("register my_bus_type failed\n");
  106.      return res;
  107.   }
  108.   bus_is_registered = 1;
  109.    /*register driver 1*/
  110.    res = driver_register(&my_driver_1.drv);
  111.    if(res)
  112.    {
  113.       printk("register my_driver_1 failed\n");
  114.       return res;
  115.    }
  116.        
  117.    /*register driver 2*/
  118.    res  = driver_register(&my_driver_2.drv);  
  119.    if(res)
  120.    {
  121.       printk("register my_driver_2 failed\n");
  122.       return res;
  123.    }
  124.    
  125.    /*add device 1*/
  126.    res = device_register(&my_device_1.dev);
  127.    if(res)
  128.    {
  129.      printk("register my_device_1 failed\n");
  130.      return res;
  131.    }
  132.    res = device_register(&my_device_2.dev);
  133.    if(res)
  134.    {
  135.      printk("register my_device_2 failed\n");
  136.      return res;
  137.    }
  138.    return 0;
  139. }
  140. static int my_init(void)
  141. {
  142.   int res;
  143.   printk("my_init called\n");
  144.   if((res = register_all()))
  145.   {
  146.     if(res != errExist && bus_is_registered)
  147.        bus_unregister(&my_bus_type);
  148.   /* dangerous if call unregister_all();*/
  149.         printk("res=%d\n",res);
  150.     return res;
  151.   }
  152.   return 0;
  153. }
  154. static void unregister_all()
  155. {
  156. device_unregister(&my_device_1.dev);
  157. device_unregister(&my_device_2.dev);
  158. driver_unregister(&my_driver_1.drv);
  159. driver_unregister(&my_driver_2.drv);
  160. bus_unregister(&my_bus_type);
  161. }
  162. static void my_exit(void)
  163. {
  164. unregister_all();
  165. }
  166. module_init(my_init);
  167. module_exit(my_exit);

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半边脸i 2022-09-29 11:19:49

:wink:
LDD 里面讲得也不错~

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文