今天能解决那个 kset,完全出乎自己所料,本来想以后遇到再说,呵呵。
既然解决了,然后按照进程是 bus 设备模型!
首先,要明确,总线,设备,驱动,三者不分家!!就是说,这节写的总线,以及接下来的设备和驱动是相互联系的!而且这三个例程也是相互联系的,都是根据总线来创建设备,接着是驱动!
1、总线概念
总线是处理器和设备之间的通道,在设备模型中,所有的设备都通过总线连接,设置时内部的虚拟“platform”总线,在 Linux 设备模型中,总线由 bus_type 结构表示,定义在 <linux/device.h> 中。
struct bus_type
{
const char *name; /* 总线名称 */
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 (*stutdown)(struct device *dev);
int (*suspend)(struct device *dev,pm_message_t state);
int (*resume)(struct device *dev);
struct dev_pm_ops *pm;
struct bus_type_private *p;
};
2、总线方法函数
总线注册使用:
bus_register(struct bus_type *bus);
若是成功,新的总线将被添加进系统,并可在 /sys/bus 下看到。
总线的注销使用:
void bus_unregister(struct bus_type *bus);
当一个新设备或者驱动被添加到这个总线时,match 方法将被调用,用于判断指定的驱动程序是否能够处理指定的驱动。若是可以,则返回非零值!
int (*match)(struct device *dev,struct device_driver *drv)
在为用户空间产生热插拔事件之前,这个方法允许总线添加环境变量!
int (*uevent)(struct device *dev,struct kobj_uevent_env *env);
如果要为 bus 创建属性文件,需要赋值 bus_attribute 结构:
struct bus_attribute
{
struct attribute attr;
ssize_t (*show)(struct bus_type *,char *buf);
ssize_t (*stroe)(struct bus_type *,const char *buf,size_t count);
};
其中 attr 成员用于描述属性的名称和对应属性文件的权限,show、store 成员方法则用于构造属性文件的读写信息。总线属性文件并不会随着总线的注册而自动创建,需要通过调用下列函数来创建:
int bus_create_file(struct bus_type *bus,struct bus_attribute *attr);
删除总线属性文件用函数:
void bus_remove_file(struct bus_type *bus,struct bus_attribute *attr);
总线属性结构可以使用下面的宏定义来完成初始化:
#define BUS_ATTR(_name,_mode,_show,_stroe) \
struct bus_attribute bus_attr_##_name = _ATTR(_name,_mode,_show,_store)
其中宏 __ATTR 定义在 linux/sfs.h 下:
#define __ATTR(_name,_mode,_show,_store) { \
.attr = {.name = _strintify(_name),.mode = _mode}, \
.show = _show, \
.store = _store, \