RK3568驱动指南|第九篇 设备模型

发布时间:2024年01月02日

瑞芯微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主板


第88章 为什么要引入设备模型

?88.1 设备模型简介

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

1. 总线(Bus):总线是设备模型中的基础组件,用于连接和传输数据的通信通道。总线可以是物理总线(如PCI、USB)或虚拟总线(如虚拟设备总线)。总线提供了设备之间进行通信和数据传输的基本机制。

2. 设备(Device):设备是指计算机系统中的硬件设备,例如网卡、显示器、键盘等。每个设备都有一个唯一的标识符,用于在系统中进行识别和管理。设备模型通过设备描述符来描述设备的属性和特性。

3. 驱动(Driver):驱动是设备模型中的软件组件,用于控制和管理设备的操作。每个设备都需要相应的驱动程序来与操作系统进行交互和通信。驱动程序负责向设备发送命令、接收设备事件、进行设备配置等操作。

4. 类(Class):类是设备模型中的逻辑组织单元,用于对具有相似功能和特性的设备进行分类和管理。类定义了一组共享相同属性和行为的设备的集合。通过设备类,可以对设备进行分组、识别和访问。

设备模型的设计目的是为了提供一种统一的方式来管理和操作系统中的各种硬件设备。通过将设备、驱动和总线等概念进行抽象和标准化,设备模型可以提供一致的接口和数据结构,简化驱动开发和设备管理,并实现设备的兼容性和可移植性。

88.2 相关结构体

在Linux设备模型中,虚构了一条名为“platform”的总线,用来连接一些直接与CPU相连的设备控制器。这种设备控制器通常不符合常见的总线标准,比如PCI总线和USB总线,所以Linux使用platform总线来管理这些设备。Platform 总线允许设备控制器与设备驱动程序进行通信和交互。设备控制器在设备树中定义,并通过设备树与对应的设备驱动程序匹配。在设备模型中,Platform 总线提供了一种统一的接口和机制来注册和管理这些设备控制器。设备驱动程序可以通过注册到 Platform 总线的方式,与相应的设备控制器进行绑定和通信。设备驱动程序可以访问设备控制器的寄存器、配置设备、处理中断等操作,如下图所示:

图 88-2

当作为嵌入式/驱动开发人员时,了解设备,驱动程序,总线和类这几个结构体的概念和关系非常重要。尽管在芯片原厂提供的BSP中已经实现了设备模型,但是了解这些概念可以帮助您更好地理解设备的工作原理,驱动程序的编写和设备的管理。

88.2.1 struct bus_type

?bus_type结构体是Linux内核中用于描述总线的数据结构,定义在include/linux/device.h头文件中。以下是对bus_type结构体的一般定义。

struct bus_type {
	const char		*name;
	const char		*dev_name;
	struct device		*dev_root;
	const struct attribute_group **bus_groups;
	const struct attribute_group **dev_groups;
	const struct attribute_group **drv_groups;

	int (*match)(struct device *dev, struct device_driver *drv);
	int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
	int (*probe)(struct device *dev);
	void (*sync_state)(struct device *dev);
	int (*remove)(struct device *dev);
	void (*shutdown)(struct device *dev);

	int (*online)(struct device *dev);
	int (*offline)(struct device *dev);

	int (*suspend)(struct device *dev, pm_message_t state);
	int (*resume)(struct device *dev);

	int (*num_vf)(struct device *dev);

	int (*dma_configure)(struct device *dev);

	const struct dev_pm_ops *pm;

	const struct iommu_ops *iommu_ops;

	struct subsys_private *p;
	struct lock_class_key lock_key;

	bool need_parent_lock;

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

以下是结构体包含的成员和其作用的简要说明

  1. name:总线类型的名称
  2. dev_name:总线设备名称
  3. dev_root: 总线设备的根设备
  4. bus_groups: 总线类型的属性组
  5. dev_groups: 设备的属性组
  6. drv_groups: 驱动程序的属性组

以下是一些回调函数成员

  1. match: 设备和驱动程序之间的匹配函数
  2. uevent:设备的事件处理函数
  3. probe: 设备的探测函数
  4. sync_state: 设备状态同步函数
  5. remove: 设备的移除函数
  6. online:设备上线函数
  7. offline:设备离线函数
  8. suspend: 设备的挂起函数
  9. resume: 设备的恢复函数
  10. num_vf: 设备的虚拟功能数目函数
  11. dma_configure:设备的DMA配置函数

以下是一些其他成员:

