15750|0

139

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

芯灵思SinlinxA33开发板Linux总线设备驱动实现过程(附代码) [复制链接]

开发平台 芯灵思Sinlinx A33
内存: 1GB   存储: 4GB

详细参数 https://m.tb.cn/h.3wMaSKm
开发板交流群 641395230


总线驱动设备模型:
  • 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
点赞 关注(1)

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表