OpenHarmony-3.HDF Display子系统(6)

news2024/12/20 14:29:59
  • Display 子系统

1.Display驱动模型介绍

  当前操作系统和 SOC 种类繁多,各厂商的显示屏器件也各有不同,随之针对器件的驱动代码也不尽相同,往往是某一款器件驱动,只适用于某单一内核系统或 SOC,如果要迁移到其他内核或者 SOC,可能会有不小的移植工作量。而且,不同驱动 IC 的驱动代码差异较大,产品更换驱动 IC,则又需要重新开发对应的器件驱动,造成重复工作。因此基于 HDF 驱动框架,编写一套较通用的 Display 器件驱动模型,尽可能降低驱动开发者的开发或移植工作量,简化器件驱动开发,提升开发效率。

  Display驱动编程,通过对显示器上电、初始化显示器驱动IC(Integrated Circuit)内部寄存器等操作,使其可以正常工作。基于HDF(Hardware Driver Foundation)驱动框架构建的Display驱动模型作用如下:

  • 为LCD器件驱动开发提供了基础驱动框架,提升驱动开发效率。

  • 便于开发的器件驱动实现跨OS、跨芯片平台迁移。

  基于HDF驱动框架的Display驱动模型如下所示:
在这里插入图片描述
  模型各层设计说明:

  • Display 驱动模型基于 HDF 驱动框架、Platform 接口及 OSAL 接口开发,可以做到不区分OS(LiteOS、Linux)和芯片平台(Hi35xx、Hi38xx、V3S等),为 LCD 器件提供统一的驱动模型。

  • 当前 HDF Display 驱动模型主要分为四层:标准架构适配层(DRM Panel Adapter Driver)、显示公共驱动层(Display Common Driver)、芯片平台适配层(SoC Adapter Driver)、器件驱动层(Display Panel Driver)。

1.1.标准架构适配层

  • drivers_hdf_core\framework\model\display\driver\hdf_drm_panel.c
    在这里插入图片描述

  本层主要完成对接标准的显示驱动架构,如 DRM(Direct Rending Manager)或 FB(Framebuffer),以 DRM 为例,将 panel 侧驱动接口对接到标准框架中,保证在 DRM 框架中实现对 Panel 驱动的操作接口,当前注册的接口如下:

static struct drm_panel_funcs g_hdfDrmPanelFuncs = {
    .get_modes = HdfDrmPanelGetModes,
    .enable = HdfDrmPanelEnable,
    .disable = HdfDrmPanelDisable,
    .prepare = HdfDrmPanelPrepare,
    .unprepare = HdfDrmPanelUnprepare,
};

1.2.显示公共驱动层

  • drivers_hdf_core\framework\model\display\driver\hdf_disp.c
    在这里插入图片描述

  此部分属于整个驱动模型的中枢,所有的屏端接口注册、Panel 信息管理、屏幕状态控制、用户态 HDI 接口命令处理、以及通用的基础显示特性,目前都是通过这部分实现。

  在本层通过结构体 DispManager 管理所有的显示信息,其成员 PanelManager 用于记录与显示屏相关的接口及参数信息。同时接收并处理 HDI 层直接对 panel 操作相关的指令(主要用于 L0-L1 等轻量级系统),如 Panel 器件信息的获取、休眠唤醒、背光设置等指令。此外,本层还负责实现一些基础显示特性的业务框架,如 ESD 检查机制,力求将显示相关的共有逻辑集中到本层实现,以简化 Panel 器件驱动的实现,避免 panel 驱动中相同功能的重复实现,便于统一管理和维护。

1.3.芯片平台适配层

在这里插入图片描述

  借助此 SoC 适配层,实现 Display 器件驱动和 SoC 侧硬件资源的解耦,主要完成芯片平台强相关的参数配置,如 mipi 速率计算及设置、管脚复用配置,以及其他和 SoC 强相关的差异化配置及初始化等。

1.4.器件驱动层

  • drivers_hdf_core\framework\model\display\driver\panel
    在这里插入图片描述

  器件驱动层主要实现和器件自身强相关的驱动适配接口,例如发送初始化序列、休眠唤醒流程、背光设置、ESD 检测等,同时完成 panel 信息的解析,并将 panel 向上注册到公共驱动层进行管理。

