微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 手机设计讨论 > MTK手机平台交流 > 内核驱动框架

内核驱动框架

时间:10-02 整理:3721RD 点击:
                                    内核驱动框架         
                                    分类: linux
                                                   
                                   内核(linux-2.6.24)有一个大的框架来管理总线,外设及其驱动。
看外设驱动代码时,明白了这个框架,可以很方便的找到需要看的函数。
1.数据结构
这个框架涉及到3个比较重要的数据结构:
   struct bus_type         用来描述总线
   struct device           用来描述设备
   struct device_driver   用来描述设备驱动
有如下拓扑图

内核中可以有很多的总线bus_type
总线bus_type上可以有很多的设备device
每个设备device都有它所对应的驱动device_driver
  • struct bus_type {    //…..省略一些成员
  •     const char      * name;
  •     struct kset     drivers;
  •     struct kset     devices;
  •     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 (*suspend_late)(struct device * dev, pm_message_t state);
  •     int (*resume_early)(struct device * dev);
  •     int (*resume)(struct device * dev);
  •     unsigned int drivers_autoprobe:1;
  • };
  • struct device {        //…..省略一些成员
  •     struct klist        klist_children;
  •     struct klist_node   knode_parent;       /* node in sibling list */
  •     struct klist_node   knode_driver;
  •     struct klist_node   knode_bus;
  •     struct device       *parent;
  •     char    bus_id[BUS_ID_SIZE;         /* position on parent bus */
  •     struct bus_type * bus;              /* type of bus device is on */
  •     struct device_driver *driver;    /* which driver has allocated this device */
  •     void        *driver_data;               /* data private to the driver */
  •     void        *platform_data;            /* Platform specific data, device core doesn't touch it */
  • };
  • struct device_driver {    //…..省略一些成员
  •     const char         * 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);
  • };



按照面向对象的思想,
bus_type虚基类,子类包括 platform_bus_type,mdio_bus_type,I2C_bus_type,pci_bus_type等
device是虚基类,子类包括 platform_device,  phy_device,   i2c_CLIent, pci_device等
device_driver虚基类,子类有platform_driver,  phy_driver,i2c_driver, pci_driver等

2.API

框架有几个关键API:
bus_register(stuct bus_type* bus)         用来注册一条总线bus
device_register(struct device *dev)       把dev加到bus的设备列表中去
driver_register(stuct device_driver *drv)   
    1. 遍历bus上所有的dev,调用 drv->match(dev,drv) 对drv与dev进行比对
    2. 比对成功后调用 dev->bus->probe(dev) 或 drv->probe(dev)
    3. 把驱动drv加入到bus的驱动列表中去
    4. 绑定drv和dev
为了便于使用,内核针对不同总线,对上述API进行了包装,衍生出了另外一批API:
platform_driver_register
platform_device_register
phy_driver_register
mdiobus_register

下面讲将这3个API
  • bus_register(struct bus_type *bus)   
  •     //没啥说的,此函数最重要一点就是 bus->drivers_autoprobe=1


  • driver_register(struct device_driver *drv)
  •     --》bus_add_driver(drv)
  •     //若bus->drivers_autoprobe = 1
  •         --》driver_attach(drv)
  •         //遍历bus下所有dev,调用
  •             --》__driver_attach(dev,drv)
  •                 --》driver_probe_device(drv,dev)
  •             //调用 bus_type.match(dev, drv),如果比对成功就执行
  •                 --》really_probe(dev,drv)
  •                     //调用 bus->probe(dev) 或 drv->probe(dev)

3.总线的注册
所有总线的注册几乎内核启动过程时完成的。
start_kernel()
  --》rest_init()
    --》kernel_init()
      --》do_basic_setup()
        --》do_initcalls()
          --》platform_bus_init()--》bus_register(&platform_bus)
          --》mdio_bus_init()    --》bus_register(&mdio_bus_type)
          --》i2c_init()         --》bus_register(&i2c_bus_type)
粉红色的都是全局变量

小编很活跃,谢谢科普

小编很活跃,谢谢科普

小编很活跃,谢谢科普

小编很活跃,谢谢科普

小编很活跃,谢谢科普

谢谢小编!

小编很活跃,谢谢科普

感谢分享,,,,,

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top