Regmap 框架:簡化慢速IO介面優化性能【轉】

来源:https://www.cnblogs.com/linhaostudy/archive/2018/05/25/9090572.html
-Advertisement-
Play Games

1. 簡介 Regmap 機制是在 Linux 3.1 加入進來的特性。主要目的是減少慢速 I/O 驅動上的重覆邏輯,提供一種通用的介面來操作底層硬體上的寄存器。其實這就是內核做的一次重構。Regmap 除了能做到統一的 I/O 介面,還可以在驅動和硬體 IC 之間做一層緩存,從而能減少底層 I/O ...


1. 簡介

Regmap 機制是在 Linux 3.1 加入進來的特性。主要目的是減少慢速 I/O 驅動上的重覆邏輯,提供一種通用的介面來操作底層硬體上的寄存器。其實這就是內核做的一次重構。Regmap 除了能做到統一的 I/O 介面,還可以在驅動和硬體 IC 之間做一層緩存,從而能減少底層 I/O 的操作次數。

2. 使用對比

在瞭解 Regmap 的實現細節前,我們先來對比一下,傳統操作寄存器的方式,與 Regmap 之間的差異。

2.1 傳統方式

我們以一個 I2C 設備為例。讀寫一個寄存器,肯定需要用到 i2c_transfer 這樣的 I2C 函數。為了方便,一般的驅動中,會在這之上再寫一個 Wrapper,然後通過調用這個 Wrapper 來讀寫寄存器。比如如下這個讀取寄存器的函數:

static int xxx_i2c_read_reg(struct i2c_client *client, u8 reg, u8 *val)
{
        struct i2c_msg msg[] = {
            {
                .addr = client->addr,
                .flags = 0,
                .len = 1,
                .buf = &reg,
            },
            {
                .addr = client->addr,
                .flags = I2C_M_RD,
                .len = 1,
                .buf = val,
            },
        };
     
        return i2c_transfer(client->adapter, msg, 2);
}

2.2 Regmap方式

如果 regmap 的方式來實現,對於上面這種讀寄存器操作,其實現如下:

// first step: define regmap_config
static const struct regmap_config xxx_regmap_config = {
        .reg_bits = 10,
        .val_bits = 14,
     
        .max_register = 40,
        .cache_type = REGCACHE_RBTREE,
     
        .volatile_reg = false,
        .readable_reg = false,
    };
     
 // second step: initialize regmap in driver loading
regmap = regmap_init_i2c(i2c_client, &xxx_regmap_config);
     
 // third step: register operations
regmap_read(regmap, XXX_REG, &value);

代碼中,做的第一步就是定義 IC 的一些寄存器信息。比如:位寬,地址位寬,寄存器總數等。然後在驅動載入的時候,初始化 Regmap,這樣就可以正常調用 Regmap 的 API 了。
可以看到,為了讓慢速 I/O 能夠專註於自身的邏輯,內核把 SPI, I2C 等匯流排操作方式全部封裝在 Regmap 里,這樣驅動若要做 I/O 操作,直接調用 Regmap 的函數就可以了。

3. 實現細節

整個 Regmap 是分為 3 層,其拓撲結構如下:

這裡通過其中 3 個核心結構體來分別說明。

3.1 regmap_config

struct regmap_config構體代表一個設備的寄存器配置信息,在做 Regmap 初始化時,驅動就需要把這個結構體傳給 Regmap。這個結構體的定義在 include/linux/regmap.h,其中包含該設備的寄存器數量,寄存器位寬,緩存類型,讀寫屬性等。
這一層是直接和驅動對接的。Regmap 根據傳進來的 regmap_config 初始化對應的緩存和匯流排操作介面,驅動就可以正常調用 regmap_writeregmap_read 函數。

3.2 regmap_ops

struct regmap_ops是用來定義一個緩存類型的,具體定義如下:

struct regcache_ops {
        const char *name;
        enum regcache_type type;
        int (*init)(struct regmap *map);
        int (*exit)(struct regmap *map);
    #ifdef CONFIG_DEBUG_FS
        void (*debugfs_init)(struct regmap *map);
    #endif
        int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
        int (*write)(struct regmap *map, unsigned int reg, unsigned int value);
        int (*sync)(struct regmap *map, unsigned int min, unsigned int max);
        int (*drop)(struct regmap *map, unsigned int min, unsigned int max);
};

