如同大部分驱动核心结构的情形, 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\n",
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", 但是这个名子已经被一个真实的, 物理总 线采用.

Linux 内核驱动结构嵌入的更多相关文章

  1. Linux 内核 设备结构嵌入

    设备结构包含设备模型核心需要的来模型化系统的信息. 大部分子系统, 但是, 跟踪关于 它们驻留的设备的额外信息. 结果, 对设备很少由空设备结构所代表; 相反, 这个结构, 如同 kobject 结构 ...

  2. linux内核驱动模型

    linux内核驱动模型,以2.6.32内核为例.(一边写一边看的,有点乱.) 1.以内核对象为基础.用kobject表示,相当于其它对象的基类,是构建linux驱动模型的关键.具有相同类型的内核对象构 ...

  3. linux 内核驱动--Platform Device和Platform_driver注册过程

    linux 内核驱动--Platform Device和Platform_driver注册过程 从 Linux 2.6 起引入了一套新的驱动管理和注册机制 :Platform_device 和 Pla ...

  4. 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化

    2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...

  5. Linux内核驱动学习(八)GPIO驱动模拟输出PWM

    文章目录 前言 原理图 IO模拟输出PWM 设备树 驱动端 调试信息 实验结果 附录 前言 上一篇的学习中介绍了如何在用户空间直接操作GPIO,并写了一个脚本可以产生PWM.本篇的学习会将写一个驱动操 ...

  6. Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/font ...

  7. Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2 ...

  8. 【引用】Linux 内核驱动--多点触摸接口

    本文转载自James<Linux 内核驱动--多点触摸接口>   译自:linux-2.6.31.14\Documentation\input\multi-touch-protocol.t ...

  9. Linux内核驱动开发之KGDB原理介绍及kgdboe方式配置

    接博文<Linux内核驱动开发之KGDB单步调试内核(kgdboc方式)>.上篇博文中,仅简单介绍使用串口的Kgbd的流程(kgdboc方式),本文将重点介绍KGDB调试Linux内核的原 ...

随机推荐

  1. vue2-vux-fitness-project

    非常感谢那些无私开源的程序员,希望我也能够有能力像你们那样,开源很多很有意思的东西~~ //index.html <!DOCTYPE html> <html> <head ...

  2. springboot 启动配置原理【转】【补】

    创建应用 几个重要的事件回调机制  , 配置在META-INF/spring.factories ApplicationContextInitializer SpringApplicationRunL ...

  3. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试 代码工程地址: https://github.co ...

  4. 2019-10-18-dotnet-文件读写务必注意事项

    title author date CreateTime categories dotnet 文件读写务必注意事项 lindexi 2019-10-18 08:42:53 +0800 2019-10- ...

  5. Java面向对象----String对象的声明和创建

    String a="abcd"  相等  String b="abcd" String a=new String("abcd")   不等于 ...

  6. @atcoder - AGC034E@ Complete Compress

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N 个点的树,编号为 1, 2, ..., N.第 i ...

  7. 从浏览器的url中获取查询字符串的参数

    正则表达式: function getQuery(name){ var reg = new RegExp("(^|&)" + name + "=([^&] ...

  8. 【t001】不高兴的津津

    Time Limit: 1 second Memory Limit: 50 MB [问题描述] 津津上初中了.妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班.另外 ...

  9. uni-app学习记录07-生命周期

    <template> <view class="content"> 我是首页 </view> </template> <scr ...

  10. 多线程:“对象当前正在其他地方使用”如何解决 system.drawing

    使用这个委托,在拥有此控件的基础窗口句柄的线程上执行指定委托 this.Invoke(new Action(() => { node.SetValues(values); }));