Linux Regmap子系统分析1(基于Linux6.6)---系统概述
一、Linux Regmap 子系统概述
Regmap 是 Linux 内核中的一个子系统,旨在提供一个统一的、抽象的方式来处理硬件寄存器的访问和管理。它的核心功能是将硬件设备的寄存器操作(如读写寄存器的值)抽象化,从而简化对这些寄存器的操作,并提供对多种硬件平台的支持。通过使用 Regmap,内核驱动程序可以更容易地管理设备的寄存器,而无需关心底层的硬件细节。
1.1、背景与问题
在嵌入式系统中,许多硬件设备(如外设、控制器、传感器等)通过寄存器进行控制。这些寄存器通常通过 I/O 地址进行访问,驱动程序需要使用相应的机制来读取或写入这些寄存器。处理这些寄存器操作时会遇到一些常见的问题:
- 寄存器访问的多样性:不同的硬件设备可能通过不同的总线(如 I2C、SPI、MMIO)访问寄存器,寄存器的访问方式和时序也各不相同。
- 并发访问与同步问题:当多个内核模块或线程同时访问硬件寄存器时,可能会出现竞争条件或不一致的读取。
- 硬件寄存器的缓存管理:硬件寄存器的值可能会被缓存,直接操作寄存器可能导致缓存与硬件不一致的问题。
因此,Linux 内核提供了 Regmap 作为解决这些问题的方案,通过一个统一的 API 和机制来处理硬件寄存器的读写操作。
1.2、Regmap 的基本概念
Regmap(Register Map) 是一种寄存器操作的抽象,允许内核驱动程序以一种一致的方式与硬件设备的寄存器交互。它封装了寄存器访问的底层细节,提供了统一的接口,使得设备驱动程序可以高效、安全地进行寄存器操作。
Regmap 的关键组成部分
-
Regmap 对象:
- 一个
regmap
对象代表了一个硬件设备的寄存器映射(通常通过 I2C、SPI、MMIO 等方式访问)。 - 它封装了硬件寄存器的访问操作,并与硬件接口(如 I2C、SPI 等)进行交互。
struct regmap
是这个对象的核心数据结构,包含了硬件寄存器的各种信息。
- 一个
-
Regmap 操作函数:
- 这些函数定义了寄存器的具体访问方式,如
read
、write
、update
等。 regmap
提供了许多高级函数,允许驱动程序通过简单的接口来进行复杂的寄存器操作。
- 这些函数定义了寄存器的具体访问方式,如
-
寄存器访问方法:
- 支持多种硬件接口,如 I2C、SPI、MMIO 和并行接口等。通过不同的访问方法,
regmap
可以提供与硬件的交互方式。 regmap
提供了regmap_read
和regmap_write
等函数来读写硬件寄存器。
- 支持多种硬件接口,如 I2C、SPI、MMIO 和并行接口等。通过不同的访问方法,
-
寄存器缓存:
- Regmap 提供对硬件寄存器值的缓存机制。寄存器的读写操作可以通过缓存来进行优化,以减少对硬件的直接访问。
- 对寄存器的写入可能会先更新缓存,当条件允许时再将数据写回硬件。
-
操作类型:
- 单字节/多字节访问:支持单字节或多字节的寄存器访问。
- 位域更新:支持对寄存器中的特定位域进行更新,而不影响其他位。
- 批量读写:支持批量读写操作,可以在单次操作中处理多个寄存器。
1.3、Regmap 的核心功能与优势
-
简化寄存器操作:
- Regmap 提供了一套统一的 API,使得设备驱动程序可以使用相同的接口与不同硬件的寄存器进行交互。驱动程序不需要关心具体的寄存器访问方式或底层硬件接口。
-
优化性能:
- Regmap 提供了寄存器的缓存机制,减少了对硬件的直接访问。可以通过缓存和延迟写入的方式,优化寄存器的读写性能。
- 还可以通过批量操作减少总线上的访问次数,进一步提高性能。
-
并发访问控制:
- Regmap 提供了对并发访问的控制。多个线程或驱动模块可以安全地共享同一个寄存器映射,而无需担心数据竞争问题。
-
寄存器保护与校验:
- 通过 Regmap,驱动可以对寄存器的读写进行保护和校验,确保操作的有效性和安全性。
- 例如,写入操作可以先在内存中更新缓存,再与硬件同步,减少硬件直接读写的次数。
-
设备树支持:
- Regmap 通常与设备树一起使用。在设备树中,硬件寄存器的映射和配置可以被描述,驱动程序可以从设备树中读取这些信息来初始化
regmap
对象。
- Regmap 通常与设备树一起使用。在设备树中,硬件寄存器的映射和配置可以被描述,驱动程序可以从设备树中读取这些信息来初始化
1.4、Regmap 的常见应用场景
-
I2C 和 SPI 设备:
- 对于通过 I2C 或 SPI 总线连接的设备,Regmap 可以提供寄存器访问的统一抽象。I2C 和 SPI 驱动可以通过 Regmap API 来读写设备寄存器,而不需要直接处理总线协议的细节。
-
内存映射寄存器(MMIO)设备:
- 对于通过内存映射(MMIO)方式访问的设备,Regmap 提供了直接与内存地址交互的机制,简化了驱动的开发。
-
多功能硬件控制器:
- 对于具有多个寄存器组的硬件控制器,Regmap 可以帮助驱动程序按功能或设备模块组织寄存器,减少复杂性。
-
寄存器缓存管理:
- Regmap 的缓存机制非常适用于那些不需要每次都直接访问硬件寄存器的情况。通过缓存,寄存器的读写可以批量操作,提高系统的响应速度和性能。
二、regmap子系统框架说明
如下为regmap子系统的整体框架,通过如下几个部分进行说明:
regmap子系统主要包含regmap、regmap_bus两大部分,其中regmap表示一个慢速i/o设备的reg操作的映射、regmap_bus则表示一类慢速i/o设备的reg操作(如i2c设备可定义对应的regmap_bus,提供寄存器的读写操作接口、spi设备也定义对应的remap_bus,提供寄存器的读写接口)。
- 具体的regmap_bus,可提供对应的regmap创建接口,可由内核其他设备驱动模块调用(如我们上一专栏中使用regmap_init_i2c接口,创建i2c_client对应的regmap);
- regmap子系统对外提供了regmap的寄存器读写接口,包含regmap_write、regmap_read、regmap_bulk_write、regmap_bulk_read等接口;
- 对于regmap而言,若该regmap是依附于具体regmap_bus,则借助regmap_bus的读写接口,实现对i/o设备的寄存器访问操作。
- regmap内部提供了一些操作接口,实现对regmap_bus接口的封装调用(如包含对缓存的访问操作、在对寄存器进行写操作前,先对寄存器、值进行format操作,然后再调用remap_bus的读写接口进行寄存器的读写接口);
- 借助于regmap_bus的读写接口,最终再调用具体外设的访问接口(如针对i2c设备,则调用i2c_transfer、i2c_master_send等接口实现对具体i2c设备的进行读写操作)。
针对regmap子系统而言,regmap_bus的实现由内核层完成、属于regmap子系统的一部分(目前实现了regmap_i2c、regmap_spi、regmap_mmio等regmap_bus),内核层通过实现remap_i2c、regmap_spi,只需要使用i2c、spi的regmap创建接口,然后就可使用regmap提供的操作接口,实现对这两类设备的访问操作。
通过regmap子系统的抽象,具体的设备驱动模块只需要调用regmap_write、regmap_read等通用接 口,即可实现对i2c/spi设备的访问。
2.1、Regmap 主要组成部分
Regmap 由以下几个关键部分组成:
-
regmap
对象:struct regmap
是 Regmap 子系统的核心数据结构,它代表了一个硬件设备的寄存器映射。regmap
维护了关于寄存器的配置、读写方法、缓存策略等信息。 -
regmap_config
结构体:regmap_config
定义了如何访问硬件寄存器的信息,包括:- 寄存器位宽(
reg_bits
和val_bits
):指定寄存器地址和数据的位宽。 - 最大寄存器地址(
max_register
):定义硬件设备的寄存器范围。 - 读写操作函数(
reg_read
和reg_write
):用于定义具体的硬件访问方式(I2C、SPI、MMIO 等)。
- 寄存器位宽(
-
寄存器操作函数:
- 读写函数:Regmap 提供了
regmap_read
和regmap_write
等 API,用于执行寄存器的读写操作。 - 更新函数:
regmap_update_bits
用于仅更新寄存器的某些位,避免不必要的修改其他位。 - 批量读写:Regmap 支持批量读取和写入多个寄存器,提高性能。
- 读写函数:Regmap 提供了
-
缓存机制: Regmap 提供寄存器缓存机制,使得寄存器的值可以缓存在内存中,减少对硬件的直接访问,提高性能和响应速度。
-
并发控制: Regmap 通过内核的锁机制确保多个进程或线程安全地访问同一寄存器映射,防止并发读写导致的数据不一致问题。
2.2、Regmap 的设计思想
-
统一的访问接口:通过
regmap
,不同硬件的寄存器访问变得统一。无论是通过 I2C、SPI,还是内存映射(MMIO)方式,驱动程序都能通过相同的 API 进行寄存器的读写操作。 -
抽象硬件接口:
regmap
抽象了硬件接口的具体实现细节,使得驱动程序不需要处理底层的硬件协议(如 I2C 的起始位、停止位等),只需要专注于寄存器的读写。 -
性能优化:Regmap 提供了对寄存器的缓存支持,在内存中缓存寄存器值,避免频繁的硬件访问,从而提高性能。此外,它还支持批量操作和延迟写入等优化策略。
-
灵活性和可扩展性:Regmap 具有高度的灵活性,能够支持多种硬件访问方式和寄存器映射结构,可以适应不同的硬件设备和架构。