当前位置:文档之家› linux设备模型之bus,device,driver

linux设备模型之bus,device,driver


总线属性的删除, 使用:
void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr);
(4)总线实例: 1:首先是要准备一个总线 bus_type.也就是定义一个 bus_type,然后 给它填上一些成员。定义如下:
struct bus_type my_bus_type = { .name = "my_bus", .match = my_match, };
(5)测试 将 bus.c 以动态加载的方式加载到内核, insmod bus.ko ,在 /sys/bus/ 目录下会有一个 my_bus 目录,这就是我们添加的总线。该目录下有
devices ,drivers 目录,因为该总线上没有挂载任何设备和驱动,所以这
两个目录都为空;同时,在/sy/devices 目录下,还可看到 my_bus0 设 备(总线本身也是一种设备)。 二:设备: 关于设备的一些常用结构体:device,
参数中的 attr,即为 bus_attr_name。 另外, 就是参数中的 show 方法,设置方法如下
static ssize_t show_bus_version(struct bus_type *bus, char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", Version); }
1:struct device { struct device * parent; //父设备,一般一个 bus 也对应一个设备。 struct kobject kobj;//代表自身 char bus_id[BUS_ID_SIZE]; struct bus_type * bus; /* 所属的总线 */ struct device_driver *driver; /* 匹配的驱动*/ void *driver_data; /* data private to the driver 指向驱动 */
} struct device my_dev={ //创建设备属性 .bus = &my_bus_type,//定义总线类型 .parent = &my_bus,//定义 my_dev 的父设备。 .release = my_device_release, }; static ssize_t mydev_show(struct device *dev, char *buf) { return sprintf(buf, "%s\n", "This is my device!"); } static DEVICE_ATTR(dev, S_IRUGO, mydev_show, NULL); static int __init my_device_init(void){ int ret; strncpy(my_dev.bus_id, "my_dev", BUS_ID_SIZE); //初始化设备 ret = device_register(&my_dev); //注册设备 if (ret) printk("device register!\n"); device_create_file(&my_dev, &dev_attr_dev); //创建设备文件 return ret; } static void __exit my_device_exit(void) { device_unregister(&my_dev);//卸载设备 } module_init(my_device_init); module_exit(my_device_exit); MODULE_AUTHOR("Fany"); MODULE_LICENSE("GPL");
当加载驱动时,驱动就支总线上找到自己对应的设备。或者先把驱动 加载上,来了一个设备就去总线找驱动。 一:总线 总线是处理器与设备之间通道,在设备模型中,所有的设备都通 过总线相连。 关于总线的一些结构体:bus_type, (1)bus_type:
struct bus_type { const char * name;//设备名称 struct subsystem subsys;//代表自身 struct kset drivers; //当前总线的设备驱动集合 struct kset devices; //所有设备集合 struct klist klist_devices; struct klist klist_drivers; struct bus_attribute * bus_attrs;//总线属性
基本关系简要的概括 linux2.6 提供了新的设备模型:总线、 驱动、 设备。 如下: 驱动核心可以注册多种类型的总线。 每种总线下面可以挂载许多设备。(通过 kset devices) 每种总线下可以用很多设备驱动。(通过包含一个 kset drivers)} 每个驱动可以处理一组设备。按照我的理解就是所有的设备都挂载到总线上,
if (ret) printk("device_register failed!\n"); return ret; } static void __exit my_bus_exit(void) { bus_unregister(&my_bus_type);//删除总线属性 device_unregister(&my_bus);//删除总线设备 } module_init(my_bus_init); module_exit(my_bus_exit); MODULE_AUTHOR("Fany"); MODULE_LICENSE("GPL");
2:设备属性: sysfs 中的设备入口可有属性. 相关的结构是:
struct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, char *buf); ssize_t (*store)(struct device *dev, const char *buf, size_t count); };
注册:int bus_register(struct bus_type * bus) 注销:void bus_unregister(struct bus_type *bus);
(3)总线属性 bus_attribute
struct bus_attribute { struct attribute attr; ssize_t (*show)(struct bus_type *bus, char *buf); ssize_t (*store)(struct bus_type *bus, const char *buf,size_t count); }; BUS_ATTR(name, mode, show, store);
linuform 总线的设备驱动时,总理不清三者之间的关系, 后来通过看国嵌的视频教程, 到 bus,device,driver,才对 linux 的 设备模型有了一个更深入的了解。于是,便在开发板上,测试了一下, 在此,把学过的东西,做下总结。
这个宏声明一个结构, 产生它的名子通过前缀字符串 bus_attr_ 到给定 的名子(bus_attr_name),然后利用 bus_create_file 来创建总线属性
int bus_create_file(struct bus_type *bus, struct bus_attribute *attr);
static int my_match(struct device *dev, struct device_driver *driver) { return !strncmp(dev->bus_id, driver->name, strlen(driver->name)); } static int my_bus_release(struct device *dev) { return 0; } static ssize_t show_bus_version(struct bus_type *bus, char *buf) { return sprintf(buf, PAGE_SIZE, "%s\n", version); } static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);
3:创建设备实例:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/device.h> #include <linux/string.h> extern struct device my_bus; //这里用到了总线设备中定义的结构体 extern struct bus_type my_bus_type; static int my_device_release() { return 0;
struct device_attribute * dev_attrs;//设备属性 struct driver_attribute * drv_attrs; int (*match)(struct device * dev, struct device_driver * drv);//设备驱动匹配函数 int (*uevent)(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);//热拔插事件 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); };
相关主题