RK3568驱动指南|第九篇 设备树模型-第85章设备模型基本框架-kobject和kset

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。


【公众号】迅为电子

【粉丝群】824412014(加群获取驱动文档+例程)

【视频观看】嵌入式学习之Linux驱动(第九期_设备模型_全新升级)_基于RK3568

【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板


第九篇 设备模型

第85章设备模型基本框架-kobject和kset

85.1 什么是设备模型

字符设备驱动通常适用于相对简单的设备,对于一些更复杂的功能,比如说电源管理和热插拔事件管理,使用字符设备框架可能不够灵活和高效。为了应对更复杂的设备和功能,Linux内核提供了设备模型。设备模型允许开发人员以更高级的方式来描述硬件设备和它们之间的关系,并提供一组通用API和机制来处理设备的注册,热插拔事件,电源管理等。

   通过使用设备模型,驱动开发人员可以将更多的底层功能交给内核来处理,而不必重复实现这些基础功能。这使得驱动的编写更加高级和模块化,减少了重复工作和出错的可能性。对于一些常见的硬件设备,如USB、i2c和平台设备,内核已经提供了相应的设备模型和相关驱动,开发人员可以基于这些模型来编写驱动,从而更快地实现特定设备的功能,并且可以借助内核的电源管理和热插拔事件管理功能。

总之,使用设备模型可以帮助简化驱动开发过程,并提供更高级的功能和灵活性,使得驱动开发人员能够更好地适应复杂的硬件设备需求。

85.2 设备模型的好处

设备模型在内核驱动中扮演着重要的角色,它提供了一种统一的方式来描述硬件设备和它们之间的关系。以下是设备模型在内核驱动中的几个重要方面。

1 代码复用:设备模型允许多个设备复用同一个驱动。通过在设备树或总线上定义不同的设备节点,这些设备可以使用相同的驱动进行初始化和管理。这样可以减少代码的冗余,提高驱动的复用性和维护性。

2 资源的动态申请和释放:设备模型提供了一种机制来动态申请和释放设备所需的资源,如内存,中断等。驱动可以使用这些机制来管理设备所需的资源,确保在设备初始化和关闭时进行正确的资源分配和释放。

3 简化驱动编写: 设备模型提供了一组通用API和机制,使得驱动编写更加简化和模块化。开发人员可以使用这些API来注册设备,处理设备事件,进行设备的读写操作等,而无需重复实现这些通用功能。

4 热插拔机制:设备模型支持热插拔机制,能够在运行时动态添加或移除设备。当设备插入或拔出时,内核会生成相应的热插拔事件,驱动可以通过监听这些事件来执行相应的操作,如设备的初始化或释放。

5 驱动的面向对象思想:设备模型的设计借鉴了面向对象编程(OOP)的思想。每个设备都被看作是一个对象,具有自己的属性和方法,并且可以通过设备模型的机制进行继承和扩展。这种设计使得驱动的编写更加模块化和可扩展,可以更好地应对不同类型的设备和功能需求。

总之,设备模型在内核驱动中扮演着关键的角色,通过提供统一的设备描述和管理机制,简化了驱动的编写和维护过程,提高了代码的复用性和可维护性,并支持热插拔和动态资源管理等重要功能。

85.3 kobject和kset基本概念

kobject和kset是Linux内核中用于管理内核对象的基本概念。

kobject(内核对象)是内核中抽象出来的通用对象模型,用于表示内核中的各种实体。kobject是一个结构体,其中包含了一些描述该对象的属性和方法。它提供了一种统一的接口和机制,用于管理和操作内核对象。kobject结构体在内核源码kernel/include/linux/kobject.h文件中,如下所示:

