查看: 1149|回复: 0

Linux总线设备驱动实现过程(附代码)

[复制链接]
  • TA的每日心情
    奋斗
    2016-4-14 10:16
  • 签到天数: 9 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2019-3-5 17:25:46 | 显示全部楼层 |阅读模式
    分享到:


    总线驱动设备模型:
    • 1、总线驱动设备模型只是提供一种机制,将驱动程序分为device和driver两部分并彼此建立联系
    • 2、注册device过程:
    •     a、将device放入bus的dev链表
    •     b、从bus的drv链表取出每一个driver,用bus的match函数判断取出的driver能否支持这个device(判断name)
    •     c、如果支持,调用该driver的probe函数(probe函数自由实现)
    • 3、注册driver过程:
    •     a、将driver放入bus的drv链表
    •     b、从bus的dev链表取出每一个device,用bus的match函数判断这个driver能否支持取出的device(判断name)
    •     c、如果支持,调用该driver的probe函数(probe函数自由实现)


    在linux系统总线存在目录/sys/bus/

    总线结构体:描述一个总线,管理device和driver,完成匹配
    struct bus_type {
        const char        *name;                                                    /*总线名*/
        const char        *dev_name;
        struct device        *dev_root;
        struct bus_attribute    *bus_attrs;
        struct device_attribute    *dev_attrs;//设备属性
        struct driver_attribute    *drv_attrs;//驱动属性
        int (*match)(struct device *dev, struct device_driver *drv); //设备驱动匹配函数
        int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
        int (*probe)(struct device *dev);
        int (*remove)(struct device *dev);
        void (*shutdown)(struct device *dev);
        int (*suspend)(struct device *dev, pm_message_t state);
        int (*resume)(struct device *dev);
        const struct dev_pm_ops *pm;
        struct iommu_ops *iommu_ops;
        struct subsys_private *p;

    };
    总线注册和注销
        int bus_register(struct bus_type *bus)
        void bus_unregister(struct bus_type *bus)

    /=================================================================/
    device对象
    struct device {
        struct kobject kobj;  //所有对象的父类
        const char        *init_name; // 在总线中会有一个名字,用于做匹配
        struct bus_type    *bus; //指向该device对象依附于总线的对象
        void        *platform_data; // 自定义的数据,指向任何类型数据

    device对象注册和注销的方法
        int device_register(struct device *dev)
        void device_unregister(struct device *dev)
    /=================================================================/
    driver对象:描述设备驱动的方法(代码逻辑)
    struct device_driver {
        const char        *name;
        // 在总线中会有一个名字,用于做匹配,在/sys/bus/mybus/drivers/名字
        struct bus_type        *bus;//指向该driver对象依附于总线的对象
        int (*probe) (struct device *dev); // 如果device和driver匹配之后,driver要做的事情
        int (*remove) (struct device *dev); // 如果device和driver从总线移除之后,driver要做的事情
    }
    driver对象注册和注销
        int driver_register(struct device_driver *drv)
        void driver_unregister(struct device_driver *drv)

    总线代码:
    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/device.h>


    4. int mybus_match(struct device *dev, struct device_driver *drv)
    5. {
    6.         //如果匹配成功,match方法一定要返回一个1, 失败返回0
    7.         if(!strncmp(drv->name, dev->kobj.name, strlen(drv->name)))
    8.         {
    9.                 printk("match ok\n");
    10.                 return 1;
    11.         }else{
    12.                 printk("match failed\n");
    13.                 return 0;

    14.         }
    15.         return 0;
    16. }


    17. //实例化一个bus对象
    18. struct bus_type mybus = {
    19.         .name = "mybus",
    20.         .match = mybus_match,
    21. };

    22. EXPORT_SYMBOL(mybus);//使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用

    23. static int __init mybus_init(void)
    24. {
    25.         printk("----------%s-------------\n", __FUNCTION__);
    26.         int ret;

    27.         //构建一个总线
    28.         // /sys/bus/mybus
    29.         ret = bus_register(&mybus);
    30.         if(ret != 0)
    31.         {
    32.                 printk("bus_register error\n");
    33.                 return ret;
    34.         }
    35.         return 0;
    36. }

    37. static void __exit mybus_exit(void)
    38. {
    39.         printk("----------%s-------------\n", __FUNCTION__);
    40.         bus_unregister(&mybus);
    41.         
    42. }

    43. module_init(mybus_init);
    44. module_exit(mybus_exit);
    45. MODULE_LICENSE("GPL");

    复制代码


    driver代码:
    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/device.h>
    4. #include <linux/io.h>
    5. int mydrv_probe(struct device *dev)
    6. {
    7.         printk("----------%s-------------\n", __FUNCTION__);
    8.         
    9.         return 0;
    10. }

    11. int mydrv_remove(struct device *dev)
    12. {

    13.         printk("----------%s-------------\n", __FUNCTION__);
    14.         return 0;
    15. }

    16. extern struct bus_type mybus;

    17. struct device_driver mydrv = {
    18.         .name = "my_dev_drv",
    19.         .bus = &mybus,
    20.         .probe = mydrv_probe,
    21.         .remove = mydrv_remove,
    22. };


    23. static int __init mydrv_init(void)
    24. {
    25.         printk("----------%s-------------\n", __FUNCTION__);
    26.         //将driver注册到总线中
    27.         int ret;
    28.         ret  = driver_register(&mydrv);
    29.         if(ret < 0)
    30.         {
    31.                 printk("device_register error\n");
    32.                 return ret;
    33.         }
    34.         

    35.         return 0;
    36. }
    37. static void __exit mydrv_exit(void)
    38. {

    39.         printk("----------%s-------------\n", __FUNCTION__);
    40.         driver_unregister(&mydrv);
    41. }





    42. module_init(mydrv_init);
    43. module_exit(mydrv_exit);
    44. MODULE_LICENSE("GPL");

    复制代码


    device代码:

    1. #include <linux/init.h>
    2. #include <linux/module.h>
    3. #include <linux/device.h>
    4. #include "dev_info.h"
    5. extern struct bus_type mybus;
    6. void        mydev_release(struct device *dev)
    7. {

    8.         printk("----------%s-------------\n", __FUNCTION__);
    9. }

    10. //构建一个device对象
    11. struct device  mydev= {
    12.         .init_name = "my_dev_drv",
    13.         .bus = &mybus,
    14.         .release = mydev_release,
    15. };



    16. static int __init mydev_init(void)
    17. {
    18.         printk("----------%s-------------\n", __FUNCTION__);
    19.         //将device注册到总线中
    20.         int ret;
    21.         ret  = device_register(&mydev);
    22.         if(ret < 0)
    23.         {
    24.                 printk("device_register error\n");
    25.                 return ret;
    26.         }
    27.         

    28.         return 0;
    29. }

    30. static void __exit mydev_exit(void)
    31. {

    32.         printk("----------%s-------------\n", __FUNCTION__);
    33.         device_unregister(&mydev);

    34. }



    35. module_init(mydev_init);
    36. module_exit(mydev_exit);
    37. MODULE_LICENSE("GPL");

    复制代码







    ---------------------
    参考文章https://blog.csdn.net/hfutyyj/article/details/80248904
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 20:36 , Processed in 0.107712 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.