在最新 Linux 4.0 版本中,已經有 3 種緩存類型,分別是數組(flat)、LZO 壓縮和紅黑樹(rbtree)。數組好理解,是最簡單的緩存類型,當設備寄存器很少時,可以用這種類型來緩存寄存器值。LZO(Lempel–Ziv–Oberhumer) 是 Linux 中經常用到的一種壓縮演算法,Linux 編譯後就會用這個演算法來壓縮。這個演算法有 3 個特性:壓縮快,解壓不需要額外記憶體,壓縮比可以自動調節。在這裡,你可以理解為一個數組緩存,套了一層壓縮,來節約記憶體。當設備寄存器數量中等時,可以考慮這種緩存類型。而最後一類紅黑樹,它的特性就是索引快,所以當設備寄存器數量比較大,或者對寄存器操作延時要求低時,就可以用這種緩存類型。
緩存的類型是在 Regmap 初始化時,由.cache_type = REGCACHE_RBTREE來指定的。對於regmap_read獲取值,若需要從硬體上讀取,則調用具體協議的讀寫函數,若是 I2C,調用i2c_transfer。寫的過程也是大同小異。

3.3 regmap_bus

前面說的都是 Regmap 所做的封裝,而真正進行 I/O 操作就是這最後一層。struct regmap_bus 定義了一個匯流排上的讀寫函數,這一層就像之前對 i2c_transfer所做的封裝一樣。其定義如下:

struct regmap_bus {
        bool fast_io;
        regmap_hw_write write;
        regmap_hw_gather_write gather_write;
        regmap_hw_async_write async_write;
        regmap_hw_reg_write reg_write;
        regmap_hw_read read;
        regmap_hw_reg_read reg_read;
        regmap_hw_free_context free_context;
        regmap_hw_async_alloc async_alloc;
        u8 read_flag_mask;
        enum regmap_endian reg_format_endian_default;
        enum regmap_endian val_format_endian_default;
};

在 Lernel 4.0 中,已經支持了 I2C、SPI、AC97、MMIO 和 SPMI 五種匯流排類型。相信在未來,有更多的匯流排會加進來。其實添加一個匯流排也不是很難,只需 4 個函數就可以了:xxx_readxxx_writexxx_initxxx_deinit。具體可以看源碼,這裡就不多說了,留個任務在這吧。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 關於“ConnectionString 屬性尚未初始化”的問題(如下圖), 我在下麵一段代碼中發現了問題所在: 問題就出在標紅的代碼上,cnn.dispose() 釋放con對象所占用的資源,釋放後這個對象就不可用了,所以出現“ConnectionString 屬性尚未初始化”的問題,當頁面首次載入 ...
  • BitAdminCore應用索引 NET Core應用框架之BitAdminCore框架應用篇系列 一、簡介 querySuite為適應後臺快速增刪查改而自行開發的組件。 開發套件的核心思想: 1、佈局與功能分離:佈局歸佈局,功能歸功能。 2、佈局易讀性:使用行業通用佈局,能看到需要呈現的完整元素。 ...
  • using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using Syst... ...
  • 在經過了上面幾篇文章的學習這賓,本篇文章我們來學習如何在已經的功能中添加新欄位。 ...
  • 20180523更新內容 本次更新兩個內容,一是增加視頻處理功能,二是增加定時服務功能。 視頻處理 定時服務 BitAdminCore框架,用最少的代碼,實現最多的功能 本次新暫未發佈,後續有空發佈 計劃修改內容 1、人臉登錄功能需要重構,目前功能不完善。 2、QuerySuite類重構,同時支持m ...
  • 偉大的無產階級Willaim曾說過:"無論你覺得自己多麼的了不起,也永遠有人比你更強"。對,我說過!我就是william。 今天想記錄一下在項目中遇到的一個比較有意思的東西,異常攔截器(也不能完全說只是異常攔截,準確的說應該叫方法攔截),那有的人可能會說,異常攔截器不就是用Try……Catch就好了 ...
  • 之前ASP.NET中使用的HTTP Modules及HTTP Handlers,在ASP.NET Core中已不復存在,取而代之的是Middleware。Middleware除了簡化了HTTP Modules/Handlers的使用方式,還帶入了Pipeline的概念。本篇將介紹ASP.NET Co ...
  • AWK中,變數分為兩種:內置變數與自定義變數。 常見的內置變數有: FS:輸入欄位分隔符, 預設為空白字元 OFS:輸出欄位分隔符, 預設為空白字元 RS:輸入記錄分隔符(輸入換行符), 指定輸入時的換行符 ORS:輸出記錄分隔符(輸出換行符),輸出時用指定符號代替換行符 NF:number of ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...