struct kobject {
	const char		*name;
	struct list_head	entry;
	struct kobject		*parent;
	struct kset		*kset;
	struct kobj_type	*ktype;
	struct kernfs_node	*sd; /* sysfs directory entry */
	struct kref		kref;
#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
	struct delayed_work	release;
#endif
	unsigned int state_initialized:1;
	unsigned int state_in_sysfs:1;
	unsigned int state_add_uevent_sent:1;
	unsigned int state_remove_uevent_sent:1;
	unsigned int uevent_suppress:1;

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

这是Linux内核中的struct kobject结构体的定义。它包含了一些字段用于表示和管理内核对象。

下面是一些主要字段的解释:

- const char *name:表示kobject的名称,通常用于在/sys目录下创建对应的目录。

- struct list_head entry:用于将kobject链接到父kobject的子对象列表中,以建立层次关系。

- struct kobject *parent:指向父kobject,表示kobject的层次关系。

- struct kset *kset:指向包含该kobject的kset,用于进一步组织和管理kobject。

- struct kobj_type *ktype:指向定义kobject类型的kobj_type结构体,描述kobject的属性和操作。

- struct kernfs_node *sd:指向sysfs目录中对应的kernfs_node,用于访问和操作sysfs目录项。

- struct kref kref:用于对kobject进行引用计数,确保在不再使用时能够正确释放资源。

- unsigned int 字段:表示一些状态标志和配置选项,例如是否已初始化、是否在sysfs中、是否发送了add/remove uevent等。

 

图 85-1

之前我们在学习平台总线时,查看平台总线要进入/sys/bus目录下,bus目录下的文件都是和总线相关的目录,比如amba总线,CPU总线,platform总线。如下图所示:

RK3568驱动指南|第九篇 设备树模型-第85章设备模型基本框架-kobject和kset_第1张图片

图 85-2

kobject表示系统/sys下的一个目录,而目录又是有多个层次,所以对应kobject的树状关系如下图所示:

RK3568驱动指南|第九篇 设备树模型-第85章设备模型基本框架-kobject和kset_第2张图片

图 85-3

我们来分析一下上图。在kobject结构体中,parent指针用于表示父kobject,从而建立了kobject之间的层次关系,类似于目录结构中的父目录和子目录的关系。一个kobject可以有一个父kobject和多个子kobject,通过parent指针可以将它们连接起来形成一个层次化的结构,类似于目录结构中,一个目录可以有一个父目录和多个子目录,通过目录的路径可以表示目录之间的层次关系。这种层次化的关系可以方便地进行遍历,查找和管理,使得内核对象能够按照层次关系进行组织和管理。这种设计使得kobject的树状结构在内核中具有很高的灵活性和可扩展性。

接下来我们继续学习kset。

kset(内核对象集合)是一种用于组织和管理一组相关kobject的容器。kset是kobject的一种扩展,它提供了一种层次化的组织结构,可以将一组相关的kobject组织在一起。kset在内核里面用struct kset结构体来表示,定义在include/linux/kobject.h头文件中,如下所示:

struct kset {
	struct list_head list;
	spinlock_t list_lock;
	struct kobject kobj;
	const struct kset_uevent_ops *uevent_ops;

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

这是Linux内核中的struct kset结构体的定义。kset是一种用于组织和管理kobject的集合。

下面是一些主要字段的解释:

- struct list_head list:用于将kset链接到全局kset链表中,以便对kset进行遍历和管理。

- spinlock_t list_lock:用于保护对kset链表的并发访问,确保线程安全性。

- struct kobject kobj:作为kset的kobject表示,用于在/sys目录下创建对应的目录,并与kset关联。

- const struct kset_uevent_ops *uevent_ops:指向kset的uevent操作的结构体,用于处理与kset相关的uevent事件。

该结构体还包含了一些与特定配置相关的保留字段。kset通过包含一个kobject作为其成员,将kset本身表示为一个kobject,并使用kobj来管理和操作kset。通过list字段,kset可以链接到全局kset链表中,以便进行全局的遍历和管理。同时,list_lock字段用于保护对kset链表的并发访问。kset还可以定义自己的uevent操作,用于处理与kset相关的uevent事件,例如在添加或删除kobject时发送相应的uevent通知。

这些字段共同构成了kset的基本属性和关系,用于在内核中组织和管理一组相关的kobject。kset提供了一种层次化的组织结构,并与sysfs目录相对应,方便对kobject进行管理和操作。


85.4 kset和kobject的关系

 在Linux内核中,kset和kobject是相关联的两个概念,它们之间存在一种层次化的关系,

如下图所示:

RK3568驱动指南|第九篇 设备树模型-第85章设备模型基本框架-kobject和kset_第3张图片

图 85-4

1. kset是kobject的一种扩展:kset可以被看作是kobject的一种特殊形式,它扩展了kobject并提供了一些额外的功能。kset可以包含多个kobject,形成一个层次化的组织结构。

2. kobject属于一个kset:每个kobject都属于一个kset。kobject结构体中的struct kset *kset字段指向所属的kset。这个关联关系表示了kobject所在的集合或组织。

通过kset和kobject之间的关系,可以实现对内核对象的层次化管理和操作。kset提供了对kobject的集合管理接口,可以通过kset来迭代、查找、添加或删除kobject。同时,kset也提供了特定于集合的功能,例如在集合级别处理uevent事件。

总结起来,kset和kobject之间的关系是:一个kset可以包含多个kobject,而一个kobject只能属于一个kset。kset提供了对kobject的集合管理和操作接口,用于组织和管理具有相似特性或关系的kobject。这种关系使得内核能够以一种统一的方式管理和操作不同类型的内核对象。


RK3568驱动指南|第九篇 设备树模型-第85章设备模型基本框架-kobject和kset_第4张图片

你可能感兴趣的:(RK3568,驱动开发,linux)