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
英文地址,請注明出處:http://en.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…