免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4100 | 回复: 1
打印 上一主题 下一主题

用一个.c文件来理解bus,driver,device,sysfs的关系和driver&device的bind过程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-21 17:48 |只看该作者 |倒序浏览
忙了一个下午,调成功了一个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);
复制代码

论坛徽章:
0
2 [报告]
发表于 2008-09-22 23:41 |只看该作者
:wink:
LDD 里面讲得也不错~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP