linux kernel struct regmap_config结构详解

在 Linux 内核中,struct regmap_config 是 ​Regmap 子系统的核心配置结构体,用于定义如何与底层硬件寄存器进行交互。Regmap(Register Map)子系统通过抽象不同总线(如 I2C、SPI、MMIO 等)的寄存器访问细节,为驱动开发者提供统一的寄存器读写接口,显著简化了设备驱动的开发。

以下是对 struct regmap_config 结构体的详细解析,涵盖其核心成员、功能及典型配置场景:

一、结构体定义概览(以 Linux 5.10+ 内核为例)

struct regmap_config {/* 基础标识与总线类型 */const char *name;               // Regmap 实例名称(调试用)enum regmap_bus_type bus_type;  // 总线类型(如 REGMAP_BUS_I2C、REGMAP_BUS_SPI、REGMAP_BUS_MMIO 等)/* 寄存器与值的位宽配置 */int reg_bits;                   // 寄存器地址的位宽(如 8/16/32 位)int val_bits;                   // 寄存器值的位宽(如 8/16/32 位)int pad_bits;                   // 地址/值与实际总线传输间的填充位(通常为 0)/* 字节序与对齐方式 */enum regmap_endian reg_format_endian;  // 寄存器地址的字节序(大端/小端/不转换)enum regmap_endian val_format_endian;  // 寄存器值的字节序(同上)bool reg_stride;                // 地址自动递增步长(默认 1,若硬件地址不连续需手动设置)/* 访问约束与超时 */unsigned int max_register;      // 设备支持的最大寄存器地址(0 表示无限制)unsigned int fast_io;           // 是否启用快速 IO(1 启用,依赖硬件特性)unsigned long read_flag_mask;   // 读操作的标志掩码(如 I2C 的 RD 位)unsigned long write_flag_mask;  // 写操作的标志掩码(如 I2C 的 WR 位)/* 缓存策略 */enum regmap_cache_type cache_type;  // 缓存类型(无缓存/读缓存/写缓存/读写缓存)unsigned int cache_size;            // 缓存大小(字节数,0 表示自动计算)bool use_single_read;               // 强制单次读(即使支持批量读)bool use_single_write;              // 强制单次写(即使支持批量写)/* 中断与事件处理 */int irq;                          // 设备关联的中断号(若需要)unsigned long irq_flags;          // 中断触发标志(如 IRQF_SHARED)/* 自定义回调函数 */int (*reg_read)(struct regmap *map, unsigned int reg, unsigned int *val);  // 自定义读回调int (*reg_write)(struct regmap *map, unsigned int reg, unsigned int val); // 自定义写回调void (*lock)(struct regmap *map);                                         // 自定义锁函数void (*unlock)(struct regmap *map);                                       // 自定义解锁函数/* 调试与日志 */bool verbose;                     // 是否启用详细日志(调试用)struct dentry *debugfs;           // DebugFS 挂载点(用于调试)
};

二、核心成员详解

1. 基础标识与总线类型
  • ​**name**​:Regmap 实例的名称(如 "my_spi_device_regmap"),主要用于调试日志和 DebugFS 展示。
  • ​**bus_type**​:指定底层总线类型,决定 Regmap 如何与总线驱动交互。常见值包括:
    • REGMAP_BUS_I2C:I2C 总线(需配合 struct i2c_client 使用)。
    • REGMAP_BUS_SPI:SPI 总线(需配合 struct spi_device 使用)。
    • REGMAP_BUS_MMIO:内存映射 IO(MMIO,直接访问物理内存地址)。
    • REGMAP_BUS_HOST:主机侧总线(如用于连接外部芯片的专用总线)。
2. 寄存器与值的位宽配置
  • ​**reg_bits**​:寄存器地址的二进制位数(如 8 位地址对应 reg_bits=8)。
    示例:若设备寄存器地址范围是 0x00 ~ 0xFF,则 reg_bits=8
  • ​**val_bits**​:寄存器值的二进制位数(如 16 位值对应 val_bits=16)。
    示例:若寄存器是 8 位宽(每次读写 1 字节),则 val_bits=8;若是 16 位宽(大端存储),则 val_bits=16
  • ​**pad_bits**​:地址或值与实际总线传输字节的填充位数(通常为 0)。
    示例:某些 SPI 设备需要在地址后填充 4 位校验位,则 pad_bits=4
3. 字节序与对齐方式
  • ​**reg_format_endian**​:寄存器地址的字节序(仅当 reg_bits > 8 时有效)。
    可选值:REGMAP_ENDIAN_BIG(大端)、REGMAP_ENDIAN_LITTLE(小端)、REGMAP_ENDIAN_NATIVE(与 CPU 一致)。
  • ​**val_format_endian**​:寄存器值的字节序(仅当 val_bits > 8 时有效)。
    示例:SPI 设备寄存器值为 16 位大端格式,则 val_format_endian=REGMAP_ENDIAN_BIG
  • ​**reg_stride**​:地址自动递增的步长(默认 1)。
    场景:若硬件寄存器地址不连续(如跳过保留地址),可手动设置步长(如 reg_stride=2 表示每次地址+2)。
4. 访问约束与超时
  • ​**max_register**​:设备支持的最大寄存器地址(0 表示无限制)。
    作用:Regmap 会检查读写操作的地址是否超过此值,避免越界访问。
  • ​**fast_io**​:启用快速 IO 优化(默认 0)。
    条件:仅当底层总线支持原子读写(如 MMIO 或高速 SPI)时设置为 1,可减少函数调用开销。
  • ​**read_flag_mask/write_flag_mask**​:总线操作的标志位掩码。
    示例:I2C 设备写操作需要在地址后置位 0(写标志),则 write_flag_mask=0x00;读操作置位 1(读标志),则 read_flag_mask=0x01(具体取决于总线协议)。
5. 缓存策略

Regmap 支持缓存寄存器值以减少总线访问次数(尤其适用于频繁读写的只读/半静态寄存器)。

  • ​**cache_type**​:缓存类型,可选值:
    • REGMAP_CACHE_NONE:无缓存(每次读写直接访问硬件)。
    • REGMAP_CACHE_R:只读缓存(仅缓存读操作结果,写操作后失效)。
    • REGMAP_CACHE_W:写缓存(写操作先更新缓存,读操作从缓存读取,需配合 regmap_write 自动同步)。
    • REGMAP_CACHE_RW:读写缓存(读写均通过缓存,需手动调用 regmap_sync() 同步到硬件)。
  • ​**cache_size**​:缓存大小(字节数)。若为 0,Regmap 会根据 max_registerval_bits 自动计算。
  • ​**use_single_read/use_single_write**​:强制单次读写(即使总线支持批量操作)。
    场景:某些老旧设备不支持批量传输,需强制每次读写一个寄存器。
6. 中断与事件处理
  • ​**irq**​:设备关联的中断号(若需要 Regmap 处理中断)。
    配合:需结合 regmap_irq_chip 定义中断映射,实现中断的统一管理。
  • ​**irq_flags**​:中断触发标志(如 IRQF_SHARED 共享中断、IRQF_ONESHOT 单次触发)。
7. 自定义回调函数

Regmap 允许通过自定义回调覆盖默认的读写逻辑(如硬件有特殊时序要求)。

  • ​**reg_read/reg_write**​:自定义读写函数,原型为:
    int (*reg_read)(struct regmap *map, unsigned int reg, unsigned int *val);
    int (*reg_write)(struct regmap *map, unsigned int reg, unsigned int val);
    示例:实现非标准的 SPI 事务(如先发命令再读数据)。
  • ​**lock/unlock**​:自定义锁函数(默认使用自旋锁或互斥锁)。
    场景:多线程/中断上下文共享 Regmap 时,需自定义锁机制保证线程安全。
8. 调试与日志
  • ​**verbose**​:启用详细日志(默认 0)。设置为 1 时,Regmap 会在读写操作时打印调试信息(如地址、值)。
  • ​**debugfs**​:DebugFS 挂载点路径(如 "/sys/kernel/debug/regmap/my_regmap"),可通过 regmap-dump 工具查看寄存器状态。

三、典型配置示例

示例 1:SPI 设备(16 位地址,8 位值,大端)

假设一个 SPI 设备的寄存器地址为 16 位(范围 0x0000 ~ 0xFFFF),每个寄存器值是 8 位,且地址采用大端格式:

static const struct regmap_config my_spi_regmap_config = {.name = "my_spi_device",.bus_type = REGMAP_BUS_SPI,.reg_bits = 16,       // 16 位寄存器地址.val_bits = 8,        // 8 位寄存器值.reg_format_endian = REGMAP_ENDIAN_BIG,  // 地址大端格式.max_register = 0xFFFF, // 最大地址.fast_io = 1,         // 启用快速 IO.cache_type = REGMAP_CACHE_RW, // 读写缓存
};
示例 2:I2C 设备(8 位地址,16 位值,小端)

假设一个 I2C 设备的寄存器地址为 8 位(范围 0x00 ~ 0x7F),每个寄存器值是 16 位小端格式:

static const struct regmap_config my_i2c_regmap_config = {.name = "my_i2c_device",.bus_type = REGMAP_BUS_I2C,.reg_bits = 8,        // 8 位寄存器地址.val_bits = 16,       // 16 位寄存器值.val_format_endian = REGMAP_ENDIAN_LITTLE, // 值小端格式.max_register = 0x7F, // 最大地址.read_flag_mask = 0x01, // I2C 读操作标志位(假设设备要求地址后第 0 位为 1).cache_type = REGMAP_CACHE_NONE, // 无缓存(实时性要求高)
};

四、关键注意事项

  1. 总线适配器依赖​:bus_type 需与实际使用的总线驱动匹配(如 SPI 需先注册 spi_device,I2C 需先注册 i2c_client)。
  2. 位宽对齐​:reg_bitsval_bits 需与硬件寄存器的实际位宽严格一致,否则会导致读写错误。
  3. 缓存一致性​:启用缓存(cache_type != REGMAP_CACHE_NONE)时,需在寄存器值变更后调用 regmap_write()regmap_update_bits() 触发缓存同步;若硬件状态可能被外部修改(如其他主设备),需手动调用 regmap_sync() 刷新缓存。
  4. 字节序处理​:reg_format_endianval_format_endian 需根据硬件的寄存器定义设置(如网络设备常用大端,传感器常用小端)。
  5. 中断处理​:若设备需要中断支持,需额外定义 struct regmap_irq_chip 并关联到 Regmap 实例(通过 regmap_add_irq_chip())。

五、总结

struct regmap_config 是 Linux Regmap 子系统的核心配置结构体,通过灵活设置其成员,开发者可以适配各种总线和寄存器特性的硬件设备。关键是根据硬件的实际需求(总线类型、位宽、字节序、缓存需求等)配置相应字段,并合理利用 Regmap 提供的统一接口简化寄存器操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88440.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python3教程】Python3高级篇之CGI编程

博主介绍:✌全网粉丝23W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

docker安装Consul笔记

安装过程 详细步骤如下: 首先拉取Consul的Docker镜像: docker pull hashicorp/consul:1.18.1创建Consul的配置文件和数据目录: mkdir -p /srv/docker/consul/data mkdir -p /srv/docker/consul/config在config目录下创建一个config.json配置文…

.net数据脱敏

.NET数据脱敏技术:保障数据安全的有效手段 在当今数字化时代,数据安全至关重要。尤其是涉及到用户的敏感信息,如密码、手机号码等,必须采取有效的措施进行保护。数据脱敏就是这样一种技术,它能够在不影响数据可用性的…

【openp2p】 学习2:源码阅读P2PNetwork和P2PTunnel

【openp2p】 学习1:P2PApp和优秀的go跨平台项目已经做了初步分析。阅读原版工程,感觉工程是一个暴露内网服务端口,让外部可以用的一个实现是一个完整的、跨平台的可商业化的应用。感谢作者需要学习作者的设计思路工程构建 F:\GolandProjects\openp2p\core\p2pnetwork.go通常…

网安学习NO.14

防火墙基础实验 传统防火墙配置实验拓扑图PC: ip 192.168.10.1 255.255.255.0 192.168.10.254 ip dns 114.114.114.114二层交换机 vl 10 ex int e0/0 sw mo ac sw ac vl 10 ex inr e0/1 sw tr en do sw mo tr三层交换机 vl 10 ex int g0/0 sw tr en do sw mo tr ex …

ESP32语音唤醒