1.5.驱动加载及运行

  HDF 的驱动的加载方式,框架通过解析设备描述的 hcs 配置文件,获取到各设备的配置信息,根据 moduleName 来匹配对应设备的驱动文件入口,按照配置的加载优先级,依次加载驱动。
在这里插入图片描述  加载流程分为 9 步,分别说明如下:

  • HDF Device Manager 解析设备描述;
  • HDF 优先加载器件驱动层,构建 Panel 设备;
  • 将 panel信息及操作接口注册到公共驱动层;
  • HDF 其次加载芯片平台适配层,进行 SoC 相关硬件资源初始化;
  • HDF再次加载公共驱动层,对共有特性进行初始化;
  • HDF 最后加载标准架构适配层;
  • 从公共驱动层中获取到 PanelManager,;
  • 将对应panel 注册到 DRM 框架中;
  • 在系统运行起来后,DRM 会调用 panel ops 进行显示屏控制。

备注:

对于LiteOS 这种轻量内核的系统,不会像 Linux 内核那样提供标准的显示框架,驱动模型也无法与其对接,因而上层图形系统可以通过 HDI 接口,来直接操控显示屏。

2.LCD接口

  LCD接口通常可分为MIPI DSI接口、TTL接口和LVDS接口,常用的是MIPI DSI接口和TTL接口。

  • MIPI DSI接口

    MIPI DSI接口是MIPI(Mobile Industry Processor Interface)联盟定义的显示接口,主要用于移动终端显示屏接口,接口数据传输遵循MIPI协议,MIPI DSI接口为数据接口,传输图像数据,通常情况下MIPI DSI接口的控制信息以MIPI包形式通过MIPI DSI接口发送到对端IC,不需要额外的外设接口。
    在这里插入图片描述

  • TTL接口
    TTL接口是并行方式传输数据的接口,有数据信号、时钟信号和控制信号(行同步、帧同步、数据有效信号等),在控制信号控制下完成数据传输。通常TTL接口的LCD,内部寄存器读写需要额外的外设接口,比如SPI接口、I2C接口等。
    在这里插入图片描述

3.HDF LCD 驱动

3.1.LCD 内核配置

  • Kconfig\Makefile
drivers_hdf_core\adapter\khdf\linux\model\display\Kconfig:
config DRIVERS_HDF_DISP
    bool "Enable HDF Display driver"
    default n
    depends on DRIVERS_HDF
    help
        Answer Y to choice HDF Display driver.
config DRIVERS_HDF_LCDKIT
    bool "Enable HDF Lcdkit driver"
    default n
    depends on DRIVERS_HDF_DISP
    help
        Answer Y to enable HDF Lcdkit driver.
config DRIVERS_HDF_LCD_ICN9700
    bool "Enable HDF Icn9700 driver"
    default n
    depends on DRIVERS_HDF_DISP
    help
        Answer Y to enable HDF Icn9700 driver.

drivers_hdf_core\adapter\khdf\linux\model\display\Makefile:
KHDF_DISPLAY_BASE_ROOT_DIR = ../../../../../../..
DISPLAY_ROOT_DIR = ../../../../../framework/model/display/driver

ifeq ($(CONFIG_DRIVERS_HDF_DISP), y)
obj-y += \
         $(DISPLAY_ROOT_DIR)/hdf_disp.o \
         $(DISPLAY_ROOT_DIR)/backlight/hdf_bl.o

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
ifeq ($(CONFIG_ARCH_ROCKCHIP), y)
obj-y += $(DISPLAY_ROOT_DIR)/hdf_drm_panel.o
endif
#endif

obj-$(CONFIG_DRIVERS_HDF_PLATFORM_PWM) += \
         $(DISPLAY_ROOT_DIR)/backlight/pwm_bl.o

obj-$(CONFIG_ARCH_SPRD) += \
         $(DISPLAY_ROOT_DIR)/panel/ili9881c_boe.o

obj-$(CONFIG_ARCH_HI3516DV300) += \
         $(DISPLAY_ROOT_DIR)/adapter_soc/hi35xx_disp.o

