开发平台 芯灵思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)
总线代码:
#include <linux/init.h> #include <linux/module.h> #include <linux/device.h> int mybus_match(struct device *dev, struct device_driver *drv) { //如果匹配成功,match方法一定要返回一个1, 失败返回0 if(!strncmp(drv->name, dev->kobj.name, strlen(drv->name))) { printk("match ok\n"); return 1; }else{ printk("match failed\n"); return 0; } return 0; } //实例化一个bus对象 struct bus_type mybus = { .name = "mybus", .match = mybus_match, }; EXPORT_SYMBOL(mybus);//使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用 static int __init mybus_init(void) { printk("----------%s-------------\n", __FUNCTION__); int ret; //构建一个总线 // /sys/bus/mybus ret = bus_register(&mybus); if(ret != 0) { printk("bus_register error\n"); return ret; } return 0; } static void __exit mybus_exit(void) { printk("----------%s-------------\n", __FUNCTION__); bus_unregister(&mybus); } module_init(mybus_init); module_exit(mybus_exit); MODULE_LICENSE("GPL");
driver代码:
#include <linux/init.h> #include <linux/module.h> #include <linux/device.h> #include <linux/io.h> int mydrv_probe(struct device *dev) { printk("----------%s-------------\n", __FUNCTION__); return 0; } int mydrv_remove(struct device *dev) { printk("----------%s-------------\n", __FUNCTION__); return 0; } extern struct bus_type mybus; struct device_driver mydrv = { .name = "my_dev_drv", .bus = &mybus, .probe = mydrv_probe, .remove = mydrv_remove, }; static int __init mydrv_init(void) { printk("----------%s-------------\n", __FUNCTION__); //将driver注册到总线中 int ret; ret = driver_register(&mydrv); if(ret < 0) { printk("device_register error\n"); return ret; } return 0; } static void __exit mydrv_exit(void) { printk("----------%s-------------\n", __FUNCTION__); driver_unregister(&mydrv); } module_init(mydrv_init); module_exit(mydrv_exit); MODULE_LICENSE("GPL");
device代码:
#include <linux/init.h> #include <linux/module.h> #include <linux/device.h> #include "dev_info.h" extern struct bus_type mybus; void mydev_release(struct device *dev) { printk("----------%s-------------\n", __FUNCTION__); } //构建一个device对象 struct device mydev= { .init_name = "my_dev_drv", .bus = &mybus, .release = mydev_release, }; static int __init mydev_init(void) { printk("----------%s-------------\n", __FUNCTION__); //将device注册到总线中 int ret; ret = device_register(&mydev); if(ret < 0) { printk("device_register error\n"); return ret; } return 0; } static void __exit mydev_exit(void) { printk("----------%s-------------\n", __FUNCTION__); device_unregister(&mydev); } module_init(mydev_init); module_exit(mydev_exit); MODULE_LICENSE("GPL");
---------------------
参考文章https://blog.csdn.net/hfutyyj/article/details/80248904