我们在Linux设备管理(一)_kobject, kset,ktype分析一文中介绍了kobject的相关知识,在Linux设备管理(二)_从cdev_add说起Linux设备管理(三)_总线设备的挂接举例介绍了内核中是如何进行设备管理的,并在Linux设备管理(四)_从sysfs回到ktype一文中结合sysfs机制和kobject对内核的设备管理机制进行一定深度的讨论,从中可以看出,字符设备的cdev本身的kobject是没有初始化的,也没有在sysfs中创建任何目录,平台设备是将设备挂接到总线上,在挂接的过程中就会在相应的sysfs目录创建相应的文件。在这里,本文将搭建一个sysfs模块接口的框架,此后,就可以为我们自己的驱动在sysfs中添加属性读写接口。

准备属性和回调接口

我们知道,呈现在sysfs中的文件名其实都是内核中ktype的属性值,而从用户空间对这些属性值进行读写其实就是回调了我们在ktype结构中注册读写函数,所以,这里我们准备了两个函数,值得注意的是,内核会将用户空间的buf转换到内核空间并当作参数传入回调函数,所以我们就不用再进行这个转换。这里由于没有实际的属性,我就只是打印一下信息,实际使用的时候这两个函数要对内核中的真实属性进行读写。

static char kbuf[1024] = {0};
static ssize_t my_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
char info[]="my_show is called\n";
return scnprintf(buf,sizeof(info),info);
} static ssize_t my_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
printk("%s is called\n",__func__);
strncpy(kbuf,buf,count);
printk("user_buf:%s,count:%ld|after copy,kbuf:%s\n",buf,count,kbuf);
return count;
}

构造kobj_attribute

准备好了原材料,第一道工序就是将属性和回调接口封装到一个kobj_attribute结构对象中,当然对这个属性的读写权限等信息也应该进行封装,我们来回顾一下这个结构

//linux/kobject.h
139 struct kobj_attribute {
140 struct attribute attr;
141 ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
142 char *buf);
143 ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
144 const char *buf, size_t count);
145 }; //linux/sysfs.h
29 struct attribute {
30 const char *name;
31 umode_t mode; //权限
32 ...
37 };

当然,内核也给我们提供了相应的宏来快速的构造这个结构

//linux/sysfs.h
100 #define __ATTR(_name, _mode, _show, _store) { \
101 .attr = {.name = __stringify(_name), \
102 .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
103 .show = _show, \
104 .store = _store, \
105 }

使用了这个宏,我们就可以快速的构造我们的kobj_attribute结构

//show是name,就是sys中的文件名
static struct kobj_attribute my_sysfs_read =__ATTR(show, S_IRUSR, my_show, NULL); static struct kobj_attribute my_sysfs_write =__ATTR(write, S_IWUSR, NULL,my_store);

构造attribute数组

一个kobject网完对应多个attribute,此时就需要将这些attribute封装成一个结构体数组,注意这个数组最后一个元素一定要是NULL

static struct attribute *my_sysfs_attr[] = {
&my_sysfs_read.attr,
&my_sysfs_write.attr,
NULL,
};

如果这些属性直接放到kobject的目录中,我们可以直接使用sysfs_create_file(),但通常情况下,我们更多的将上述的struct attribute进行进一步的封装,并使用sysfs_create_group()来创建一个名为attribute_group.name的、包含struct attribute中的属性目录,这种方式更加的灵活,因为如果我们不指定目录的名字,那么效果个sysfs_create_file()是一样的。

static struct attribute_group my_sysfs_attr_group = {
.name = "sub_my_attr", //不写这个成员就不会创建子文件夹
.attrs = my_sysfs_attr,
}; struct kobject *my_kobj = NULL;
int mysys_init(void)
{
...
my_kobj = kobject_create_and_add("my_sysfs", NULL);
sysfs_create_group(my_kobj, &my_sysfs_attr_group);
...
} void mysys_exit(void)
{
...
sysfs_remove_group(my_kobj, &my_sysfs_attr_group);
kobject_put(my_kobj);
}

输出

将上述的程序编译成模块,我们就可以观察到下面的输出结果。

