驱动-设备模型kobject实现属性文件读写功能

驱动设备模型kobject属性文件读写功能实现

提示:设备模型kobject实现属性文件读写功能


前言

前面了解了设备模型基础,设备模型框架kobject/kset 的创建,那么针对kobject 属性如何读写? 这里就讲这个知识点。

参考资料

什么是引用计数器
引用计数器实验
kobject释放实例分析实验
迅为设备模型篇
Linux驱动-引用计数器kref
引入并完善kobject_type结构体
创建属性文件并实现读写功能实验1
在线查看Linux 系统源码:Linux Kernel Cross Reference (LXR)

一、基本知识点

创建kboject 两种方法再思考

设备模型基本框架-kobject-kset 篇章中我们对比了两种创建kobject 方式。如下:我们也同步回顾一下之前的知识点。

struct kobject *kobject_create_and_add(const char *name, struct kobject *parent);

int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, 
                         struct kobject *parent, const char *fmt, ...);

关键区别kobject_create_and_add - kobject_init_and_add

特性 kobject_create_and_add kobject_init_and_add
内存分配 内部动态分配 由调用者预先分配
初始化控制 自动完成基础初始化 需手动指定kobj_type等参数
适用场景 独立kobject kobject嵌入到其他结构体中
释放方式 直接kobject_put() 通过ktype->release回调释放外层结构
灵活性 较低 较高

如何选择kobject_create_and_add - kobject_init_and_add

  • 优先kobject_init_and_add:当kobject是自定义结构体的一部分时(常见于设备驱动)。
  • 使用kobject_create_and_add:当仅需一个独立的kobject且无需复杂控制时(例如创建简单sysfs节点)。

两种创建方式小结

上面已经分析了两种方式区别,kobject_init_and_add 方式更具备扩展性,大家发现扩展性通过什么来支持的呢? 不就是它的第三个参数 kobj_type 嘛。 那我们就分析下 kobj_type 结构体是作什么的。

结构体 kobj_type

结构体定义

struct kobj_type {
   
   
	void (*release)(struct kobject *kobj);
	const struct sysfs_ops *sysfs_ops;
	struct attribute **default_attrs;
	const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
	const void *(*namespace)(struct kobject *kobj);
	void (*get_ownership)(struct kobject *kobj, kuid_t *uid, kgid_t *gid);

	ANDROID_KABI_RESERVE(1);
	ANDROID_KABI_RESERVE(2);
	ANDROID_KABI_RESERVE(3);
	ANDROID_KABI_RESERVE(4);
};

分析:之前的门在字符设备里面还有上一节kref 计数器知识点,我们大概就能看出基本内容:

  • release 参数结构体回调:释放结构体时候回调,前面一节Linux驱动-引用计数器kref篇已经验证过。
  • sysfs_ops 如同之前知识点 像是文件相关操作,大概那就是kobject 的一些读写操作
  • attribute 不就是属性相关操作嘛

成员初识

struct kobj_type 是 Linux 内核中用于定义内核对象(kobject)类型的关键数据结构,它描述了属于同一类型的内核对象的共同行为和属性。以下是该结构体每个成员的详细说明:

release - 对象释放回调函数
void (*release)(struct kobject *kobj);

**作用:**当kobject的引用计数降为0时调用的释放函数

**必须实现:**所有kobj_type都必须提供此回调

典型实现:

void my_release(struct kobject *kobj) {
   
   
    struct my_struct *obj = container_of(kobj, struct my_struct, kobj);
    kfree(obj);
}

注意事项:

  • 必须正确处理包含kobject的结构体的释放
  • 通常使用container_of宏获取包含kobject的父结构体
sysfs_ops - sysfs操作集
const struct sysfs_ops *sysfs_ops;

**作用:**定义在sysfs中如何显示和存储属性
相关结构:

struct sysfs_ops {
   
   
    ssize_t (*show)(struct kobject *, struct attribute *, char *);
    ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
};

方法说明:

  • show:当用户读取sysfs属性文件时调用
  • store:当用户写入sysfs属性文件时调用

示例:

static const struct sysfs_ops my_sysfs_ops = {
   
   
    .show = my_attr_show,
    .store = my_attr_store,
};
default_attrs - 默认属性数组
struct attribute **default_attrs;

**作用:**定义该类型kobject的默认属性集

属性定义:

struct attribute {
   
   
    const char *name;   // 在sysfs中显示的名称
    umode_t mode;       // 文件权限 (如 S_IRUGO 表示只读)
};

用法

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野火少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值