【笔记】STM32L4系列使用RT-Thread Studio电源管理组件(PM框架)实现低功耗
硬件平台:STM32L431RCT6
RT-Thread版本:4.1.0
目录
一.新建工程
二.配置工程
编辑 三.移植pm驱动
四.配置cubeMX
五.修改驱动文件,干掉报错
六.增加用户低功耗逻辑
1.设置唤醒方式
2.设置睡眠时以及唤醒后动作
编辑
3.增加测试命令
七.下载验证
一.新建工程

二.配置工程
打开pm

这时候编译会报错

提示空闲线程栈太小了,改到2048就不会提示报错了
三.移植pm驱动
此时PM框架虽然已经打开,但是还是一个空架子,没有驱动。所以要去RTT官方仓库里边拷贝一套L4系列PM驱动。驱动文件位置在rt-thread\bsp\stm32\libraries\HAL_Drivers。
需要以下三个文件

然后将drv_lptim.c 和drv_pm.c放在drivers目录下,drv_lptim.h放在drivers\include目录下,这时候编译会报错,先不理会。

四.配置cubeMX
lptim的HAL需要使用cubeMX配置生成
SYS和RCC全部保持默认就行,不然程序可能运行不了

时钟配置为80M

打开LPTIM1
打开串口1
然后点击生成,关闭cubeMX
五.修改驱动文件,干掉报错
这时候编译错误就会从40多个减少到20多个,大多数都是头文件包含的问题,在drv_pm.c文件添加头文件

#include "rt-thread\components\drivers\include\drivers\pm.h"
#include <rtthread.h>
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
报错进一步减少

现在就是缺少一些PM所需函数,这些函数需要我们自己实现
在board.c文件中rt_hw_board_init函数下方添加如下代码
#include "rt-thread\components\drivers\include\drivers\pm.h"void SystemClock_MSI_ON(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/* Initializes the CPU, AHB and APB busses clocks */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;RCC_OscInitStruct.MSIState = RCC_MSI_ON;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){RT_ASSERT(0);}RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK){Error_Handler();}
}void SystemClock_MSI_OFF(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;RCC_OscInitStruct.HSIState = RCC_MSI_OFF;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* No update on PLL */if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}
}void SystemClock_80M(void)
{RCC_OscInitTypeDef RCC_OscInitStruct;RCC_ClkInitTypeDef RCC_ClkInitStruct;/**Initializes the CPU, AHB and APB busses clocks */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 1;RCC_OscInitStruct.PLL.PLLN = 20;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/**Initializes the CPU, AHB and APB busses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK){Error_Handler();}
}void SystemClock_24M(void)
{RCC_OscInitTypeDef RCC_OscInitStruct;RCC_ClkInitTypeDef RCC_ClkInitStruct;/** Initializes the CPU, AHB and APB busses clocks */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 1;RCC_OscInitStruct.PLL.PLLN = 12;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB busses clocks */RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK){Error_Handler();}
}void SystemClock_2M(void)
{RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_OscInitTypeDef RCC_OscInitStruct = {0};/* MSI is enabled after System reset, update MSI to 2Mhz (RCC_MSIRANGE_5) */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;RCC_OscInitStruct.MSIState = RCC_MSI_ON;RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){/* Initialization Error */Error_Handler();}/* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2clocks dividers */RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){/* Initialization Error */Error_Handler();}
}/*** @brief Configures system clock after wake-up from STOP: enable HSI, PLL* and select PLL as system clock source.* @param None* @retval None*/
void SystemClock_ReConfig(uint8_t mode)
{SystemClock_MSI_ON();switch (mode){case PM_RUN_MODE_HIGH_SPEED:case PM_RUN_MODE_NORMAL_SPEED:SystemClock_80M();break;case PM_RUN_MODE_MEDIUM_SPEED:SystemClock_24M();break;case PM_RUN_MODE_LOW_SPEED:SystemClock_2M();break;default:break;}// SystemClock_MSI_OFF();
}
并在board.h里声明

void SystemClock_Config(void);
void SystemClock_MSI_ON(void);
void SystemClock_MSI_OFF(void);
void SystemClock_80M(void);
void SystemClock_24M(void);
void SystemClock_2M(void);
void SystemClock_ReConfig(uint8_t mode);
这时候编译就不会在出现问题,PM驱动已经完成

