冬天的早上,突然开始暖和起来了。。心中散发出:那是春天的气息哈,上午的课选择果断的跑路掉。看来我还是个调皮的孩子。明天好像还是光棍节呢。。这哥们问我怎么过?你告诉我怎么过啊。。<尴尬的我始终独自怀抱整个秘密,但朋友都说我太过忧郁。。>
1)在Linux设备模型中用bus_type来描述总线,那么什么是总线呢?总线是处理器与一个或者多个设备之间的通道。在设备模型中所有的设备都通过总线相连的。
<linux/device.h>
struct bus_type {
const char *name; /**总线名字比如说PCI、USB等*/
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 bus_type_private *p; /**总线私有数据*/
};
总线的注册:
bus_register(struct bus_type *bus);如果注册成功新的总线将被添加进系统,该总线可以在/sys/bus目录下找到
总线的删除:
bus_unregister(struct bus_type *bus);
总线方法:
int (*match)(struct device *dev, struct device_driver *drv);当一个新的设备或驱动添加进该总线的时候该函数会被调用,用与判断指定的设备是否能处理指定的驱动,若匹配成功则返回一个非0值。
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);用户空间产生热插拔之前该方法允许总线添加环境变量。
总线同样也有属性的:bus_attribute
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *bus, char *buf);/**当用户读属性时 被调用,将属性值存到buf中返回给用户态**/
ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);/*当用户写属性是被调用,用于存储用户传入的属性值*/
};
LDD3一书上有说可以在编译时刻创建和初始化bus_attribute结构,而且是使用一个宏来搞定的。
BUS_ATTR(name,mode,show,store);
我真的很想知道这个宏究竟是什么咚咚我看了看源代码才知道,原来它是这样定义的。这么的复杂啊。。
#define BUS_ATTR(_name, _mode, _show, _store) \
struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store),
它将bus_attr_作为给定的name的前缀来创建总线的真正名称。<书上是这么解释的我也表示默认了>
创建属性:int bus_create_file(struct bus_type *,struct bus_attribute *);
删除属性:void bus_remove_file(struct bus_type *, struct bus_attribute *);
2)设备device系统中的任一设备在设备模型中都由一个device对象描述,其对应的数据结构struct device,定义如下:
struct device {
struct device *parent;/**设备的父亲设备---只的是该设备属于哪个设备*/
struct device_private *p; /**设备的私有数据成员**/
struct kobject kobj;
const char *init_name; /* initial name of the device */
struct device_type *type; /**设备类型**/
struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this device */
void *platform_data; /* Platform specific data, device core doesn't touch it */
struct dev_pm_info power; /**这个是电源管理的吧**/
dev_t devt; /* 设备号 大家都懂的" */
struct class *class;
void (*release)(struct device *dev);
/**还省略了一些成员了**/
};
设备的注册和注销:
int device_register(struct device *dev);将一个新的device对象插入设备模型,并自动在/sys/devices下创建一个对应的目录。
void device_unregister(struct device *dev);完成相反的操作,注销设备对象。
设置设备名字:dev_set_name(struct device *dev, const char *name, ...);<初始化设备>
设备的属性:真烦写不下去了
/* interface for exporting device attributes */
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
这个宏是在编译时刻用来构造这些device_attribute结构体的,具体和上面总线哪个宏没什么那样吧,神马神马的。。。。。。
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
创建和移除属性:
int device_create_file(struct device *device,
const struct device_attribute *entry);
void device_remove_file(struct device *dev,
const struct device_attribute *attr);
不再做过多的解释啊
3)设备驱动程序device_driver
struct device_driver {
const char *name; /*驱动程序名字*/
struct bus_type *bus; /*总线类型 属于何种总线。。*/
struct module *owner; /是THIS_MODULE吗呵呵**/
#if defined(CONFIG_OF)
const struct of_device_id *of_match_table;
#endif
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);
struct driver_private *p;/*驱动程序私有数据*/
/*********很高兴这些大家都懂的***/
};
驱动的注册和注销:
int driver_register(struct device_driver *drv);注册驱动
int driver_unregister(struct device_driver *drv);注销驱动
悲剧驱动程序也有属性的。。
struct driver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver *driver, char *buf);
ssize_t (*store)(struct device_driver *driver, const char *buf,
size_t count);
};
#define DRIVER_ATTR(_name, _mode, _show, _store) \
struct driver_attribute driver_attr_##_name = \
__ATTR(_name, _mode, _show, _store)
创建和删除一个属性:
int driver_create_file(struct device_driver *driver,
const struct driver_attribute *attr);
void driver_remove_file(struct device_driver *driver,
const struct driver_attribute *attr);
/*********************************************************好了到此打止吧这么多的结构体也够呛够晕呼的*****************************************************************************************/
那么接下来该是什么?来几个实际例子那是必须的嘿嘿。。。。。。。。。。。。。