两种唤醒方式AfeWakeWord与EspWakeWord对比 底层技术 AfeWakeWord:基于ESP-IDF的AFE框架(esp_afe_sr_iface_t),高性能模式(AFE_MODE_HIGH_PERF)EspWakeWord:基于WakeNet接口(esp_wn_…

借助 Wisdom SSH AI 助手,轻松安装 CentOS 8 LNMP 环境

打开Wisdom SSH软件,在AI对话区输入“在CentOS 8服务器安装LNMP环境”,AI助手会按以下步骤分析并执行安装: 安装Nginx 分析:CentOS 8默认软件源可能没有Nginx,所以要先启用Nginx官方软件源,然后才能安装Ngi…

WD0407 40V 7A 超级肖特基二极管,应用于开关汽车工业控制

WD0407 40V 7A 超级肖特基二极管说明​ 产品概述​ WD0407 是一款性能卓越的超级肖特基二极管,专为满足现代电子设备对高效、可靠电源管理的需求而设计。它采用先进的半导体制造工艺,在诸多关键性能指标上表现出色,能够为各类电路提供稳定、高…

卢比危机下的金融破局:科伦坡交易所技术升级作战图

🌏 今日南亚风暴眼 印度双重上市机制加速落地:印度国家证券国际交易所(NSE IX)与科伦坡证券交易所(CSE)达成技术对接协议,斯企可通过印度GIFT City吸引美元资本,交易时段覆盖全球22小…

upload-labs靶场通关详解:第20关 /.绕过

一、分析源代码// 初始化上传状态标记,默认为false,即文件未上传 $is_upload false; // 初始化消息变量,用于存储错误信息 $msg null;// 检查是否通过POST方式提交了表单(点击上传按钮) if (isset($_POST[submit])) …

企业用云状态评估

云部署形态及其策略规划成熟度 单云部署: 主要业务负载运行在单一公有云或私有云上 多云/混合云部署 —有清晰战略规划与实施: 业务负载运行在多个云(公有云或混合云)上,并且企业拥有清晰的多云/混合云战略规划&#x…

STM32G473串口通信-USART/UART配置和清除串口寄存器状态的注意事项

USART和UART配置的区别 如果USART使用的是异步通信,那么UART与USART配置基本相同。 USART配置如下:UART配置如下:如果USART使用的是同步通信,那么UART配置就有差异。首先通信双方都是使用USART的同步通信,一个主机,一个…

Debezium:一款基于CDC的开源数据同步工具

Debezium 是由 Red Hat 开源的一种基于变更数据捕获(CDC) 的分布式平台,专为实时捕获和传播数据库的变更事件而设计。Debezium 常见的使用场景包括: 实时数据集成:将数据库变更同步到数据仓库或数据湖,支撑…

从面向对象编程语言PHP转到Go时的一些疑惑?

前言 1、php中面向对象编程时 与 Go中的区别? 2、php中最常使用laravel框架,不用过多关注依赖注入和反射,在go中又该如何使用呢?是 舍弃? 本文是一个系统化梳理,帮助从 语言哲学 → 依赖注入在 Go 的现状 →…

Vue3中使用konva插件动态制作海报以及可在画布上随意移动位置

1、下载konva插件 官网地址 npm install vue-konva konva --save2、在主文件中引入,如main.js import VueKonva from vue-konva; app.use(VueKonva);3、组件内使用,我现在的布局是左侧是画布,右侧是相关设置(颜色、标题等&#…

政安晨【开源人工智能硬件】【ESP乐鑫篇】 —— 在macOS上部署工具开发环境(小资的非开发者用苹果系统也可以玩乐鑫)

政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 前言 开源人工智能硬件会给你带来无限可能,玩开源硬件,环境和工具少…

Vue3 学习教程,从入门到精通,vue3学习中的JavaScript ES6 特性详解与案例(5)

vue3学习中的JavaScript ES6 特性详解与案例 ES6(ECMAScript 2015)是 JavaScript 的一个重要版本,引入了许多新特性,极大地提升了语言的表达能力和开发效率。本文将详细介绍 ES6 的主要特性,包括 let 和 const 命令、变…

深度学习模型1:理解LSTM和BiLSTM

深度学习模型1:理解LSTM和BiLSTM 因为最近科研复现论文中需要了解单向LSTM和双向LSTM,所以就学习了一下LSTM的基本原理,下面孬孬带着大家一起学习一下,感谢大家的一键三连 一、RNN 因为谈到LSTM,就必不可少的会考虑RNN…

[论文阅读] 软件工程 | 一篇关于开源许可证管理的深度综述

关于开源许可证管理的深度综述 论文标题:Open Source, Hidden Costs: A Systematic Literature Review on OSS License ManagementarXiv:2507.05270 Open Source, Hidden Costs: A Systematic Literature Review on OSS License Management Boyuan Li, Chengwei Liu…

Qt悬浮动态

粉丝悬浮动态,及抽奖程序#include "masklabel.h"MaskLabel::MaskLabel(int pos_x,QString fans_name,QWidget*parent):QLabel(parent) {this->setAlignment(Qt::AlignHCenter);//设置字体居中this->setStyleSheet("color:white;font-size:20px…