六.增加用户低功耗逻辑
之前步骤已经将驱动配置完了,现在需要增加一些逻辑,比如什么时候该进入睡眠,设置用什么方式唤醒,唤醒之后要做一些什么
1.设置唤醒方式
本篇文章使用PA0中断唤醒,在mian.c里添加代码

#include "board.h"
#include "stm32l431xx.h"
#include "rt-thread\components\drivers\include\drivers\pm.h"#define PM_INT_PIN GET_PIN(A, 0) // 定义 PM 中断引脚为 PA0void PM_int_callback(void *args)
{rt_kprintf("PM Data Ready Interrupt Triggered!\n");
}void PM_int_init(void)
{// 设置 PA0 为输入模式rt_kprintf("PM INT pin init\r\n");rt_pin_mode(PM_INT_PIN, PIN_MODE_INPUT_PULLUP);// 绑定中断回调函数rt_pin_attach_irq(PM_INT_PIN, PIN_IRQ_MODE_RISING, PM_int_callback, RT_NULL);// 使能中断rt_pin_irq_enable(PM_INT_PIN, PIN_IRQ_ENABLE);
}INIT_BOARD_EXPORT(PM_int_init);
下载到板子上,这时候触发PA0中断,终端打印现象,说明PA0中断可以正常触发,触发后将唤醒睡眠的单片机

2.设置睡眠时以及唤醒后动作
#define LED_1 GET_PIN(C, 1) // LED1引脚定义
void pm_notify(rt_uint8_t event, rt_uint8_t mode, void *data)
{if (event == RT_PM_ENTER_SLEEP && mode == PM_SLEEP_MODE_DEEP) // 进入睡眠{rt_pin_write(LED_1, PIN_HIGH);rt_kprintf("enter pm\n");}else if (event == RT_PM_EXIT_SLEEP && mode == PM_SLEEP_MODE_DEEP) // 退出休眠{rt_pm_dump_status(); // 打印 PM 组件的状态rt_pm_run_enter(PM_RUN_MODE_HIGH_SPEED);clock_information(); // 打印时钟频率rt_pm_release(PM_SLEEP_MODE_DEEP); // 释放 DeepSleep 模式rt_pm_request(PM_SLEEP_MODE_NONE); // 请求工作模式rt_pin_write(LED_1, PIN_LOW);}
}int main(void)
{clock_information();rt_pm_notify_set(pm_notify, 0);return RT_EOK;
}
这时候编译会报错

将pm.c里边的static void rt_pm_dump_status(void)的static删除就行
3.增加测试命令
在main.c里边随便找个地方放进去
int stop_mode_test(void)
{rt_pm_request(PM_SLEEP_MODE_DEEP); // 请求 stop 模式rt_pm_dump_status(); // 打印 PM 组件状态rt_pm_release(PM_SLEEP_MODE_NONE); // 释放正常工作模式,释放后才能进入 stop 模式rt_pm_dump_status(); // 打印 PM 组件状态return 0;
}
MSH_CMD_EXPORT(stop_mode_test, stop_mode_test);
mian.c全部内容
/** Copyright (c) 2006-2025, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date Author Notes* 2025-03-08 RT-Thread first version*/#include <rtthread.h>#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>#include <rtdevice.h>
#include "board.h"
#include "stm32l431xx.h"
#include "rt-thread\components\drivers\include\drivers\pm.h"#define PM_INT_PIN GET_PIN(A, 0) // 定义 PM 中断引脚为 PA0void PM_int_callback(void *args)
{rt_kprintf("PM Data Ready Interrupt Triggered!\n");
}void PM_int_init(void)
{// 设置 PA0 为输入模式rt_kprintf("PM INT pin init\r\n");rt_pin_mode(PM_INT_PIN, PIN_MODE_INPUT_PULLUP);// 绑定中断回调函数rt_pin_attach_irq(PM_INT_PIN, PIN_IRQ_MODE_RISING, PM_int_callback, RT_NULL);// 使能中断rt_pin_irq_enable(PM_INT_PIN, PIN_IRQ_ENABLE);
}INIT_BOARD_EXPORT(PM_int_init);#define LED_1 GET_PIN(C, 1) // LED1引脚定义
void pm_notify(rt_uint8_t event, rt_uint8_t mode, void *data)
{if (event == RT_PM_ENTER_SLEEP && mode == PM_SLEEP_MODE_DEEP) // 进入睡眠{rt_pin_write(LED_1, PIN_HIGH);rt_kprintf("enter pm\n");}else if (event == RT_PM_EXIT_SLEEP && mode == PM_SLEEP_MODE_DEEP) // 退出休眠{rt_pm_dump_status(); // 打印 PM 组件的状态rt_pm_run_enter(PM_RUN_MODE_HIGH_SPEED);clock_information(); // 打印时钟频率rt_pm_release(PM_SLEEP_MODE_DEEP); // 释放 DeepSleep 模式rt_pm_request(PM_SLEEP_MODE_NONE); // 请求工作模式rt_pin_write(LED_1, PIN_LOW);}
}int stop_mode_test(void)
{rt_pm_request(PM_SLEEP_MODE_DEEP); // 请求 stop 模式rt_pm_dump_status(); // 打印 PM 组件状态rt_pm_release(PM_SLEEP_MODE_NONE); // 释放正常工作模式,释放后才能进入 stop 模式rt_pm_dump_status(); // 打印 PM 组件状态return 0;
}
MSH_CMD_EXPORT(stop_mode_test, stop_mode_test);int main(void)
{clock_information();rt_pm_notify_set(pm_notify, 0);return RT_EOK;
}
七.下载验证
测试成功

