4、linux总线设备驱动模型

1、分层分离的概念。

分层:核心层和设备相关层分开

这种思想的优点就是能把很多文件共用的代码抽离集中起来成为一个或者多个核心文件供设备相关层调用,每一层专注于自己的功能。

分离: 把硬件相关的代码和驱动(稳定的代码)分离开来,即要编写两个文件:dev.c和drv.c

2、bus-dev-drv模型的匹配规则

内核发现一个设备时,调用device_add:a.会将device结构体加入到bus的device链表 b.从总线的drv链表中取出每一个drv,调用总线的match函数判断是否支持这个设备 c.若支持,调用驱动的probe函数

向内核注册一个驱动时,调用driver_register:a.会将driver结构体加入到bus的driver链表 b.从总线的dev链表取出每一个dev,调用总线的match函数判断是否支持该设备 c.若支持,调用驱动的probe函数

3、衍生出的几大总线

在LINUX中由BUS衍生出很多总线如,i2c_bus_type,platform_bus_type等。所谓的衍生就是指它们的设备和驱动结构都内嵌了device和driver结构体。

4、例子

总线:

/*当一个新设备或者驱动被添加到这个总线时,该方法被调用。用于判断指定的驱动程序是否能处理指定的设备。若可以,则返回非零值。*/

static int my_match(struct device *dev, struct device_driver *driver)
{
        return !strncmp(dev->kobj.name, driver->name, strlen(driver->name));
}

/*声明总线*/
struct bus_type my_bus_type = {
        .name = "my_bus",  //总线名字
        .match = my_match, //总线match函数指针
};

/*模块加载函数*/
static int __init my_bus_init(void)
{
        int ret;

        /*注册总线*/
        ret = bus_register(&my_bus_type);

        return ret;
}

/*模块卸载函数*/
static void my_bus_exit(void)
{
        bus_unregister(&my_bus_type);
}


设备:

static void my_dev_release(struct device *dev)
{

}

struct device my_dev = {
        .init_name = "my_dev",
        .bus = &my_bus_type,   //指明设备所属的总线
        .release = my_dev_release,
};

static int __init my_device_init(void)
{
        int ret = 0;

        /*注册设备*/
        device_register(&my_dev);  //device_initialize(dev);  return device_add(dev);

        return ret;

}

static void my_device_exit(void)
{
        device_unregister(&my_dev);
}

驱动:

/*当驱动找到对应的设备时会执行该函数*/
static int my_probe(struct device *dev)
{
    printk("Driver found device which my driver can handle!\n");
    return 0;
}

static int my_remove(struct device *dev)
{
    printk("Driver found device unpluged!\n");
    return 0;
}

struct device_driver my_driver = {
        .name = "my_dev",
        .bus = &my_bus_type,
        .probe = my_probe,
        .remove = my_remove,
};


static int __init my_driver_init(void)
{
        int ret = 0;

        /*注册驱动*/
        driver_register(&my_driver);

        return ret;

}

static void my_driver_exit(void)
{
        driver_unregister(&my_driver);
}


关于bus-dev-drv模型的链表是如何形成的,如何关联,并且在sys目录下是如何变化的可以参考如下两篇文章:http://blog.chinaunix.net/uid-26837113-id-3182571.html      http://www.linuxidc.com/Linux/2012-05/60757.htm


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值