obj-$(CONFIG_DRIVERS_HDF_LCDKIT) += \
         $(DISPLAY_ROOT_DIR)/lcdkit/lite_lcdkit.o \
         $(DISPLAY_ROOT_DIR)/lcdkit/lcdkit_parse_config.o
...

ccflags-y += -lm -lc -lgcc \
            -I$(srctree)/drivers/hdf/framework/model/display/driver \
            -I$(srctree)/drivers/hdf/framework/model/display/driver/adapter_soc \
            ...
ccflags-y +=-I$(srctree)/bounds_checking_function/include

endif

3.2.LCD 设备配置

  • 配置设备描述信息(vendor/hihope/rk3568/hdf_config/khdf/device_info/device_info.hcs)

  驱动注册到 HDF 框架所需要的设备驱动描述信息,如驱动是否加载以及加载次序等。device_info.hcs 中的信息主要提供给 HDF 框架使用,包含了 Input 模型各层驱动注册到 HDF 框架所必需的信息,开发者无特殊场景需求无需改动。各驱动层私有配置信息通过**“deviceMatchAttr”字段与 input_config.hcs 中的“match_attr”**相关内容进行匹配。

237         display :: host {
238             hostName = "display_host";
239             device_hdf_drm_panel :: device {
240                 device0 :: deviceNode {
241                     policy = 0;
242                     priority = 197;
243                     preload = 0;
244                     moduleName = "HDF_DRMPANEL";
245                 }
246             }
                /* Display平台驱动设备描述 */
247             device_hdf_disp :: device {                 
248                 device0 :: deviceNode {
249                     policy = 2;
250                     priority = 196;
251                     permission = 0660;
252                     moduleName = "HDF_DISP";
253                     serviceName = "hdf_disp";
254                 }
255             }
             /* SOC适配层驱动设备描述 */
256       	device_hi35xx_disp :: device {
257                 device0 :: deviceNode {
258                     policy = 0;
259                     priority = 195;
260                     moduleName = "HI351XX_DISP";
261                 }
262             }
               /* LCD器件驱动设备描述 */
263             device_lcd :: device {
271                 ...
283                 device3 :: deviceNode {
284                     policy = 0;
285                     priority = 100;
286                     preload = 0;
287                     moduleName = "LCD_ILI9881_ST_5P5";
288                 }
289             }
290             device_pwm_bl :: device {
291                 device0 :: deviceNode {
292                     policy = 0;
293                     priority = 95;
294                     preload = 0;
295                     moduleName = "PWM_BL";
296                     deviceMatchAttr = "pwm_bl_dev";
297                 }
298             }
299             device_backlight :: device {
300                 device0 :: deviceNode {
301                     policy = 2;
302                     priority = 90;
303                     preload = 0;
304                     permission = 0660;
305                     moduleName = "HDF_BL";
306                     serviceName = "hdf_bl";
307                 }
308             }
309         }
  • .板级配置及器件私有配置(vendor/hihope/rk3568/hdf_config/khdf/lcd/lcd_config.hcs )
  1 root {
  2     backlightConfig {
  3         pwmBacklightConfig {
  4             match_attr = "pwm_bl_dev";
  5             pwmDevNum = 1;
  6             pwmMaxPeriod = 25000;
  7             backlightDevName = "hdf_pwm";
  8             minBrightness = 0;
  9             defBrightness = 127;
 10             maxBrightness = 255;
 11         }
 12     }
 13 }

3.3.驱动实现

  • 对于LCD类型的设备,公共驱动框架已实现。
	drivers_hdf_core\framework\model\display\driver\hdf_drm_panel.c
	drivers_hdf_core\framework\model\display\driver\hdf_disp.c
	drivers_hdf_core\framework\model\display\driver\backlight\hdf_bl.c
	drivers_hdf_core\framework\model\display\driver\backlight\pwm_bl.c
  • 适配 ili9881_st_5p5 需要完成器件层驱动初始化、释放资源、注册驱动至HDF框架。

    drivers_hdf_core\framework\model\display\driver\panel\ili9881_st_5p5.c

3.3.1.ssp_st7789器件驱动

