当前位置: 首页 > news >正文

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

  • 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_DISPbool "Enable HDF Display driver"default ndepends on DRIVERS_HDFhelpAnswer Y to choice HDF Display driver.
config DRIVERS_HDF_LCDKITbool "Enable HDF Lcdkit driver"default ndepends on DRIVERS_HDF_DISPhelpAnswer Y to enable HDF Lcdkit driver.
config DRIVERS_HDF_LCD_ICN9700bool "Enable HDF Icn9700 driver"default ndepends on DRIVERS_HDF_DISPhelpAnswer 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/driverifeq ($(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
#endifobj-$(CONFIG_DRIVERS_HDF_PLATFORM_PWM) += \$(DISPLAY_ROOT_DIR)/backlight/pwm_bl.oobj-$(CONFIG_ARCH_SPRD) += \$(DISPLAY_ROOT_DIR)/panel/ili9881c_boe.oobj-$(CONFIG_ARCH_HI3516DV300) += \$(DISPLAY_ROOT_DIR)/adapter_soc/hi35xx_disp.oobj-$(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/includeendif

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.cdrivers_hdf_core\framework\model\display\driver\hdf_disp.cdrivers_hdf_core\framework\model\display\driver\backlight\hdf_bl.cdrivers_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

相关文章:

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

Display 子系统 1.Display驱动模型介绍 当前操作系统和 SOC 种类繁多,各厂商的显示屏器件也各有不同,随之针对器件的驱动代码也不尽相同,往往是某一款器件驱动,只适用于某单一内核系统或 SOC,如果要迁移到其他内核或者…...

Nginx中Server块配置的详细解析

Nginx中Server块配置的详细解析 一、Server块简介 在Nginx配置文件中,server块是非常关键的部分。它用于定义虚拟主机,一个server块就代表一个虚拟主机。这使得我们可以在一台Nginx服务器上通过不同的配置来处理多个域名或者基于不同端口的服务请求。 …...

php学习资料分享

php学习资料分享:夸克网盘分享...

EE308FZ_Sixth Assignment_Beta Sprint_Sprint Essay 3

Assignment 6Beta SprintCourseEE308FZ[A] — Software EngineeringClass Link2401_MU_SE_FZURequirementsTeamwork—Beta SprintTeam NameFZUGOObjectiveSprint Essay 3_Day5-Day6 (12.15-12.16)Other Reference1. WeChat Mini Program Design Guide 2. Javascript Style Guid…...

Eureka学习笔记-服务端

Eureka学习笔记 服务端 模块设计 Resources :这部分对外暴露了一系列的 Restful 接口。Eureka Client 的注册、心跳、获取服务列表等操作都需要调用这些接口。另外,其他的 Server 在同步 Registry 时也需要调用这些接口。Controller :这里提…...

无限次使用 cursor pro

github地址 cursor-vip 使用方式 在 MacOS/Linux 中,请打开终端; 在 Windows 中,请打开 Git Bash。 然后执行以下命令来安装: 部分电脑可能会误报毒,需要关闭杀毒软件/电脑管家/安全防护再进行 方式1:通过…...

网站运维之整站同步

网站运维之整站同步 1、使用rsync安装rsync工具子服务器生成密钥子服务器发送公钥到服务端(需要root允许ssh登录)服务端添加密钥子服务器尝试免密登录子服务器添加任务计划 2、开启root用户远程ssh3、ubuntu开启root用户 1、使用rsync 很多时候由于访问…...

【机器人】Graspness 端到端 抓取点估计 | 论文解读

在复杂场景中实现抓取检测,Graspness是一种端到端的方法; 输入点云数据,输出抓取角度、抓取深度、夹具宽度等信息。 开源地址:GitHub - rhett-chen/graspness_implementation: My implementation of Graspnet Graspness. 论文地…...

力扣2300.咒语和药水的成功对数(二分法)

根据 灵茶山艾府 题解所写 题目描述: 给你两个正整数数组 spells 和 potions ,长度分别为 n 和 m ,其中 spells[i] 表示第 i 个咒语的能量强度,potions[j] 表示第 j 瓶药水的能量强度。 同时给你一个整数 success 。一个咒语和药…...

WEB开发: 全栈工程师起步 - Python Flask +SQLite的管理系统实现

一、前言 罗马不是一天建成的。 每个全栈工程师都是从HELLO WORLD 起步的。 之前我们分别用NODE.JS 、ASP.NET Core 这两个框架实现过基于WebServer的全栈工程师入门教程。 今天我们用更简单的来实现: Python。 我们将用Python来实现一个学生管理应用&#xff0…...

云原生周刊:Kubernetes v1.32 正式发布

开源项目推荐 Helmper Helmper 简化了将 Helm Charts导入OCI(开放容器倡议)注册表的过程,并支持可选的漏洞修复功能。它确保您的 Helm Charts不仅安全存储,还能及时应用最新的安全修复。该工具完全兼容 OCI 标准,能够…...

京准电钟:电厂自控NTP时间同步服务器技术方案

京准电钟:电厂自控NTP时间同步服务器技术方案 京准电钟:电厂自控NTP时间同步服务器技术方案 随着计算机和网络通信技术的飞速发展,火电厂热工自动化系统数字化、网络化的时代已经到来。一方面它为控制和信息系统之间的数据交换、分析和应用…...

深入探索Flink的复杂事件处理CEP

深入探索Flink的复杂事件处理CEP 引言 在当今大数据时代,实时数据处理变得愈发关键。Apache Flink作为一款强大的流处理框架,其复杂事件处理(CEP)组件为我们从海量实时数据中提取有价值信息提供了有力支持。本文将详细介绍Flink…...

clickhouse-数据库引擎

1、数据库引擎和表引擎 数据库引擎默认是Ordinary,在这种数据库下面的表可以是任意类型引擎。 生产环境中常用的表引擎是MergeTree系列,也是官方主推的引擎。 MergeTree是基础引擎,有主键索引、数据分区、数据副本、数据采样、删除和修改等功…...

力扣hot100——哈希

1. 两数之和 class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> ans;map<int, int> mp;for (int i 0; i < nums.size(); i) {if (mp.count(target - nums[i])) {ans.push_back(mp[target - nums[i]])…...

少样本学习之CAML算法

上下文感知元学习&#xff08;Context-Aware Meta-Learning, CAML&#xff09; 概述 在机器学习和深度学习领域&#xff0c;元学习&#xff08;Meta-Learning&#xff09;旨在通过学习如何学习&#xff0c;使模型能够在面对新任务时快速适应。传统的元学习方法通常需要在特定…...

C# 中的闭包

文章目录 前言一、闭包的基本概念二、匿名函数中的闭包1、定义和使用匿名函数2、匿名函数捕获外部变量3、闭包的生命周期 三、Lambda 表达式中的闭包1、定义和使用 Lambda 表达式2、Lambda 表达式捕获外部变量3、闭包的作用域 四、闭包的应用场景1、事件处理2、异步编程3、迭代…...

网络编程 03:端口的定义、分类,端口映射,通过 Java 实现了 IP 和端口的信息获取

一、概述 记录时间 [2024-12-19] 前置文章&#xff1a; 网络编程 01&#xff1a;计算机网络概述&#xff0c;网络的作用&#xff0c;网络通信的要素&#xff0c;以及网络通信协议与分层模型 网络编程 02&#xff1a;IP 地址&#xff0c;IP 地址的作用、分类&#xff0c;通过 …...

制作项目之前的分析

对网页的分析可以从多个角度入手&#xff0c;具体包括内容分析、技术分析、用户体验分析。 以下是对网页分析的详细步骤&#xff0c;帮助你从不同维度评估一个网页的效果与质量&#xff1a; 1. 内容分析 内容是网页最核心的部分&#xff0c;确保其符合用户需求是网页设计的首…...

LeetCode 1925 统计平方和三元组的数目

探索平方和三元组&#xff1a;从问题到 Java 代码实现 在数学与编程的交叉领域&#xff0c;常常会遇到一些有趣且富有挑战性的问题。今天&#xff0c;就让我们深入探讨一下 “平方和三元组” 这个有趣的话题&#xff0c;并使用 Java 语言来实现计算满足特定条件的平方和三元组…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

TJCTF 2025

还以为是天津的。这个比较容易&#xff0c;虽然绕了点弯&#xff0c;可还是把CP AK了&#xff0c;不过我会的别人也会&#xff0c;还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...