  1. pm:设备的电源管理操作。
  2. iommu_ops:设备的IOMMU操作。
  3. p:子系统私有数据。
  4. lock_key:用于锁机制的锁类别键。
  5. need_parent_lock:是否需要父级锁。

88.2.2 struct device

device 结构体是 Linux 内核中用于描述设备的数据结构,定义在 include/linux/device.h 头文件中。以下是 device 结构体的一般定义:

struct device {
	//设备的父设备
	struct device		*parent;
	//私有指针
	struct device_private	*p;
	//对应的kobj
	struct kobject kobj;
	//设备初始化的名字
	const char		*init_name; 
	//设备类型
	const struct device_type *type;

	//设备所属的总线
	struct bus_type	*bus;		
	struct device_driver *driver;	
	...........

	//设备所属的类
	struct class		*class;
	//设备的属性组
	const struct attribute_group **groups;	/* optional groups */
	...........
};

88.2.3 struct device_driver

struct device_driver 是 Linux 内核中描述设备驱动程序的数据结构,定义在 include/linux/device.h 头文件中。以下是 struct device_driver 的一般定义:

struct device_driver {
	const char		*name;
	struct bus_type		*bus;

	struct module		*owner;
	const char		*mod_name;	/* used for built-in modules */

	bool suppress_bind_attrs;	/* disables bind/unbind via sysfs */
	enum probe_type probe_type;

	const struct of_device_id	*of_match_table;
	const struct acpi_device_id	*acpi_match_table;

	int (*probe) (struct device *dev);
	void (*sync_state)(struct device *dev);
	int (*remove) (struct device *dev);
	void (*shutdown) (struct device *dev);
	int (*suspend) (struct device *dev, pm_message_t state);
	int (*resume) (struct device *dev);
	const struct attribute_group **groups;

	const struct dev_pm_ops *pm;
	void (*coredump) (struct device *dev);

	struct driver_private *p;

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

以下是该结构体包含的成员和其作用的简要说明。

  1. name:设备驱动程序的名称
  2. bus: 设备驱动程序所属的总线类型
  3. owner:拥有该驱动程序的模块。
  4. mod_name:用于内置模块的名称。
  5. suppress_bind_attrs:禁用通过 sysfs 进行绑定/解绑的属性。
  6. probe_type:探测类型,用于指定探测的方式。
  7. of_match_table:Open Firmware(OF)设备匹配表。
  8. acpi_match_table:ACPI 设备匹配表。
  9. groups:驱动程序的属性组。
  10. pm:电源管理操作。
  11. p:驱动程序的私有数据。

??以下是一些回调函数成员

  1. probe:设备的探测函数,用于初始化和配置设备,注意:device 和 device_driver 必须挂在同一个 bus 下。这样才可以触发 probe
  2. sync_state: 设备状态同步函数
  3. remove:设备的移除函数
  4. shutdown: 设备的关机函数
  5. suspend: 设备的挂起函数
  6. resume: 设备的恢复函数
  7. coredump: 设备的核心转储函数

88.2.4 struct class

struct class 是 Linux 内核中描述设备类的数据结构,定义在 include/linux/device.h 头文件中。以下是 struct class 的一般定义:

struct class {
	const char		*name;
	struct module		*owner;

	const struct attribute_group	**class_groups;
	const struct attribute_group	**dev_groups;
	struct kobject			*dev_kobj;

	int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
	char *(*devnode)(struct device *dev, umode_t *mode);

	void (*class_release)(struct class *class);
	void (*dev_release)(struct device *dev);

	int (*shutdown_pre)(struct device *dev);

	const struct kobj_ns_type_operations *ns_type;
	const void *(*namespace)(struct device *dev);

	void (*get_ownership)(struct device *dev, kuid_t *uid, kgid_t *gid);

	const struct dev_pm_ops *pm;

	struct subsys_private *p;

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

以下是该结构体包含的成员和其作用的简要说明

  1. name : 设备类的名称
  2. owner:拥有该类的模块

以下是一些属性组成员

  • class_groups: 类属性组,用于描述设备类的属性,在类注册到内核时,会自动在/sys/class/xxx_class下创建对应的属性文件
  • dev_groups: 设备属性组,用于描述设备的属性,在类注册到内核时,会自动在该类下的设备目录创建对应的属性文件
  • dev_kobj: 设备的内核对象

以下是一些回调函数成员

  • dev_uevent :设备的事件处理函数
  • devnode : 生成设备节点的函数

以下是一些其他成员

  • class_release: 类资源的释放函数
  • dev_release: 设备资源的释放函数
  • shutdown_pre: 设备关机前的回调函数
  • ns_type: 命名空间类型操作
  • namespace: 命名空间函数
  • get_ownership: 获取设备所有权的函数
  • pm: 电源管理操作
  • p: 子系统私有数据

文章来源:https://blog.csdn.net/BeiJingXunWei/article/details/135341488
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。