1).注册到HDF框架

struct HdfDriverEntry PanelDevEntry = {
    .moduleVersion = 1,
    .moduleName = "LCD_ILI9881_ST_5P5",
    .Init = PanelEntryInit,
};

HDF_INIT(PanelDevEntry);

2).器件层驱动初始化

struct panel_ili9881_dev {
    bool power_invert;
    struct PanelData panel;  		//重要数据结构
    struct mipi_dsi_device *dsiDev;
    struct regulator *supply;
    struct gpio_desc *enable_gpio;
    struct gpio_desc *reset_gpio;
    struct gpio_desc *hpd_gpio;
    struct panel_hw_delay hw_delay;
};

struct PanelData {
    struct HdfDeviceObject *object;
    int32_t (*init)(struct PanelData *panel);
    int32_t (*on)(struct PanelData *panel);
    int32_t (*off)(struct PanelData *panel);
    int32_t (*prepare)(struct PanelData *panel);
    int32_t (*unprepare)(struct PanelData *panel);
    struct PanelInfo *info;
    enum PowerStatus powerStatus;
    struct PanelEsd *esd;
    struct BacklightDev *blDev;
    void *priv;
};

static int32_t PanelEntryInit(struct HdfDeviceObject *object)
{
    struct device_node *panelNode = NULL;
    struct panel_ili9881_dev *panel_dev = NULL;

    panel_dev = (struct panel_ili9881_dev *)OsalMemCalloc(sizeof(struct panel_ili9881_dev));

    g_panel_dev = panel_dev;
    panelNode = of_find_compatible_node(NULL, NULL, "simple-panel-dsi");

    panel_dev->dsiDev = of_find_mipi_dsi_device_by_node(panelNode);

    panel_dev->supply = devm_regulator_get(&panel_dev->dsiDev->dev, "power");

    if (PanelRequestGpio(panel_dev) != HDF_SUCCESS) {
        goto FAIL;
    }

    PanelResInit(panel_dev);
    panel_dev->panel.object = object;
    object->priv = panel_dev;

    if (RegisterPanel(&panel_dev->panel) != HDF_SUCCESS) {
    	...
    }
    return HDF_SUCCESS;
}
  • 申请struct panel_ili9881_dev结构体,根据"simple-panel-dsi"查找内核设备数节点panelNode;
  • 获取plane 供电regulator和gpio 引脚;
  • 调用 PanelResInit进行初始化panel结构体;
    Panel 操作函数有:
    panel_dev->panel.init = PanelInit;
    panel_dev->panel.on = PanelOn;
    panel_dev->panel.off = PanelOff;
    panel_dev->panel.prepare = PanelPrepare;
    panel_dev->panel.unprepare = PanelUnprepare;
  • 调用RegisterPanel 注册panel到g_panelManager。

3.3.2. HDF LCD 公共驱动层

3.3.2.1.HDF_DISP

  • 结构体
drivers_hdf_core\framework\model\display\driver\hdf_disp.h
struct DispManager {
    struct PanelManager *panelManager;
    struct OsalMutex dispMutex;
    HdfWorkQueue dispWorkQueue;
    bool initialzed;
    struct DispEsd *esd;
};

struct PanelManager {
    struct PanelData *panel[PANEL_MAX];
    uint32_t panelNum;
};
  • 初始化及注册驱动至HDF框架
drivers_hdf_core\framework\model\display\driver\hdf_disp.c
struct HdfDriverEntry g_dispDevEntry = {
    .moduleVersion = 1,
    .moduleName = "HDF_DISP",
    .Init = HdfDispEntryInit,
    .Bind = HdfDispBind,
};

HDF_INIT(g_dispDevEntry);
  • .Init = HdfDispEntryInit,
    DispManagerInit初始化struct DispManager ,将 panelManager 注册到g_dispManager->panelManager,然后创建一个工作队列 HdfWorkQueueInit(&g_dispManager->dispWorkQueue, “dispWQ”);
  • .Bind = HdfDispBind,
    绑定服务HdfDispDispatch,调用DispCmdProcess通过g_dispCmdHandle进行显示命令处理。
