zoukankan      html  css  js  c++  java
  • Linux总线设备驱动模型

    1. Linux2.6内核引入总线、设备、驱动模型来描述各种总线(PCI、USB、I2C、SPI)与外围设备及其驱动之间的关系。

    2. 在Linux内核中,总线用bus_type结构来描述,定义于文件:include/linux/Device.h

    struct bus_type {
        const char        *name;
        struct bus_attribute    *bus_attrs;
        struct device_attribute    *dev_attrs;
        struct driver_attribute    *drv_attrs;
    
        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);
    
        struct dev_pm_ops *pm;
    
        struct bus_type_private *p;
    };

    ① name:总线名字,如PCI

    bus_attrs:总线属性

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

    ④ uevent:

    ⑤ probe:

    ⑥ remove:

    (1) 总线的注册:int us_register(struct bus_type *bus)(若注册成功,新的总线将被添加进系统,可在/sys/bus 下看到相应的目录)

    (2) 总线的注销:void bus_unregister(struct bus_type *bus)

    3. 在Linux内核中, 驱动由device_driver结构描述

    struct device_driver {
        const char        *name;
        struct bus_type        *bus;
    
        struct module        *owner;
        const char         *mod_name;    /* used for built-in modules */
    
        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);
        struct attribute_group **groups;
    
        struct dev_pm_ops *pm;
    
        struct driver_private *p;
    };

    ① probe:

    ② remove:

    (1)驱动的注册:int driver_register(struct device_driver *drv)

    (2)驱动的注销:void driver_unregister(struct device_driver *drv)

    4. 在Linux内核中, 设备由struct device结构描述

    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;
    
        struct kobject kobj;
        char    bus_id[BUS_ID_SIZE];    /* position on parent bus */
        unsigned        uevent_suppress:1;
        const char        *init_name; /* initial name of the device */
        struct device_type    *type;
    
        struct semaphore    sem;    /* semaphore to synchronize calls to
                         * its driver.
                         */
    
        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 dev_pm_info    power;
    
    #ifdef CONFIG_NUMA
        int        numa_node;    /* NUMA node this device is close to */
    #endif
        u64        *dma_mask;    /* dma mask (if dma'able device) */
        u64        coherent_dma_mask;/* Like dma_mask, but for
                             alloc_coherent mappings as
                             not all hardware supports
                             64 bit addresses for consistent
                             allocations such descriptors. */
    
        struct device_dma_parameters *dma_parms;
    
        struct list_head    dma_pools;    /* dma pools (if dma'ble) */
    
        struct dma_coherent_mem    *dma_mem; /* internal for coherent mem
                             override */
        /* arch specific additions */
        struct dev_archdata    archdata;
    
        dev_t            devt;    /* dev_t, creates the sysfs "dev" */
    
        spinlock_t        devres_lock;
        struct list_head    devres_head;
    
        struct klist_node    knode_class;
        struct class        *class;
        struct attribute_group    **groups;    /* optional groups */
    
        void    (*release)(struct device *dev);
    };

    (1)设备的注册:int device_register(struct device *dev)

    (2)设备的注销:void device_unregister(struct device *dev)

    5. 简单示例

    (1)Bus.c

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/device.h>
    
    MODULE_LICENSE("GPL");
    
    int my_match(struct device *dev, struct device_driver *drv)
    {
        printk("Bus: my_match
    ");
        return !strncmp(dev->kobj.name, drv->name, strlen(drv->name));
    }
    
    int my_remove(struct device *dev)
    {
        printk("Bus: Device %s removed from bus
    ", dev->init_name);
    }
    
    struct bus_type my_bus_type = {
        .name = "my_bus",
        .match = my_match,
        .remove = my_remove,
    };
        
    EXPORT_SYMBOL(my_bus_type);
    
    int my_bus_init(void)
    {
        int ret;
        
        ret = bus_register(&my_bus_type);
        
        return ret;
    }
    
    void my_bus_exit(void)
    {
        bus_unregister(&my_bus_type);
    }
    
    module_init(my_bus_init);
    module_exit(my_bus_exit);

    (2)Device.c

    #include <linux/device.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    
    MODULE_LICENSE("GPL");
    
    extern struct bus_type my_bus_type;
    
    void my_release(struct device *dev)
    {
        printk("Device: Device %s's release function
    ", dev->init_name);
    }
    
    struct device my_dev = {
        .init_name = "my_dev",
        .bus = &my_bus_type,
        .release = my_release,
    };
    
    int my_device_init(void)
    {
        int ret;
        ret = device_register(&my_dev);
        return ret;
    }
    
    void my_device_exit(void)
    {
        device_unregister(&my_dev);
    }
    
    module_init(my_device_init);
    module_exit(my_device_exit);

    (3)Driver.c

    #include <linux/device.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    
    MODULE_LICENSE("GPL");
    
    extern struct bus_type my_bus_type;
    
    int my_probe(struct device *dev)
    {
        printk("Driver: driver found the device it can handle!
    ");
        return 0;
    }
    
    struct device_driver my_driver = {
        .name = "my_dev",
        .bus = &my_bus_type,    
        .probe = my_probe,
    };
    
    int my_driver_init(void)
    {
        int ret;
        
        ret = driver_register(&my_driver);
        
        return ret;
    }
    
    void my_driver_exit(void)
    {
        driver_unregister(&my_driver);    
    }
    
    module_init(my_driver_init);
    module_exit(my_driver_exit);
  • 相关阅读:
    递延收益的主要账务处理
    少数股东权益
    一揽子交易中处置价款与净资产账面价值差额为什么计入其他综合收益
    为什么权益法下其他综合收益合并时要计入投资收益
    R语言代写实现MCMC中的Metropolis–Hastings算法与吉布斯采样
    加速R语言代码的策略
    R语言代写:EM算法和高斯混合模型的实现
    R语言代写进行网站评论文本数据挖掘聚类
    R语言代写对推特数据进行文本情感分析
    WEKA代写文本挖掘分析垃圾邮件分类模型
  • 原文地址:https://www.cnblogs.com/wulei0630/p/9542343.html
Copyright © 2011-2022 走看看