52 linux设备驱动模型的sysfs接口
来源:互联网 发布:linux 查看内存泄漏 编辑:程序博客网 时间:2024/05/21 17:37
除了在proc目录里实现驱动的简单接口外,还可以/sys目录下实现驱动接口
//在linux内核里很多结构体都包含有kobject成员. 通常每个kobject对象在/sys/目录下有对应的目录
struct kobject { const char *name; //显示的目录名 struct list_head entry; //内核里用于管理kobject对象用,通过此成员加入链表 struct kobject *parent; //也就在指定此kobject对象是在什么目录下的 struct kset *kset; //多个同类型(同子系统)的kobject对象的集合 struct kobj_type *ktype; //指定当前kobject对象的类型 struct sysfs_dirent *sd; // 对应的/sys下的目录 struct kref kref; // 引用当前对象的计数 unsigned int state_initialized:1; //是否已初始化 unsigned int state_in_sysfs:1; //是否显示在/sys目录里 unsigned int state_add_uevent_sent:1; //已增加热插拔事件 unsigned int state_remove_uevent_sent:1; // 移除热插拔事件 unsigned int uevent_suppress:1; };
每个kobject对象表示/sys目录的一个子目录, 此目录里还可以有可读写的文件, 这些文件叫属性(attribute).
每个kobject对象创建时都带有默认的属性, 也可加入自定义的属性.
struct attribute { const char *name; //文件名 umode_t mode; //权限 ...}int sysfs_create_file(struct kobject *kobj,const struct attribute *attr); //在kobj目录下, 创建属性文件void sysfs_remove_file(struct kobject *kobj , const struct attribute *attr); //移除kobj目录下的属性文件
/////////////////////////////////////////////设备的属性文件/////////////////////////////
//在linux内核的驱动模型里的device结构体struct device { struct device *parent; ... struct kobject kobj; //包含有kobject对象, 设备对象在/sys/bus/.../devices下可查看 const char *init_name; ...}struct device_attribute { struct attribute attr; //基于attribute扩展的属性 ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); //读属性文件时触发调用的函数 ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); //写属性文件时触发调用的函数}; //基于attribute扩展而来,以便为设备创建属性文件int device_create_file(struct device *dev, const struct device_attribute *attr) //方便为设备增加属性文件的函数{ int error = 0; if (dev) error = sysfs_create_file(&dev->kobj, &attr->attr); //真家伙 return error;}void device_remove_file(struct device *dev, const struct device_attribute *attr) //方便移除设备的属性文件的函数{ if (dev) sysfs_remove_file(&dev->kobj, &attr->attr); //真家伙}
///////////
如为平台设备增加一属性文件:
test.c
#include <linux/init.h>#include <linux/module.h>#include <linux/sysfs.h>#include <linux/platform_device.h>ssize_t myshow(struct device *dev, struct device_attribute *attr, char *buf){ static int n = 0; sprintf(buf, "n = %d\n", n++); return strlen(buf);}size_t mystore(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ printk("in mystore: %s\n", buf); return count;}struct device_attribute attr = { .attr = {"hello", 0644}, .show = myshow, .store = mystore,};struct platform_device pdev = { .name = "haha", .id = -1, };static int __init test_init(void){ int ret; ret = platform_device_register(&pdev); sysfs_create_file(&pdev.dev.kobj, &attr.attr); return 0;}static void __exit test_exit(void){ sysfs_remove_file(&pdev.dev.kobj, &attr.attr); platform_device_register(&pdev);}module_init(test_init);module_exit(test_exit);MODULE_LICENSE("GPL");
/////////
加载模块后, 对”/sys/bus/platform/devices/haha/hello”文件读写即可
/////////////////////////////////////////////总线的属性文件/////////////////////////////
struct bus_type { const char *name; ... struct subsys_private *p; // 里面有struct kset类型(kobject对象的集合)的成员: subsys, devices_kset, drivers_kset. 所以在"/sys/bus/xx/"总线目录下有devices目录装载挂载到总线的设备, drivers目录挂载到总线的设备驱动}struct bus_attribute { struct attribute attr; ssize_t (*show)(struct bus_type *bus, char *buf); ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);}; //为了方便总线创建属性文件封装的类型int bus_create_file(struct bus_type *bus, struct bus_attribute *attr) //为总线创建属性文件{ int error; if (bus_get(bus)) { error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr); //真家伙 ...}EXPORT_SYMBOL_GPL(bus_create_file);void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr){ if (bus_get(bus)) { sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr); //真家伙 bus_put(bus); }}EXPORT_SYMBOL_GPL(bus_remove_file);
/////////////////////////////////////////////设备驱动的属性文件/////////////////////////////
struct device_driver { const char *name; struct bus_type *bus; ... struct driver_private *p; //里有struct kobject成员kobj, 所以设备驱动注册后也会在总线的drivers目录下有一个名为name的目录.};struct driver_attribute { struct attribute attr; ssize_t (*show)(struct device_driver *driver, char *buf); ssize_t (*store)(struct device_driver *driver, const char *buf, size_t count);}; //为了方便在设备驱动目录创建属性文件封装出来的类型int driver_create_file(struct device_driver *drv, const struct driver_attribute *attr){ int error; if (drv) error = sysfs_create_file(&drv->p->kobj, &attr->attr); //真家伙 ...}EXPORT_SYMBOL_GPL(driver_create_file);void driver_remove_file(struct device_driver *drv, const struct driver_attribute *attr){ if (drv) sysfs_remove_file(&drv->p->kobj, &attr->attr); //真家伙}EXPORT_SYMBOL_GPL(driver_remove_file);
阅读全文
0 0
- 52 linux设备驱动模型的sysfs接口
- Linux设备驱动模型 sysfs
- Linux设备驱动模型一 sysfs
- Linux设备驱动模型一 sysfs
- linux设备驱动模型之sysfs
- linux设备模型--sysfs
- 设备驱动模型与sysfs
- 初识Linux设备驱动模型与sysfs(1)
- linux ------ 设备驱动模型之一(sysfs, koject, kset)
- Linux设备驱动模型框架分析(五)——LDDM的展现:sysfs
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的关系
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
- 非常重要----1、字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
- 写给自己的Java程序员学习路线图
- 注解式开发
- json调用
- android6.0屏蔽声音加减
- TF Learn入门 —— 简单使用举例
- 52 linux设备驱动模型的sysfs接口
- 传统线程同步通信技术
- 基于Kubernetes的分布式压力测试方案
- XJTU2017Robocon少年的总结
- spring事务和synchronized锁的一些问题
- api返回json
- ES6/ES2015常用语法 (上)
- CloudStack VM系统被还原的原因
- python在线编译器的简单原理与超简单实现