static int HdfDispBind(struct HdfDeviceObject *dev)
{
    if (dev == NULL) {
        return HDF_FAILURE;
    }
    static struct IDeviceIoService dispService = {
        .object.objectId = 1,
        .Dispatch = HdfDispDispatch,
    };
    dev->service = &dispService;
    return HDF_SUCCESS;
}

DispCmdHandle g_dispCmdHandle[] = {
    GetPowerStatus,
    GetInfo,
    SetPowerStatus,
    SetBacklight,
    GetBacklight,
};

3.3.2.2.HDF_DRMPANEL

  • 结构体
drivers_hdf_core\framework\model\display\driver\hdf_drm_panel.h
struct HdfDrmPanel {
    struct drm_panel panel;
    struct DispManager *manager;
    struct drm_display_mode mode;
    struct mipi_dsi_device *dsiDev;
    uint32_t index;
};
  • 初始化及注册驱动至HDF框架
drivers_hdf_core\framework\model\display\driver\hdf_drm_panel.c
struct HdfDriverEntry g_hdfDrmPanelEntry = {
    .moduleVersion = 1,
    .moduleName = "HDF_DRMPANEL",
    .Init = HdfDrmPanelEntryInit,
};

refer to

  • https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-peripherals-lcd-des.md
  • https://blog.csdn.net/HarmonyOS_666/article/details/140824498?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-140824498-blog-143099522.235%5Ev43%5Epc_blog_bottom_relevance_base2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-140824498-blog-143099522.235%5Ev43%5Epc_blog_bottom_relevance_base2&utm_relevant_index=8

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

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

相关文章

一个日期范围选择框的设计

一个日期范围选择框的设计 一个日期范围选择框 这是一个日期范围选择框的设计,除了可以选择开始日期、结束日期之外。还要一些按钮用于快速选择日期范围: Today今天Yesterday昨天Today & Yesterday今天和昨天This month当月Last month上个月Last w…

【中标麒麟服务器操作系统实例分享】java应用DNS解析异常分析及处理

了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer.kylinos.cn 文档中心:https://documentkylinos.cn 情况描述 中标麒麟服务器操作系统V7运行在 ARM虚…

React 第十七节 useMemo用法详解

概述 useMemo 是React 中的一个HOOK,用于根据依赖在每次渲染时候缓存计算结果; 大白话就是,只有依赖项发生变化时候,才会重新渲染为新计算的值,否则就还是取原来的值,有点类似 vue 中的 computed 计算属性…

景联文科技:精准语音标注,驱动语音技术新发展

在人工智能迅速发展的今天,语音技术的应用已经渗透到我们生活的方方面面。从智能音箱、语音助手到自动语音识别系统,高质量的语音数据是这些应用成功的关键。景联文科技作为领先的AI数据服务提供商,专注于为客户提供高精度、高效的语音标注服…

中文分词学习

1.安装 jieba 库 !pip install jieba jieba 库是用于中文分词的工具,它通过精确的分词算法来处理文本。通过分词可以将中文句子拆分成单独的词语,这对于自然语言处理任务非常重要,比如文本分类、情感分析、关键词提取。 2.中文文本分词处理…

Android 动画深度解析

