zoukankan      html  css  js  c++  java
  • [国嵌攻略][125][总线设备驱动模型]

    总线模型

    随着技术的不断进步,系统的拓扑结构也越来越复杂,对热插拔,跨平台移植性的要求越来越高,2.4内核已经难以满足这些需求。为了适应这种形势的需要,从Linux2.6内核开始提供了全新的设备驱动模型。

    总线驱动设备模型

    这个模型首先有一条总线,然后是总线上挂载有很多驱动。当有设备插到总线上的时候,总线会把设备和驱动进行匹配,当设备匹配到驱动时,总线把控制权交给相应的驱动处理;当设备从总线上拔掉的时候,总线会找到相应的驱动来处理相应的事件。这样驱动就可以支持热插拔,并且当驱动从一种总线(如USB)改到另一种总线(如MINIPCI)时,驱动需要修改的部分很少,提高了驱动的可移植性。

    总线

    1.描述结构

    在Linux内核中,总线由bus_type结构表示,定义在<linux/device.h>

    struct bus_type{

        const char *name;   //总线名称

        int (*match)(struct device *dev, struct device_driver *drv);   //匹配函数,驱动与设备的匹配函数。如果返回非零表示匹配成功,否则匹配失败。物理总线通过设备中的ID与驱动进行匹配,虚拟总线通过设备的名字与驱动进行匹配。

        ......

    }

    2.总线的注册与注销

    总线的注册使用:

    bus_register(struct bus_type *bus)

    若成功,新的总线将被添加进系统,并可以在/sys/bus下看到相应的目录

    总线的注销使用:

    void bus_unregister(struct bus_type *bus)

    busmod.c

    /********************************************************************
    *头文件
    *********************************************************************/
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/device.h>
    
    /********************************************************************
    *总线匹配
    *********************************************************************/
    //总线匹配
    int bus_match(struct device *dev, struct device_driver *drv){
        //名称匹配
        int isMatch;
        
        isMatch = !strncmp(dev->kobj.name, drv->name, strlen(drv->name));
        
        return isMatch;
    }
    
    /********************************************************************
    *模块安装
    *********************************************************************/
    //总线结构
    struct bus_type busmod = {
        .name  = "busmod",   //总线名称
        .match = bus_match   //匹配函数
    };
    
    //安装模块
    static int ibus_init(void){
        //注册总线
        bus_register(&busmod);
        
        return 0;
    }
    
    //卸载模块
    static void ibus_exit(void){
        //注销总线
        bus_unregister(&busmod);
    }
    
    /********************************************************************
    *模块声明
    *********************************************************************/
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("D");
    MODULE_DESCRIPTION("");
    MODULE_VERSION("v1.0");
    
    EXPORT_SYMBOL(busmod);
    
    module_init(ibus_init);
    module_exit(ibus_exit);

    驱动

    1.描述结构

    在Linux内核中,驱动由device_driver结构来表示。

    struct device_driver{

        const char *name;   //驱动名称

        struct bus_type *bus;   //驱动程序所在的总线

        int (*probe)(struct device *dev);   //驱动函数,当总线找到与设备匹配的驱动时,调用该函数对设备进行处理

        ......

    }

    2.驱动的注册与注销

    驱动的注册使用:

    int driver_register(struct device_driver *drv)

    若成功,新的驱动将被添加进系统,并可以在/sys/bus/xxx/drivers下看到该驱动。

    驱动的注销使用:

    void driver_unregister(struct device_driver *drv)

    drvmod.c

    /********************************************************************
    *头文件
    *********************************************************************/
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/device.h>
    
    /********************************************************************
    *全局变量
    *********************************************************************/
    extern struct bus_type busmod;
    
    /********************************************************************
    *驱动处理
    *********************************************************************/
    //驱动处理
    int drv_probe(struct device *dev){
        printk("Driver found the device it can be handle!
    ");
        
        return 0;
    }
    
    /********************************************************************
    *模块安装
    *********************************************************************/
    //驱动结构
    struct device_driver drvmod = {
        .name  = "drvmod",    //驱动名称
        .bus   = &busmod,     //所属总线
        .probe = drv_probe,   //驱动函数
    };
    
    //安装模块
    static int idrv_init(void){
        //注册驱动
        driver_register(&drvmod);
        
        return 0;
    }
    
    //卸载模块
    static void idrv_exit(void){
        //注销驱动
        driver_unregister(&drvmod);
    }
    
    /********************************************************************
    *模块声明
    *********************************************************************/
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("D");
    MODULE_DESCRIPTION("");
    MODULE_VERSION("v1.0");
    
    module_init(idrv_init);
    module_exit(idrv_exit);

    设备

    1.描述结构

    在Linux内核中,设备由struct device结构表示。

    struct device{

        const char *init_name;   //设备名称,必须与驱动名称相同

        struct bus_type *bus;   //设备所在的总线

        struct kobject kobj.name;   //当调用device_register函数时,init_name会被赋值到该变量,然后清空init_name。

        ......

    }

    2.设备的注册与注销

    设备的注册使用:

    int device_register(struct device *dev)

    若成功,新的设备将被添加进系统,并可以在/sys/bus/xxx/devices下看到该设备。

    设备的注销使用:

    void device_unregister(struct device *dev)

    devmod.c

    /********************************************************************
    *头文件
    *********************************************************************/
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/device.h>
    
    /********************************************************************
    *全局变量
    *********************************************************************/
    extern struct bus_type busmod;
    
    /********************************************************************
    *模块安装
    *********************************************************************/
    //设备结构
    struct device devmod = {
        .init_name = "drvmod",   //设备名称,必须与驱动名称相同
        .bus       = &busmod     //所属总线
    };
    
    //安装模块
    static int idev_init(void){
        //注册设备
        device_register(&devmod);
        
        return 0;
    }
    
    //卸载模块
    static void idev_exit(void){
        //注销设备
        device_unregister(&devmod);
    }
    
    /********************************************************************
    *模块声明
    *********************************************************************/
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("D");
    MODULE_DESCRIPTION("");
    MODULE_VERSION("v1.0");
    
    module_init(idev_init);
    module_exit(idev_exit);

    先有驱动后有设备和先有设备后有设备,总线都能让驱动和设备匹配。

    第一种情况:

    总线上面已经挂载了驱动,然后添加设备,总线会拿match函数去对设备与每个驱动进行匹配。如果能够匹配,那么会调用相应的probe函数。

    第二种情况:

    总线上面已经挂载了设备,然后添加驱动,总线会拿match函数去对驱动与每个设备进行匹配。如果能够匹配,那么会调用相应的probe函数。

  • 相关阅读:
    多数据源报表解析之简单多源报表
    8.5.4 Optimizing InnoDB Redo Logging 优化InnoDB Redo Logging
    8.5.2 Optimizing InnoDB Transaction Management
    8.5.1 Optimizing Storage Layout for InnoDB Tables
    Linux_RHEL7_YUM
    Linux_RHEL7_YUM
    Python基本语法_函数_返回值
    Python基本语法_函数_返回值
    8.4 Optimizing Database Structure 优化数据库结构
    8.3.7 InnoDB and MyISAM Index Statistics Collection InnoDB 和MyISAM 索引统计信息收集
  • 原文地址:https://www.cnblogs.com/d442130165/p/5259776.html
Copyright © 2011-2022 走看看