相关文章:
【笔记】STM32L4系列使用RT-Thread Studio电源管理组件(PM框架)实现低功耗
硬件平台:STM32L431RCT6 RT-Thread版本:4.1.0 目录 一.新建工程 二.配置工程 编辑 三.移植pm驱动 四.配置cubeMX 五.修改驱动文件,干掉报错 六.增加用户低功耗逻辑 1.设置唤醒方式 2.设置睡眠时以及唤醒后动作 编辑 3.增加测试命…...
C++什么是深复制和浅复制,构造函数和析构函数,哪一个可以写成虚函数,为什么?
在C之中深复制是指对于值类型复制它的值,对于指针类型不仅仅复制指针指向的值,还会重新分配一个内存空间用于放置复制的值(对动态分配的内存进行重新分配和内存复制),这种深复制不会出现悬空指针的问题,但是…...
从连接到交互:SDN 架构下 OpenFlow 协议的流程与报文剖析
在SDN架构中,交换机与控制器之间的通信基于 OpenFlow协议,其设计目的是实现控制平面与数据平面的解耦。以下是 交换机连接控制器 和 数据包进入交换机触发交互 的详细流程及协议报文分析: 一、交换机连接控制器的流程(初始化阶段&…...
第七课:Python反爬攻防战:Headers/IP代理与验证码
在爬虫开发过程中,反爬虫机制成为了我们必须面对的挑战。本文将深入探讨Python爬虫中常见的反爬机制,并详细解析如何通过随机User-Agent生成、代理IP池搭建以及验证码识别来应对这些反爬策略。文章将包含完整的示例代码,帮助读者更好地理解和…...
Golang学习笔记_47——访问者模式
Golang学习笔记_44——命令模式 Golang学习笔记_45——备忘录模式 Golang学习笔记_46——状态模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 编译器实现2. 财务系统3. UI组件系统 四、Go语言实现示例完整实现代码执行结果 五、…...
软件高级架构师 - 软件工程
补充中 测试 测试类型 静态测试 动态测试 测试阶段 单元测试中,包含性能测试,如下: 集成测试中,包含以下: 维护 遗留系统处置 高水平低价值:采取集成 对于这类系统,采取 集成 的方式&…...
IDEA 基础配置: maven配置 | 服务窗口配置
文章目录 IDEA版本与MAVEN版本对应关系maven配置镜像源插件idea打开服务工具窗口IDEA中的一些常见问题及其解决方案IDEA版本与MAVEN版本对应关系 查找发布时间在IDEA版本之前的dea2021可以使用maven3.8以及以前的版本 比如我是idea2021.2.2 ,需要将 maven 退到 apache-maven-3.…...
Qt之QGraphicsView图像操作
QGraphicsView图像操作:旋转、放大、缩小、移动、图层切换 1 摘要 GraphicsView框架结构主要包含三个主要的类QGraphicsScene(场景)、QGraphicsView(视图)、QGraphicsItem(图元)。QGraphicsScene本身不可见,是一个存储图元的容器,必须通过与之相连的QGraphicsView视图来显…...
人工智能之数学基础:对线性代数中逆矩阵的思考?
本文重点 逆矩阵是线性代数中的一个重要概念,它在线性方程组、矩阵方程、动态系统、密码学、经济学和金融学以及计算机图形学等领域都有广泛的应用。通过了解逆矩阵的定义、性质、计算方法和应用,我们可以更好地理解和应用线性代数知识,解决各种实际问题。 关于逆矩阵的思…...
嵌入式开发之串行数据处理
前题 前面几篇文章写了关于嵌入式软件开发时,关于串行数据处理的一些相关内容,有兴趣的可以看看《嵌入式开发:软件架构、驱动开发与串行数据处理》、《嵌入式软件开发之生产关系模型》和《嵌入式开发之Modbus-RTU协议解析》相关的内容。从业十…...
机器学习(六)
一,决策树: 简介: 决策树是一种通过构建类似树状的结构(颠倒的树),从根节点开始逐步对数据进行划分,最终在叶子节点做出预测结果的模型。 结构组成: 根节点:初始的数据集…...
结合unittest和pytest进行虚拟数据库测试
使用 pytest 和 MagicMock 模拟数据库操作,并测试假设的 create_user 函数,将用户添加到数据库中。 代码实现 from datetime import date from typing import List, Optional from unittest.mock import MagicMock from pydantic import BaseModel, Fi…...
Spring Boot 监听器(Listeners)详细教程
Spring Boot 监听器(Listeners)详细教程 目录 Spring Boot 监听器概述监听器核心概念最佳使用场景实现步骤高级配置详细使用场景总结 1. Spring Boot 监听器概述 Spring Boot 监听器(Listeners)基于 Spring Framework 的事件机制…...
工具介绍《githack》以及Git 命令行
一、Githack 工具介绍 Githack 是一个用于检测和利用网站 .git 目录泄露漏洞的安全工具。当网站错误配置导致 .git 目录可公开访问时,攻击者可通过该工具下载 .git 中的版本控制文件,并重建完整的项目源代码。 核心用途 检测 .git 目录泄露漏洞。从泄…...
【hello git】git rebase、git merge、git stash、git cherry-pick
目录 一、git merge:保留了原有分支的提交结构 二、git rebase:提交分支更加整洁 三、git stash 四、git cherry-pick 共同点:将 一个分支的提交 合并到 到另一个上分支上去 一、git merge:保留了原有分支的提交结构 现有一个模型…...
MR的环形缓冲区(底层)
MapReduce的大致流程: 1、HDFS读取数据; 2、按照规则进行分片,形成若干个spilt; 3、进行Map 4、打上分区标签(patition) 5、数据入环形缓冲区(KVbuffer) 6、原地排序ÿ…...
下载Hugging Face模型的几种方式
1.网页下载 直接访问Hugging Face模型页面,点击“File and versions”选项卡,选择所需的文件进行下载。 2.使用huggingface-cli 首先,安装huggingface_hub: pip install huggingface_hub 然后,使用以下命令下载模型࿱…...
Java 第十一章 GUI编程(2)
目录 GUI 事件处理 基本思路 添加事件监听器 对话框 实例 GUI 事件处理 对于采用了图形用户界面的程序来说,事件控制是非常重要的;到目前为止, 我们编写的图形用户界面程序都仅仅只是完成了界面,而没有任何实际的功能&…...
Redis数据结构深度解析:从String到Stream的奇幻之旅(一)
Redis系列文章 《半小时掌握Redis核心操作:从零开始的实战指南》-CSDN博客 Redis数据结构深度解析:从String到Stream的奇幻之旅(一)-CSDN博客 Redis数据结构深度解析:从String到Stream的奇幻之旅(二&…...
7V 至 30V 的超宽 VIN 输入范围,转换效率高达 96%的WD5030
WD5030 具备 7V 至 30V 的超宽 VIN 输入范围,这一特性使其能够适应多种不同电压等级的供电环境,无论是在工业设备中常见的较高电压输入,还是在一些便携式设备经过初步升压后的电压,WD5030 都能轻松应对,极大地拓展了应…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...