一、Android 动画发展历程与核心类型总览 自 Android 诞生起,动画系统便不断推陈出新。早期存在补间动画(Tween Animation)与帧动画(Frame Animation),而 Android 3.0 重磅引入属性动画(Proper…

Linux-ubuntu之主频和时钟配置

Linux-ubuntu之主频和时钟配置 一,主频二,其它时钟配置1.PLL2和PLL3的PFD0-3设置2.AHB_CLK_ROOT3.IPG 和 PERCLK时钟 三,总结 一,主频 24MHz 晶振为内核和其它外设提供时钟源,经电路后到PLL1变为996MHZ,再…

Autosar入门_汽车电子控制器

上一篇 | 返回主目录 汽车电子控制器 1 汽车电子控制器定义2 从功能角度来看构成2.1 车门控制器简单示例2.1.1 解锁过程分析2.1.2 无框车窗短降2.1.3 下电控制电耗2.2 控制器几大基本功能 3 从硬件构成角度看构成3.1 芯片类别说明3.2 芯片与功能联系 1 汽车电子控制器定义 汽…

变压器“变压”和“变流”说明

变压器可以改变交流电压的大小,也可以改变交流电流的大小。 改变交流电压 变压器既可以升高交流电压,也能降低交流电压。在忽略电能损耗的情况下,变 压器电压U、二次电压U2与烧组匝数N、二次烧组匝数的关系为: n称为匝数比或电…

初学stm32 --- 时钟配置

目录 stm32时钟系统 时钟源 (1) 2 个外部时钟源: (2)2 个内部时钟源: 锁相环 PLL PLLXTPRE: HSE 分频器作为 PLL 输入 (HSE divider for PLL entry) PLLSRC: PLL 输入时钟源 (PL…

[机器学习]XGBoost(3)——确定树的结构

XGBoost的目标函数详见[机器学习]XGBoost(2)——目标函数(公式详解) 确定树的结构 之前在关于目标函数的计算中,均假设树的结构是确定的,但实际上,当划分条件不同时,叶子节点包含的…

常用命名总结

命名在编程中是非常重要的,它直接影响到代码的可读性、可维护性和开发效率。一个好的命名能够让代码更加直观、易于理解和修改,反之,不恰当的命名可能导致混乱、错误和难以调试的问题。以下是一些关于命名的最佳实践和原则: 1. 简…

AutoMQ 流表一体新特性 Table Topic 发布: 无缝集成 AWS S3 Table 和 Iceberg

超越共享存储:使用 Apache Iceberg 中的 AutoMQ Table Topic 实现流处理与分析的统一 自 2023 年底官宣以来,AutoMQ 成功地将 Apache Kafka 从“Shared Nothing architecture”转变为“Shared Storage architecture”,这为京东、知乎、小红书…

maven使用Dependency-Check来扫描安全漏洞

在现代软件开发中,使用开源库和第三方依赖项已成为常态。然而,这些依赖项可能包含已知的安全漏洞,给应用程序带来潜在的风险。为了解决这个问题,OWASP Dependency-Check 应运而生。本文将介绍 OWASP Dependency-Check 的功能、安装…

#渗透测试#红队全栈 powshell基础使用

声明! 学习视频来自B站up主 泷羽sec,任何违法事件与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!! 目录标题 认识powsehll打开方式 使用方式美化自己的powershell简单…

Qt:QMetaObject::connectSlotsByName实现信号槽自动关联

简介 在Qt中,QMetaObject::connectSlotsByName 是一个便利的方法,它可以根据对象的对象名(objectName)自动将信号和槽连接起来。但是,要使用这个方法,必须确保: 1 控件(如按钮&…

《算法ZUC》题目

判断题 ZUC算法LFSR部分产生的二元序列具有很低的线性复杂度。 A.正确 B.错误 正确答案A 单项选择题 ZUC算法驱动部分LFSR的抽头位置不包括( )。 A.s15 B.s10 C.s7 D.s0 正确答案C 单项选择题 ZUC算法比特重组BR层主要使用了软件实现友好的…

maven项目中对不同目录下的同包同名类的引用情况整理

说明 maven项目,允许在不同目录中出现相同包名和相同类名,不会出现冲突,包括: java目录test目录依赖中目录 这里就用Hutool.class类中的一个常量做测试,如图 好奇同包同名类同时存在时,会加载哪个类 Syst…

【UE5 C++课程系列笔记】10——动态单播/多播的基本使用

目录 概念 申明动态委托 一、DECLARE_DYNAMIC_DELEGATE 二、DECLARE_DYNAMIC_MULTICAST_DELEGATE 绑定动态委托 一、BindDynamic 二、AddDynamic 三、RemoveDynamic 执行动态委托 ​一、Execute 二、ExecuteIfBound 三、IsBound 四、Broadcast 动态单播使用示…

Redis篇-19--运维篇1-主从复制(主从复制,读写分离,配置实现,实战案例)

1、概述 Redis的主从复制(Master-Slave Replication)是一种数据冗余机制,它允许将一台Redis服务器的数据复制到其他Redis服务器。在主从复制中,有一台主服务器(Master)和一个或多个从服务器(Sl…