Linux设备管理(五)_写自己的sysfs接口的更多相关文章

  1. Linux操作系统(五)_部署Zentao

    一.部署Zentao 1.检查服务器信息 uname -a 2.下载相应的部署包(一键安装包) http://dl.cnezsoft.com/zentao/9.8.1/ZenTaoPMS.9.8.1. ...

  2. Linux设备管理(四)_从sysfs回到ktype

    sysfs是一个基于ramfs的文件系统,在2.6内核开始引入,用来导出内核对象(kernel object)的数据.属性到用户空间.与同样用于查看内核数据的proc不同,sysfs只关心具有层次结构 ...

  3. Linux设备管理(四)_从sysfs回到ktype【转】

    转自:https://www.cnblogs.com/xiaojiang1025/archive/2016/12/21/6202298.html sysfs是一个基于ramfs的文件系统,在2.6内核 ...

  4. Linux设备管理(二)_从cdev_add说起

    我在Linux字符设备驱动框架一文中已经简单的介绍了字符设备驱动的基本的编程框架,这里我们来探讨一下Linux内核(以4.8.5内核为例)是怎么管理字符设备的,即当我们获得了设备号,分配了cdev结构 ...

  5. Linux设备管理(三)_总线设备的挂接

    扒完了字符设备,我们来看看平台总线设备,平台总线是Linux中的一种虚拟总线,我们知道,总线+设备+驱动是Linux驱动模型的三大组件,设计这样的模型就是将驱动代码和设备信息相分离,对于稍微复杂一点的 ...

  6. Linux设备管理(一)_kobject, kset,ktype分析

    Linux内核大量使用面向对象的设计思想,通过追踪源码,我们甚至可以使用面向对象语言常用的UML类图来分析Linux设备管理的"类"之间的关系.这里以4.8.5内核为例从kobje ...

  7. linux设备管理之主设备号与次设备号

    主设备号和次设备号 一个字符设备或者块设备都有一个主设备号和次设备号.主设备号和次设备号统称为设备号.主设备号用来表示一个特定的驱动程序.次设备号用来表示使用该驱动程序的其他设备.(主设备号和控制这类 ...

  8. 《sed的流艺术之三》-linux命令五分钟系列之二十三

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  9. 《sed的流艺术之二》-linux命令五分钟系列之二十二

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

随机推荐

  1. ASP.NET Core MVC/WebAPi 模型绑定探索

    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...

  2. git 命令

    切换仓库地址: git remote set-url origin xxx.git切换分支:git checkout name撤销修改:git checkout -- file删除文件:git rm  ...

  3. Vue-Router 页面正在加载特效

    Vue-Router 页面正在加载特效 如果你在使用 Vue.js 和 Vue-Router 开发单页面应用.因为每个页面都是一个 Vue 组件,你需要从服务器端请求数据,然后再让 Vue 引擎来渲染 ...

  4. .NET Core的日志[4]:将日志写入EventLog

    面向Windows的编程人员应该不会对Event Log感到陌生,以至于很多人提到日志,首先想到的就是EventLog.EventLog不仅仅记录了Windows系统自身针对各种事件的日志,我们的应用 ...

  5. 【Reading Note】算法读书杂记

    1 排序 排序基本信息 稳定性:排序前大的数在排序后,大的数依然保持不变就是稳定排序,反之不稳定 内外排序:根据待排序的记录是否放在内存里面区分的.诸如:插入排序(直接插入&希尔).交换排序( ...

  6. 玩转spring boot——MVC应用

    如何快速搭建一个MCV程序? 参照spring官方例子:https://spring.io/guides/gs/serving-web-content/ 一.spring mvc结合thymeleaf ...

  7. 让你从零开始学会写爬虫的5个教程(Python)

    写爬虫总是非常吸引IT学习者,毕竟光听起来就很酷炫极客,我也知道很多人学完基础知识之后,第一个项目开发就是自己写一个爬虫玩玩. 其实懂了之后,写个爬虫脚本是很简单的,但是对于新手来说却并不是那么容易. ...

  8. HTML5 程序设计 - 使用HTML5 Canvas API

    请你跟着本篇示例代码实现每个示例,30分钟后,你会高喊:“HTML5 Canvas?!在哥面前,那都不是事儿!” 呵呵.不要被滚动条吓到,很多都是代码和图片.我没有分开写,不过上面给大家提供了目录,方 ...

  9. 关系型数据库与NoSQL数据库

    关系型数据库的优缺点 优点: 可以做事务处理,从而保证了数据的一致性: 可以进行JOIN等多表查询: 由于以SQL标准化为前提,数据更新的开销很小(相同的字段基本上都只有一处). 缺点: 大量数据的写 ...

  10. svnserver hook python

    在使用中可能会遇到的错误排除 :1.Error: svn: 解析"D:\www\test"出错,或svn: E020024: Error resolving case of 'D: ...