Linux驱动开发-12、总线设备驱动模型

来源:互联网 发布:1到n的阶乘的和的算法 编辑:程序博客网 时间:2024/05/14 05:30

总线设备驱动模型

1、概念:将属于同一种接口(如USBI2C等)的不同设备挂载在总线上,设备可以通过总线匹配到相应的驱动程序。

 

2、优点:

a) 支持热插拔

b) 驱动程序可移植性提高

3、关系图解 ---- 头文件  #include<linuxx/device.h>


 

4、图解说明

a) 总线设备包含三个结构;既设备,设备的驱动,总线

b) 设备和其驱动通过struct bus_type 结构体实现挂载在同一条总线上

c) 总线结构体中的match匹配函数将通过设备和设备驱动结构体中的name成员来匹配,如果名字相同,则匹配上,返回0。然后调用设备驱动中的probe 函数来驱动设备;其实这里的匹配函数是搜索挂载在总线上的所有设备和驱动,然后逐个匹配

 

5、总线描述结构及函数

struct bus_type {

const char*name;/*总线名,在/sys/bus目录下注册的名*/

...

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 subsys_private *p;

};

注册:int  bus_register(struct bus_type *bus); 注册成功将在/sys/bus下生成目录文件

 

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

 

6、设备驱动结构描述及函数

struct device_driver {

const char*name;/*必须和设备结构体中的name名相同*/

struct bus_type*bus;

....

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

...

};

注册:int  driver_register(struct device_driver *drv);

 

注销:void driver_unregister(struct device_driver *drv);

 

7、设备描述结构及函数

 

struct device {

....

struct kobject kobj; /*设备初始化名字之后存放到该结构体中*/

const char *init_name; /* initial name of the device */

...

 

struct bus_type *bus; /* type of bus device is on */

struct device_driver *driver; /* which driver has allocated this device */

...

}

注册函数:int __must_check device_register(struct device *dev);

 

注销函数:void device_unregister(struct device *dev);

  

8、程序设计

a) 初始化

b) 注册

c) 注销

d) 总结:Linux 每一种设备都是这种套路,彼此之间相对独立,只有在某一方面通过某个结构体联系在一起

 

 

驱动程序设计

总线创建

/************************************

作者:hntea

时间:2016/3/16

函数功能:总线测试

查看/sys/bus 目录下生成目录

************************************/

 

#include<linux/init.h>

#include<linux/module.h>

#include<linux/device.h>

 

 

/*初始化新总线*/

static int newmatch(struct device *dev, struct device_driver *drv)

{

/*总线驱动会自动去寻找匹配,这里这么写就够了*/

   return !strncmp(dev->kobj.name,drv->name,strlen(drv->name));

}

struct bus_type newbus =

{

.name = "newbus",

.match = newmatch, /*匹配函数*/

};

EXPORT_SYMBOL(newbus); /*符号输出*/

static int newbusInit(void)

{

int ret = 0;

ret = bus_register(&newbus);

return ret;

}

 

static void newbusExit(void)

{

bus_unregister(&newbus);

}

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Hntea");

 

module_init(newbusInit);

module_exit(newbusExit);

 

设备驱动创建

/************************************

作者:hntea

时间:2016/3/16

函数功能:总线测试

 

************************************/

#include<linux/init.h>

#include<linux/module.h>

#include<linux/device.h>

 

 

/*初始化设备驱动*/

extern struct bus_type newbus ;

int A_probe(struct device *dev)

{

printk("I find A");

return 0;

}

struct device_driver  A_drv =

{

.name = "A_device",

.bus = &newbus,

.probe = A_probe,

};

 

static int a_driverInit(void)

{

int ret = 0;

ret = driver_register(&A_drv);

return ret;

}

 

static void a_driverExit(void)

{

driver_unregister(&A_drv);

}

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Hntea");

module_init(a_driverInit);

module_exit(a_driverExit);

 

设备创建

/************************************

作者:hntea

时间:2016/3/16

函数功能:总线测试

************************************/

 

#include<linux/init.h>

#include<linux/module.h>

#include<linux/device.h>

 

/*初始化设备*/

extern struct bus_type newbus ;

 

/*这个函数要填充,要卸载时会有警告*/

void A_release(struct device *dev)

{

 

}

struct device A_dev=

{

.init_name = "A_device", /* initial name of the device */

.bus  = &newbus, /* type of bus device is on */

.release = A_release

};

static int a_deviceInit(void)

{

int ret = 0;

ret = device_register(&A_dev);

return ret;

}

 

static void a_deviceExit(void)

{

device_unregister(&A_dev);

}

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Hntea");

 

module_init(a_deviceInit);

module_exit(a_deviceExit);

 

0 0
原创粉丝点击