zoukankan      html  css  js  c++  java
  • Linux 内核驱动结构嵌入

    如同大部分驱动核心结构的情形, device_driver 结构常常被发现嵌到一个更高级的, 总 线特定的结构. lddbus 子系统不会和这样的趋势相反, 因此它已定义了它自己的 ldd_driver 结构:

    struct ldd_driver { char *version;

    struct module *module; struct device_driver driver;

    struct driver_attribute version_attr;

    };

    #define to_ldd_driver(drv) container_of(drv, struct ldd_driver, driver);

    这里, 我们要求每个驱动提供特定当前软件版本, 并且 lddbus 输出这个版本字串为它知 道的每个驱动. 总线特定的驱动注册函数是:

    int register_ldd_driver(struct ldd_driver *driver)

    {

    int ret;

    driver->driver.bus = &ldd_bus_type;

    ret = driver_register(&driver->driver); if (ret)

    return ret;

    driver->version_attr.attr.name = "version"; driver->version_attr.attr.owner = driver->module; driver->version_attr.attr.mode = S_IRUGO;

    driver->version_attr.show = show_version; driver->version_attr.store = NULL;

    return driver_create_file(&driver->driver, &driver->version_attr);

    }

    这个函数的第一部分只注册低级的 device_driver 结构到核心; 剩下的建立版本属性. 因为这个属性在运行时被创建, 我们不能使用 DRIVER_ATTR 宏; 反之,

    driver_attribute 结构必须手工填充. 注意我们设定属性的拥有者为驱动模块, 不是 lddbus 模块; 这样做的理由是可以在为这个属性的 show 函数的实现中见到:

    static ssize_t show_version(struct device_driver *driver, char *buf)

    {

    struct ldd_driver *ldriver = to_ldd_driver(driver); sprintf(buf, "%s ", ldriver->version);

    return strlen(buf);

    }

    有人可能认为属性拥有者应当是 lddbus 模块, 因为实现这个属性的函数在那里定义. 这 个函数, 但是, 是使用驱动自身所创建的 ldd_driver 结构. 如果那个结构在一个用户空 间进程试图读取版本号时要消失, 事情会变得麻烦. 指定驱动模块作为属性的拥有者阻止 了模块被卸载, 在用户空间保持属性文件打开时. 因为每个驱动模块创建一个对 lddbus 模块的引用, 我们能确信 lddbus 不会在一个不合适的时间被卸载.

    为完整起见, sculld 创建它的 ldd_driver 结构如下:

    static struct ldd_driver sculld_driver = { .version = "$Revision: 1.1

    $", .module = THIS_MODULE, .driver = { .name = "sculld", }, };

    一个简单的对 register_ldd_driver 的调用添加它到系统中. 一旦完成初始化, 驱动信 息可在 sysfs 中见到:

    $ tree /sys/bus/ldd/drivers

    /sys/bus/ldd/drivers

    `-- sculld

    |-- sculld0 -> ../../../../devices/ldd0/sculld0

    |-- sculld1 -> ../../../../devices/ldd0/sculld1

    |-- sculld2 -> ../../../../devices/ldd0/sculld2

    |-- sculld3 -> ../../../../devices/ldd0/sculld3

    [46] 这个总线的逻辑名子, 当然, 应当是"sbus", 但是这个名子已经被一个真实的, 物理总 线采用.

  • 相关阅读:
    微信红包高并发交易
    MQ夺命11问
    美团雪花LEAF算法
    Mysql一遍过
    分布式
    如何注册和发现服务
    服务发布和引用
    微服务的构成
    什么是微服务
    Java的动态代理
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11147990.html
Copyright © 2011-2022 走看看