Linux驱动之设备模型(6)

7.设备驱动

7.1  设备驱动

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

struct  device_driver {

        constchar                 *name;       

        structbus_type                *bus;     

        structmodule          *owner;

        const structof_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 structdriver_attribute *attr);

 

7.3 驱动基本操作

驱动注册和注销

    intdriver_register(struct device_driver *drv)

    voiddriver_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 = "revision1.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  __initscdriver_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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值