您的位置:首页 > 运维架构 > Linux

bus, device, driver之间是怎么一回事,继续 分类: linux_内核_设备模型 2013-07-10 09:35 234人阅读 评论(0) 收藏

2013-07-10 09:35 459 查看
bus, device, driver之间是怎么一回事,继续 2010-11-20
22:14:24

分类: LINUX

继续上一篇。整理虚拟总线的代码部分:

1.将挂在总线上的设备及驱动的数据各定义成一个结构体;

2.将设备及驱动的注册,注销部分各自模块化并导出;

3.初始化match函数指针。

下面是虚拟总线的代码:

#include <linux/module.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/mm.h>

#include <linux/ioport.h>

#include <linux/interrupt.h>

#include <linux/delay.h>

#include <linux/device.h>

#include <asm/io.h>

#include "bus.h"

MODULE_LICENSE("GPL");

MODULE_AUTHOR("zl");

int zl_match(struct device * dev, struct device_driver * drv);

struct bus_type zl_bus = {

.name = "zlbus",

.match = zl_match,

};

int zl_device_register(struct zl_device *dev)

{

dev->dev.bus = &zl_bus;

//strcpy(dev->dev.bus_id, dev->name); //2.6.13

dev->dev.init_name = dev->name; //2.6.36

device_register(&dev->dev);

return 0;

}

EXPORT_SYMBOL(zl_device_register);

int zl_device_unregister(struct zl_device *dev)

{

device_unregister(&dev->dev);

return 0;

}

EXPORT_SYMBOL(zl_device_unregister);

int zl_driver_register(struct zl_driver *drv)

{

drv->drv.bus = &zl_bus;

driver_register(&drv->drv);

return 0;

}

EXPORT_SYMBOL(zl_driver_register);

int zl_driver_unregister(struct zl_driver *drv)

{

driver_unregister(&drv->drv);

return 0;

}

EXPORT_SYMBOL(zl_driver_unregister);

//------------------------------------------

int zl_match(struct device * dev, struct device_driver * drv)

{

struct zl_device *zldev;

struct zl_driver *zldrv;

printk("zl_match.\n");

zldev = container_of(dev, struct zl_device, dev);

zldrv = container_of(drv, struct zl_driver, drv);

if ((zldev->idVendor == zldrv->idVendor) && (zldev->idProduct == zldrv->idProduct)) {

return 1;

}

return 0;

}

int test_init(void)

{

int ret = 0;

bus_register(&zl_bus);

return ret;

}

void test_exit(void)

{

bus_unregister(&zl_bus);

}

module_init(test_init);

module_exit(test_exit);


其中的match函数在插入设备或驱动模块时会执行。具体是比较两组数字,一般是厂商及其产品代号。若能匹配,说明设备和相应驱动对上号了,这时会执行驱动代码中的probe指向的函数。

相应头文件:

#ifndef _BUS_Header_

#define _BUS_Header_

#include <linux/device.h>

struct zl_device {

int idVendor, idProduct;

unsigned long phys;

int irq;

char *name;

struct device dev;

};

struct zl_driver {

int idVendor, idProduct;

struct device_driver drv;

};

int zl_device_register(struct zl_device *dev);

int zl_device_unregister(struct zl_device *dev);

int zl_driver_register(struct zl_driver *drv);

int zl_driver_unregister(struct zl_driver *drv);

#endif /* _BUS_Header_ */


接在zl_bus虚拟总线下的一个设备的代码也有变化,下面是相应代码:

#include <linux/module.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/mm.h>

#include <linux/ioport.h>

#include <linux/interrupt.h>

#include <linux/delay.h>

#include <linux/device.h>

#include <asm/io.h>

#include "bus.h"

MODULE_LICENSE("GPL");

MODULE_AUTHOR("zl");

void zl_device_release(struct device * dev)

{

printk("device release.\n");

}

struct zl_device zl_device_struct = {

.idVendor = 0x1234,

.idProduct = 0x5678,

.name = "zldevice",

.dev = {

.release = zl_device_release,

},

};

int test_init(void)

{

int ret = 0;

zl_device_register(&zl_device_struct);

return ret;

}

void test_exit(void)

{

zl_device_unregister(&zl_device_struct);

}

module_init(test_init);

module_exit(test_exit);


下面是接在zl_bus虚拟总线下的驱动的代码:

#include <linux/module.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/mm.h>

#include <linux/ioport.h>

#include <linux/interrupt.h>

#include <linux/delay.h>

#include <linux/device.h>

#include "bus.h"

#include <asm/io.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("zl");

int zl_probe(struct device * dev)

{

printk("driver probe.\n");

return 0;

}

int zl_remove(struct device * dev)

{

printk("driver remove.\n");

return 0;

}

struct zl_driver zl_driver_struct = {

.idVendor = 0x1234,

.idProduct = 0x5678,

.drv = {

.name = "zldevice",

.probe = zl_probe,

.remove = zl_remove,

},

};

int test_init(void)

{

int ret = 0;

zl_driver_register(&zl_driver_struct);

return ret;

}

void test_exit(void)

{

zl_driver_unregister(&zl_driver_struct);

}

module_init(test_init);

module_exit(test_exit);


match指向的函数如果返回1,表明设备驱动对上号了,就会执行probe指向的函数,进行设备正常工作必要的初始化动作。remove指向的函数与probe函数执行相反的动作。

插入以上三个模块后,

1.在/sys/bus/zlbus/drivers目录下有zldriver生成

2.在/sys/bus/zlbus/device目录下有zldevice生成

在match函数返回1的情况下:

a./sys/bus/zlbus/drivers/zldriver下有driver,其中有zldevice

b./sys/bus/zlbus/devices/zldevice下有device,其中有zldriver

     即设备与驱动匹配成功。

若match函数返回0,则上述a,b不成立。

回到上一篇中,没有初始化match函数指针。也有上述a,b的情况发生

     即同一总线上的设备与驱动在没有match的情况下默认是匹配成功的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