如同大部分驱动核心结构的情形, 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. dsadsa

    1.Swift预览 一般来说,编程语言教程中的第一个程序是在屏幕上打印“Hello, world”.在 Swift 中,可以用一行代码实现: println("Hello, world&qu ...

  2. spring boot 2.X上传文件限制大小

    Spring Boot 1.3.x multipart.maxFileSize multipart.maxRequestSize Spring Boot 1.4.x and 1.5.x spring. ...

  3. VelocityTracker监控速度!!!

    用来追踪触摸事件(flinging事件和其他手势事件)的速率.用obtain()函数来获得类的实例,用addMovement(MotionEvent)函数将motion event加入到Velocit ...

  4. @codeforces - 1153F@ Serval and Bonus Problem

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 从一条长度为 l 的线段中随机选择 n 条线段,共 2*n 个线 ...

  5. 报错No module named IPython的解决方法

    没有按照 ipython 或者 ide 没有选择编译器

  6. hdu 3873 Invade the Mars(有限制的最短路 spfa+容器)

    Invade the Mars Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 365768/165536 K (Java/Others ...

  7. behavior planning——14.implement a cost function in C++

    n most situations, a single cost function will not be sufficient to produce complex vehicle behavior ...

  8. jieba中文分词源码分析(四)

    一.未登录词问题在jieba中文分词的第一节曾提到未登录词问题 中文分词的难点 分词规范,词的定义还不明确 (<统计自然语言处理>宗成庆)歧义切分问题,交集型切分问题,多义组合型切分歧义等 ...

  9. TabHost选项卡的实现(一):使用TabActivity实现

    一. TabHost的基本开发流程 TabHost是一种非常实用的组件,可以很方便的在窗口上防止多个标签页,每个标签页相当于获得了一个外部容器相同大小的组件摆放区域. 我们熟悉的手机电话系统" ...

  10. 精选Pycharm里6大神器插件

    http://www.sohu.com/a/306693644_752099 上次写了一篇关于Sublime的精品插件推荐,有小伙伴提议再来一篇Pycharm的主题.相比Sublime,Pycharm ...