Linux设备模型<三>总线、设备、驱动程序

冬天的早上,突然开始暖和起来了。。心中散发出:那是春天的气息哈奋斗奋斗奋斗奋斗奋斗奋斗,上午的课选择果断的跑路掉。看来我还是个调皮的孩子明天好像还是光棍节呢。。这哥们问我怎么过?你告诉我怎么过啊。。<尴尬的我始终独自怀抱整个秘密,但朋友都说我太过忧郁。。>

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

/*********************************************************好了到此打止吧这么多的结构体也够呛够晕呼的*****************************************************************************************/

那么接下来该是什么?来几个实际例子那是必须的嘿嘿。。。。。。。。。。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值