您的位置:首页 > 其它

国嵌——内核驱动——第二天(总线-驱动-设备模型)

2013-11-24 17:59 381 查看
总线-驱动-设备模型

总线是处理器和设备之间的通道,在设备模型中,所有的设备都通过总线相连,

甚至是内部的虚拟"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);

    /* 当添加新设备或新驱动时被调用,和回调特定的驱动的probe函数来初始化匹配的设备 */

    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;

    /* 总线电源管理操作,回调特定设备驱动的pm-ops */

    struct iommu_ops *iommu_ops;

    struct subsys_private *p;

    /* 驱动核心的私有数据,只有驱动核心能访问 */

};

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);

}; //总线属性结构体

 int  bus_create_file(struct bus_type *, struct bus_attribute *); //在/sys/bus/bus_name/目录下创建属性文件

 void bus_remove_file(struct bus_type *, struct bus_attribute *); //移除属性文件

 

#define BUS_ATTR(_name, _mode, _show, _store)    \

struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)

/* 此宏定义定义bus_attr_[name]属性

   并设置属性文件名字,保护属性mode,show和store函数 */

总线注册:int  bus_register(struct bus_type *bus);

若成功,新的总线被添加到/sys/bus目录

总线注销:void bus_unregister(struct bus_type *bus);

设备结构体:

struct device {

    struct device        *parent;

    /* 此设备的父设备,在多数情况下是总线或host controller

       如果是NULL,则此设备是顶级设备

     */

    struct device_private    *p;

    struct kobject kobj;     /* 顶级抽象类 */

    const char        *init_name; /* 设备最初的名字 */

    const struct device_type *type; /* 设备类型 */

    struct mutex        mutex;    /* mutex to synchronize calls to its driver. */

    struct bus_type    *bus;        /* 设备所在的总线 */

    struct device_driver *driver;    /* 管理该设备的驱动 */

    void        *platform_data;    /* 通常用于指向板级硬件信息结构体 */

    struct dev_pm_info    power; /* 设备电源管理Documentation/power/devices.txt */

    struct dev_pm_domain    *pm_domain;

  ......

    struct device_node    *of_node; /* associated device tree node */

    

    dev_t            devt;    /* dev_t, creates the sysfs "dev" */

    

    spinlock_t        devres_lock;

    struct list_head    devres_head;

    struct klist_node    knode_class;

    struct class        *class;

    const struct attribute_group **groups;    /* optional groups */

    void    (*release)(struct device *dev);/* 当设备引用变为0时的回调函数,应该被设备分配器设置 */

};

设备注册: int  device_register(struct device *dev);

设备注销: void device_unregister(struct device *dev);

注意:一条总线也是一个设备,也必须按设备注册

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);

};

#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);

驱动结构体:

struct device_driver {

    const char        *name;     /* 设备驱动的名字 */

    struct bus_type        *bus;  /* 设备驱动所在的总线 */

    struct module        *owner;

    const char        *mod_name;    /* used for built-in modules */

    bool suppress_bind_attrs;    /* disables bind/unbind via sysfs */

    const struct of_device_id    *of_match_table;

    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 attribute_group **groups;

    const struct dev_pm_ops *pm;

    struct driver_private *p;

};

驱动注册:

 int  driver_register(struct device_driver *drv);

驱动注销:

 void 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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: