主题 : 【分享】总线设备驱动模型浅析 复制链接 | 浏览器收藏 | 打印
畅游在知识的海洋...
级别: 论坛版主
UID: 33629
精华: 4
发帖: 554
金钱: 3075 两
威望: 615 点
综合积分: 1188 分
注册时间: 2010-12-03
最后登录: 2015-09-22
楼主  发表于: 2011-11-27 18:06

 【分享】总线设备驱动模型浅析

今天重新复习了总线设备驱动模型,做了一点小笔记,共享给大家,大牛免看


总线设备驱动模型分析
一.linux系统的驱动框架的基础很大一部份是围绕着总线设备驱动模型的。

二.三个结构体:
struct bus_type表示总线
struct device 表示设备
struct device_driver表示驱动

三.结构体核心代码分析(2.6.38内核)
<1>struct bus_type
{
    const char        *name;/*总线名*/
    struct bus_attribute    *bus_attrs;/*总线属性文件,属性文件会显示在/sys/文件系统中*/
    struct device_attribute    *dev_attrs;/*设备属性文件*/
    struct driver_attribute    *drv_attrs;/*驱动属性文件*/
    int (*match)(struct device *dev, struct device_driver *drv);/*驱动与设备是否匹配的检测函数*/
    struct subsys_private *p;
};
其中,struct subsys_private中包含一个设备链表(struct klist klist_devices)和一个驱动链表(    struct klist klist_drivers)

<2>struct device
{
    struct kobject kobj;
    const char        /*设备名*/
    struct bus_type    *bus;        /* 该设备挂接在哪条总线上*/
    struct device_driver *driver;    /* 该设备所对应的驱动 */
    void        *platform_data;    /* 平台特定数据,一般我们移植内核时需填充该结构体(如支持mini2440的nandflash,dm9000等)*/
    dev_t            devt;    /* 设备号*/
};
    任何建立在平台总线设备驱动模型基础上的驱动代码(如平台驱动,PCI驱动,USB驱动,I2C驱动,SPI驱动等),它的设备结构体(如platform_device,pci_dev,usb_device,i2c_device,spi_device等)都会包含一个struct device结构体,当这些驱动向内核注册各式各样的设备时,其实最终都会调用到:
int device_register(struct device *dev)
{
    device_initialize(dev);/*做各类初始化*/
    /*将设备挂接在对应的总线上,主要工作就是把设备(device)添加到总线(bus_type)的klist_devices链表中去*/
    return device_add(dev);
}

<3>struct device_driver {
    const char        *name;/*驱动名*/
    struct bus_type        *bus;/该驱动所属的总线/
    int (*probe) (struct device *dev);/*指向设备探测函数*/
    int (*remove) (struct device *dev);/*指向设备移除函数*/
    struct driver_private *p;
};
    同理,任何建立在平台总线设备驱动模型基础上的驱动代码(如平台驱动,PCI驱动,USB驱动,I2C驱动,SPI驱动等),它的驱动结构体(如platform_driver,pci_driver,usb_driver,i2c_driver,spi_driver等)都会包含一个struct device_driver结构体,当这些驱动向内核注册各式各样的驱动时,其实最终都会调用到:
int driver_register(struct device_driver *drv)
{
    /*将驱动绑定在对应的总线上,主要工作就是把驱动(device_driver)添加到总线(bus_type)的klist_drivers链表中去*/
    ret = bus_add_driver(drv);
}
无论是调用driver_register()注册驱动还是用device_register注册设备时,内核都会调用总线的match函数来探测是否有合适device_driver的device或者是否有合适device的device_driver,如果match成功,则会调用device_driver的probe函数进行更进一步的探测。

这样我们就可以站在一个新的高度上看驱动了
[ 此帖被wuweidong在2011-11-27 20:38重新编辑 ]
好好学习,天天鲁管
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2011-11-27 20:01
Good. 这部分在Linux Device Driver 第三版的第14章有详细的描述:)
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
畅游在知识的海洋...
级别: 论坛版主
UID: 33629
精华: 4
发帖: 554
金钱: 3075 两
威望: 615 点
综合积分: 1188 分
注册时间: 2010-12-03
最后登录: 2015-09-22
2楼  发表于: 2011-11-27 20:14
有时书上讲得太具体反而让人理解不了
好好学习,天天鲁管