1、在/sys/bus下注册一个自定义总线
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/kobject.h>
#include<linux/slab.h>
#include<linux/sysfs.h>
#include<linux/device.h>
#include "my_bus.h"#if 0
struct bus_type {const char *name;const char *dev_name;struct device *dev_root;struct device_attribute *dev_attrs; /* use dev_groups instead */const struct attribute_group **bus_groups;const struct attribute_group **dev_groups;const struct attribute_group **drv_groups;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 (*online)(struct device *dev);int (*offline)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;const struct iommu_ops *iommu_ops;struct subsys_private *p;struct lock_class_key lock_key;
};
int bus_register(struct bus_type *bus)
#endifstruct bus_type my_bus = {.name = "my_bus",.match = my_bus_match,.probe = my_bus_probe,
};int my_bus_match(struct device *dev, struct device_driver *drv)
{return (strcmp(dev_name(dev),drv->name) == 0);
}int my_bus_probe(struct device *dev)
{struct device_driver *drv = dev->driver;if(drv->probe)drv->probe(dev);return 0;
}static int my_bus_init(void)
{int ret;ret = bus_register(&my_bus);return ret;
}static void my_bus_exit(void)
{bus_unregister(&my_bus);
}module_init(my_bus_init);
module_exit(my_bus_exit);
MODULE_LICENSE("GPL");
//my_bus.h
#ifndef _ATTR_H_
#define _ATTR_H_int my_bus_match(struct device *dev, struct device_driver *drv);
int my_bus_probe(struct device *dev);#endif
2、在总线目录下创建自己的属性文件
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/kobject.h>
#include<linux/slab.h>
#include<linux/sysfs.h>
#include<linux/device.h>
#include "my_bus.h"#if 0
struct bus_type {const char *name;const char *dev_name;struct device *dev_root;struct device_attribute *dev_attrs; /* use dev_groups instead */const struct attribute_group **bus_groups;const struct attribute_group **dev_groups;const struct attribute_group **drv_groups;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 (*online)(struct device *dev);int (*offline)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;const struct iommu_ops *iommu_ops;struct subsys_private *p;struct lock_class_key lock_key;
};
int bus_register(struct bus_type *bus)
static struct bus_attribute bus_attr_uevent = __ATTR(uevent, S_IWUSR, NULL,bus_uevent_store);int bus_create_file(struct bus_type *bus, struct bus_attribute *attr)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);
};
void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr)
#endifstruct bus_type my_bus = {.name = "my_bus",.match = my_bus_match,.probe = my_bus_probe,
};
static struct bus_attribute my_bus_attr = __ATTR(attr1, 0660, my_bus_attr_show,my_bus_attr_store);ssize_t my_bus_attr_show(struct bus_type *bus, char *buf)
{ssize_t ret;ret = sprintf(buf,"this is in my_bus_attr_show\n");return ret;
}
ssize_t my_bus_attr_store(struct bus_type *bus, const char *buf, size_t count)
{printk("my_bus_attr_store:buf = %s\n",buf);return count;
}int my_bus_match(struct device *dev, struct device_driver *drv)
{return (strcmp(dev_name(dev),drv->name) == 0);
}int my_bus_probe(struct device *dev)
{struct device_driver *drv = dev->driver;if(drv->probe)drv->probe(dev);return 0;
}static int my_bus_init(void)
{int ret;ret = bus_register(&my_bus);ret = bus_create_file(&my_bus, &my_bus_attr);return ret;
}static void my_bus_exit(void)
{bus_remove_file(&my_bus, &my_bus_attr);bus_unregister(&my_bus);
}module_init(my_bus_init);
module_exit(my_bus_exit);
MODULE_LICENSE("GPL");
#ifndef _ATTR_H_
#define _ATTR_H_int my_bus_match(struct device *dev, struct device_driver *drv);
int my_bus_probe(struct device *dev);ssize_t my_bus_attr_show(struct bus_type *bus, char *buf);
ssize_t my_bus_attr_store(struct bus_type *bus, const char *buf, size_t count);
#endif
3、一些结构体和api介绍
3.1 struct bus_type
The bus type of the device
3.2 bus_register
注册一个总线
3.3 bus_unregister
去除一个总线
3.4 bus_create_file
总线目录下创建属性文件api