Linux驱动之设备模型(6)

来源:互联网 发布:mac如何清理重复照片 编辑:程序博客网 时间:2024/05/14 10:04

Linux驱动之设备模型(6)

 (2013-02-21 11:14:00)
转载
 分类: 设备模型

原文地址:  http://blog.csdn.net/hsly_support/article/details/7366598

7.设备驱动

7.1  设备驱动

 在Linux设备模型中,设备驱动用device_driver结构来表示

struct  device_driver {

         const char                  *name;       

         struct bus_type                 *bus;     

         struct module           *owner;

         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; 

};

 

7.2  驱动属性

 驱动属性由driver_attribute来表示

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

};

DRIVER_ATTR(_name,_mode, _show, _store)

 

 属性操作

     创建属性

    int  driver_create_file(struct  device_driver *driver,

                            const structdriver_attribute *attr);

     删除属性

    void  driver_remove_file(struct device_driver *driver,

                                const struct driver_attribute *attr);

 

7.3 驱动基本操作

 驱动注册和注销

    int driver_register(struct device_driver *drv)

    void driver_unregister(struct device_driver *drv)

 

 驱动注册分析

     driver_register

    int  driver_register(struct device_driver *drv)

    {

         int  ret;

         struct device_driver  *other;

         BUG_ON(!drv->bus->p);

 

        

         if ((drv->bus->probe &&drv->probe) ||

            (drv->bus->remove && drv->remove) ||

            (drv->bus->shutdown && drv->shutdown))

                   printk(KERN_WARNING  "Driver '%s' needs updating - please use "

                            "bus_type methods\n", drv->name);

        

        

         other = driver_find(drv->name,drv->bus);

         if (other) {

                   put_driver(other);

         }

 

        

         ret = bus_add_driver(drv);

        

         

    ret = driver_add_groups(drv, drv->groups);

}

 

 bus_add_driver

int  bus_add_driver(struct device_driver *drv)

{

        

         bus = bus_get(drv->bus);

 

            

         error =kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,

                                          "%s", drv->name);

 

         if(drv->bus->p->drivers_autoprobe) {

                   error = driver_attach(drv);

         }

        

         klist_add_tail(&priv->knode_bus,&bus->p->klist_drivers);

 

        

         error = driver_create_file(drv,&driver_attr_uevent);

         error = driver_add_attrs(bus, drv);

 

        

         kobject_uevent(&priv->kobj,KOBJ_ADD);

}

 

 driver_attach

int driver_attach(struct  device_driver *drv)

{

         return bus_for_each_dev(drv->bus,NULL, drv, __driver_attach);

}

遍历总线上的所有设备,当有驱动支持的设备时,调用__driver_attach函数完成相应的工作__driver_attach()->driver_probe_device()->driver_probe_device()->bus->probe()->

drv->probe () 优先调用总线中定义的probe函数,如果bus中未定义probe,则再调用驱动中定义的probe。

 

7.4  实例分析

 

#include

#include

#include

#include

#include

 

extern   struct  bus_type  scbus_type;

 

static char  * Version = "revision 1.0,scdriver";

 

static int sc_probe(struct device *dev)

{

         printk("driver  found  device\n");

         return 0;

}

 

static int sc_remove(struct device *dev)

{

         printk("device  remove  \n");

         return  0;

}

 

struct device_driver scdriver = {

         .name       = "scdevice0",    

         .bus = &scbus_type,        

         .probe      = sc_probe,     

         .remove   = sc_remove,    

};

 

 

static ssize_t driver_show_version(struct  device_driver *driver, char *buf)

{

         return  sprintf(buf, "%s\n", Version);

}

static DRIVER_ATTR(version, S_IRUGO,driver_show_version, NULL);

 

static  int  __init scdriver_init(void)

{

         int  ret;

     

         ret= driver_register(&scdriver);

         if(ret)

                   return  ret;

        

         ret= driver_create_file(&scdriver, &driver_attr_version);

         if(ret)

                   goto  err_create;

 

         printk("drvierregistered\n");

         return  0;

 

err_create:

         driver_unregister(&scdriver);

         return  ret;

}

 

static void  __exit scdriver_exit(void)

{

         driver_remove_file(&scdriver,&driver_attr_version);

         driver_unregister(&scdriver);

}

 

module_init(scdriver_init);

module_exit(scdriver_exit);

 

MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("CJOK");

 

试验结果:

Linux驱动之设备模型(6)
0 0
原创粉丝点击