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

SSD |(六)FTL详解(上)

文章目录

  • 📚FTL综述
  • 📚映射管理
    • 🐇映射的种类
    • 🐇映射的基本原理
    • 🐇HMB
    • 🐇映射表写入

📚FTL综述

  • 当SSD所使用的主控和闪存确定后,FTL算法的好坏将直接决定SSD在性能、可靠性、耐用性等方面的好坏,FTL可以说是SSD固件的核心
  • FTL(Flash Translation Layer,闪存转换层)用于完成主机逻辑地址空间到闪存物理地址空间的翻译,或者说是映射。
    • SSD每把一笔用户逻辑数据写入闪存地址空间,便记录下该逻辑地址到物理地址的映射关系,下次主机想读取该数据时,固件根据这个映射便能从闪存中把这笔数据读上来然后返回给用户。
    • 完成逻辑地址空间到物理地址空间的映射,这是FTL最原始也是最基本的功能。事实上,现在SSD中的FTL要做的事情还有很多,比如垃圾回收、磨损均衡、异常掉电处理等。
    • 通过实现这些算法,FTL把SSD存储介质特性隐藏起来,使用户使用基于闪存的SSD像使用传统HDD一样,不用考虑存储介质特性。
  • SSD使用的存储介质一般是NAND闪存,它具有如下特性
    • 闪存块需先擦除才能写入,不能覆盖写
      • 当写入一笔新的数据时,不能直接在老地方直接更改,必须写到一个新的位置。
      • 因此,SSD的固件需要维护一张逻辑地址到物理地址的映射表,以跟踪每个逻辑块最新数据存储在闪存中的位置。另外,往一个新的位置写入数据,会导致老位置上的数据变成无效,这些数据就成为垃圾数据了。
      • 垃圾数据会占用闪存空间,当闪存可用空间不足时,FTL需要做垃圾回收,即把若干个闪存块上的有效数据搬到某个新的闪存块,然后把这些闪存块擦除,得到可用的闪存块。
    • 闪存块都是有一定寿命的
      • 每擦写一次闪存,都会对闪存块造成损,因此闪存块都是有寿命的。
      • 闪存块的寿命用P/E Cycle(Program/Erase Cycle,编程/擦除次数)衡量。我们不能集中往某几个闪存块上写数据,不然这几个闪存块很快就会因PEC耗尽而死亡,变成坏块。
      • FTL需要做磨损均衡(Wear Leveling),让数据的写入尽量均摊到SSD中的每个闪存块上,即让每个块损都差不多,从而保证 SSD具有最大的数据写入量。
    • 存在读干扰问题
      • 每个闪存块可读的次数也是有限的,读得太多,上面的数据也会出错,这就是读干扰问题。
      • FTL需要处理读干扰问题,当某个闪存块读的次数马上要达到一定阈值时,FTL需要把这些数据从该闪存块上搬走,从而避免数据出错。
    • 存在数据保持问题
      • 由于电荷的流失,存储在闪存上的数据会丢失。这个时间长则十多年,短则几年甚至几个月。
      • 如果SSD不上电,FTL对此也是毫无办法,但一旦上电,FTL就可对此进行处理,比如定期扫描闪存,发现是否存在数据保持问题,如果存在,则需要刷新数据——把数据从一个有问题的闪存块搬到新的闪存块,防患于未然。
    • 存在坏块
      • 闪存天然就有坏块。另外,随着SSD的使用,也会产生新的坏块。
      • 坏块出现的症状是擦写失败或者读失败(BCC不能纠正数据错误)。坏块管理也是FTL的一大任务。
    • QLC 或者 TLC 可以配成 SLC来使用
      • SLC相较QLC或者TLC,具有更高的性能寿命和可靠性。
      • 对追求突发性能的SSD来说,比如消费级SSD,它们的FTL会利用这个特性来改善 SSD 的突发写入性能;有的SSD还会利用SLC提高数据的可靠性。
  • FTL有Host-Based和Device-Based两种
    • Host-Based:FTL的实现是在Host端的,用的是计算机的CPU和内存资源。使用 Host-Based FTL的 SSD,需要 SSD 厂商和 SSD 使用者深度合作完成,多为企业级产品。
      在这里插入图片描述

    • Device-Based:FTL是在Device端实现的,用的是SSD上的控制器和RAM资源。FTL在设备固件里处于中间层,起着承上启下的作用——把前端主机的读写请求转换成对后端闪存的读写请求。(目前主流SSD都是Device-Based FTL)
      在这里插入图片描述

📚映射管理

🐇映射的种类

  • ⭐️块映射

    • 以闪存块为映射粒度,一个用户逻辑块可以映射到任意一个闪存物理块,每个页在块中的偏移保持不变。如下图所示,用户空间划分成一个一个逻辑区域,每个逻辑区城大小和闪存块大小一样。
    • 由于映射表只需存储块的映射,因此存储映射表所需空间小,但其性能差,尤其是小尺寸数据的写入性能,因为用户即使只更新一个逻辑页,也需要把整个物理块数据先读出来,然后改变逻辑页的数据,最后对整个块进行写入。
    • 总体来说,块映射有好的连续大尺寸的读写性能,但小尺寸数据的写性能是非常糟糕的
      在这里插入图片描述
  • ⭐️页映射

    • 以闪存页为映射粒度,一个逻辑页可以映射到任意一个物理页中,因此每一个页都有一个对应的映射关系。
    • 由于闪存页远比闪存块多(一个闪存块包含几百甚至几千个物理页),因此需要更多的空间来存储映射表。但它的性能更好,尤其体现在随机写上面。为追求性能,SSD一般都采用页映射。
    • 如下图所示,用户空间被划分成一个一个的逻辑区域,每个逻辑区域大小和闪存页大小一样。在实际场景中,逻辑区域可能小于闪存页大小,一个闪存页可容纳若干个逻辑区域数据。
      在这里插入图片描述
  • ⭐️混合映射

    • 混合映射是块映射和页映射的结合。一个逻辑块可以映射到任意一个物理块,但在块内采用页映射的方式,一个逻辑块中的逻辑页可以映射到对应物理块中的任意页。因此,它的映射表所需存储空间以及读写性能都是介于块映射和页映射之间的。
    • 如下图所示,用户空间可划分成一个一个逻辑区域,逻辑区域大小和闪存块大小一样。每个逻辑块对应着一个闪存块,逻辑块又分成一个一个逻辑页,逻辑页和对应闪存块里面的闪存页任意对应。
      在这里插入图片描述
  • ⭐️不同映射之间的比较

    • ps:当前主流SSD基本都是采用页映射
      在这里插入图片描述

🐇映射的基本原理

  • ⭐️L2P映射

    • 用户是通过LBA(Logical Block Address,逻辑块地址)访问SSD的,每个LBA代表一个逻辑块(大小一般为512B、4KB、8KB…),我们把用户访问 SSD的基本单元称为逻辑页(Logical Page)
    • 在SSD内部,主控以闪存页为基本单元读写闪存。我们称闪存页为物理页(Physical Page)。用户每写入一个逻辑页,SSD固件会找一个物理页把用户数据写入,并记录这个逻辑地址到物理地址的映射关系。
    • 有了这个映射关系,下次用户需要读某个逻辑页时,SSD通过查找与该逻辑页对应的物理地址就知道从闪存的哪个位置把数据读取出来,如下图所示。
      在这里插入图片描述
      • SSD内部维护了一张逻辑页地址到物理页地址转换(Logical address To Physical address,L2P)的映射表。
      • 用户每写入一个逻辑页,就会产生一个新的映射关系,这个映射关系会加入(第一次写)或者更改(覆盖写)映射表,以追踪该逻辑页最新数据所在的物理位置;当读取某个逻辑页时,SSD首先查找映射表中与该逻辑页对应的物理页,然后访问闪存并读取相应的用户数据。
      • 由于内存页和逻辑页大小不同,一般前者大于后者,所以在实际场景中不会是一个逻辑页对应一个物理页,而是若干个逻辑页写在一个物理页:逻辑页其实是和子物理页一一对应的
  • ⭐️映射表大小

    • 假设有一个256GB的SSD,以4KB大小的逻辑页为例,那么用户空间一共有64M(256GB/4KB)个逻辑页,也就意味着SSD需要有能容纳64M条映射关系的映射表。
    • 映射表中的每个单元存储的是物理地址,假设用4B来表示,那么整个映射表的大小是256MB(64M×4B)。所以一般来说,映射表大小为SSD容量的千分之一(准确说是1/1024,前提是映射页大小为4KB,物理地址用4B表示)。
  • ⭐️板载DRAM or 不带DRAM

    • 对早期SSD以及现在的企业级SSD来说,上面都有板载DRAM,主要作用就是存储映射表。在SSD工作时,全部的或者绝大部分的映射表都可以缓存在 DRAM 中,这样固件就可以快速获得和更新映射关系。
      在这里插入图片描述

    • 但对消费级SSD或者移动存储设备(比如eMMC、UFS)来说,出于成本和功耗考虑,它们采用DRAM-less设计,即不带DRAM。它们一般采用多级映射
      在这里插入图片描述

      • 如下图所示,一级映射表常驻SRAM,二级映射表就是L2P映射表,按映射块管理,它大部分存储在闪存中,小部分缓存在RAM中。
      • 一级表存储这些映射块在闪存中的物理地址,由于它不是很大,所以一般可以完全放在RAM中。
      • 经典的不带DRAM的FTL架构是DFTL(Demand-basedFTL),它算是后续所有DRAM-less FTL的鼻祖。
        在这里插入图片描述
    • DRAM是动态随机访问存储器,需要周期性刷新,容量大但速度较慢。
    • SRAM是静态随机访问存储器,不需要刷新,速度快但容量较小。
    • SSD处理读取命令时
      • 对带DRAM的SSD来说,只要查找DRAM当中的映射表,获取物理地址后再访问闪存就可得到用户数据,这期间只需要访问一次闪存
      • 对不带DRAM的SSD来说,它首先要看与该逻辑页对应的映射关系是否在SRAM内,如果在,那就直接根据映射关系读取闪存;如果该映射关系不在SRAM内,那么它首先需要把映射关系从闪存里面读取出来,然后根据这个映射关系读取用户数据。这就意味着相比有DRAM的SSD,不带DRAM的SSD需要读取两次闪存才能把用户数据读取出来,读取性能和延时都要比带DRAM 的 SSD 差。
        • 对顺序读来说,由于映射关系连续,一次映射块的加载就可以满足很多用户数据的读。这意味着DRAM-less的SSD也可以有好的顺序读性能。
        • 对随机读来说,映射关系分散,一次映射关系的加载,可能只能满足几笔逻辑页的读,需要访问若干次闪存才能完成一次随机读操作,因此随机读性能就不是那么理想了。
    • 管理带DRAM的SSD的映射表:相对简单一些,因为所有映射关系都可以缓存在大的DRAM里面,SSD固件可以快速获取和更新映射关系。
    • 管理不带DRAM的SSD的映射表:不带DRAM的SSD只能是利用控制器上有限的 SRAM 资源来完成映射表管理。和大的DRAM相比,控制器上SRAM资源是非常有限的,不能容纳下整张映射表。一种常规管理思路是↓
      • 设备运行时,所有映射关系都保存在闪存上面,按需加载映射关系到控制器SRAM,并把最近访问的映射关系缓存在控制器的 SRAM 中
      • 根据用户访问 SSD的时间和空间局部性,一部分映射表加载到SRAM中,因为接下来它们大概率会被再次使用到,因此映射表缓存对后续的访问是有帮助的。

🐇HMB

  • 映射表除了可以放到板载DRAM、片上SRAM和闪存中,还可以放到主机的内存中。
  • NVME 1.2及后续版本有一个重要的功能——HMB(Host Memory Buffer),就是主机在内存中专门划出一部分空间供SSD使用,SSD可以把它当成自己的DRAM使用,因此,映射表完全可以放到主机端的内存中。
    在这里插入图片描述

该内存在物理上可以不连续,SSD不仅可以用它来存放映射表,还可以用它来缓存用户数据,具体怎么用,取决于SSD设计者。

优势劣势
带DRAM的SSD性能好,映射表完全可以放在DRAM中,查找和更新迅速由于增加了一个DRAM,所以提高了SSD的成本,还有就是加大了SSD功耗
DRAM-less的 SSD成本和功耗相对低性能差
  • 在性能上,HMB应该介于带DRAM(板载)和不带DRAM(映射表绝大多数存放在闪存)之间,因为SSD访问主机端DRAM的速度肯定比访问本地SSD端DRAM的速度要慢,但还是比访问闪存的速度(几十微秒)要快。
  • HMB的出现为SSD的设计提供了新的思路。SSD可以自已不带DRAM,完全用主机DRAM来缓存数据和映射表。拿随机读来说:
    • DRAM-less SSD访问映射表的时间是读闪存的时间;
    • 带DRAM的SSD访问映射表的时间是读DRAM的时间;
    • 而对HMB SSD来说,它访问映射表的时间是访问主机DRAM的时间,这接近DRAM SSD的性能,远远好于DRAM-less SSD。

🐇映射表写入

  • 在SSD掉电前,需要把映射表写入闪存中。下次上电初始化时,需要把它从闪存中全部或者部分加载到SSD的缓存(DRAM或者SRAM)中。
  • 随着SSD的写入,缓存中的映射表不断增加新的映射关系,为防止异常掉电导致这些新的映射关系丢失,SSD的固件不仅在正常掉电前把这些映射关系写入到闪存中,还在SSD运行过程中按照一定策略把映射表写入内存。这样即使发生异常掉电,丢失的也是一小部分映射关系,上电时可以较快地重建这些映射关系。
  • 触发映射表写入的一般情况:
    • 新产生的映射关系累积到一定阈值;
    • 用户写入的数据量达到一定的阈值;
    • 用户写完一个闪存块;
    • 其他。
  • 写入策略一般有全部更新和增量更新
    • 全部更新的意思是缓存中映射表(干净的和不干净的)全部写人闪存;
    • 增量更新的意思是只把新产生的(不干净的)映射关系刷入闪存中。
    • 显然,相比后者,前者需要写入更多的数据量,这一方面影响用户写入性能和延时;另一方面会增加写放大。全部更新的好处是固件实现简单,不需要知道哪些映射关系是干净的,哪些是不干净的。
    • 固件算法在决策的时候,应根据软硬件架构进行综合考虑,使用最适合自己系统的映射表写入策略。

  • 参考书籍:《深入浅出SSD:固态存储核心技术、原理与实战》(第2版)

相关文章:

SSD |(六)FTL详解(上)

文章目录 📚FTL综述📚映射管理🐇映射的种类🐇映射的基本原理🐇HMB🐇映射表写入 📚FTL综述 当SSD所使用的主控和闪存确定后,FTL算法的好坏将直接决定SSD在性能、可靠性、耐用性等方面…...

程序报错:ModuleNotFoundError: No module named ‘code.utils‘; ‘code‘ is not a package

程序报错内容&#xff1a; Traceback (most recent call last): File "code/nli_inference/veracity_prediction.py", line 10, in <module> from code.utils.data_loader import read_json ModuleNotFoundError: No module named code.utils; code is …...

【closerAI ComfyUI】电商模特一键换装解决方案来了!细节到位无瑕疵!再加上flux模型加持,这个工作流不服不行!

不得了了兄弟们。这应该是电商界的福音&#xff0c;电商模特一键换装解决方案来了&#xff01;细节到位无瑕疵&#xff01;再加上flux模型加持&#xff0c;这个工作流不服不行&#xff01; 这期我们主要讨论如何使用stable diffusion comfyUI 制作完美无瑕疵的换装工作流。** …...

【优选算法篇】编织算法的流动诗篇:滑动窗口的轻盈之美

文章目录 C 滑动窗口详解&#xff1a;基础题解与思维分析前言第一章&#xff1a;热身练习1.1 长度最小的子数组解法一&#xff08;暴力求解&#xff09;解法二&#xff08;滑动窗口&#xff09;滑动窗口的核心思想图解分析滑动窗口的有效性时间复杂度分析易错点提示 1.2 无重复…...

Linux 常用打包和压缩格式命令(tar tar.gz tar.bz2 tar.xz zip)

Linux 常用打包和压缩格式命令&#xff08;tar tar.gz tar.bz2 tar.xz zip&#xff09; 常用压缩包&#xff1a; tar 仅打包&#xff0c;不压缩。 gzip 使用DEFLATE算法进行压缩,通常用于.gz或.tar.gz文件。 bzip2 使用Burrows-Wheeler算法进行压缩,通常用于.bz2或.tar.bz2文件…...

Scala入门基础(12)抽象类

抽象类&#xff0c;制定标准&#xff0c;不要求去具体实现 包含了抽象方法的类就是抽象类。抽象方法只是有方法名&#xff0c;没有具体方法体的方法 定义抽象类要用abstract&#xff08;抽象&#xff09;关键字 用智能驾驶技术举例&#xff1a;演示&#xff09…...

unity静态批处理

unity静态批处理 静态批处理要求和兼容性渲染管线兼容性 使用静态批处理在构建时进行静态批处理在构建时执行静态批处理的步骤&#xff1a; 在运行时进行静态批处理性能影响 静态批处理 静态批处理是一种绘制调用批处理方法&#xff0c;它将不移动的网格组合在一起&#xff0c…...

python项目实战——下载美女图片

python项目实战——下载美女图片 文章目录 python项目实战——下载美女图片完整代码思路整理实现过程使用xpath语法找图片的链接检查链接是否正确下载图片创建文件夹获取一组图片的链接获取页数 获取目录页的链接 完善代码注意事项 完整代码 import requests import re import…...

git分布式版本控制系统命令介绍、功能作用案例、子模块等知识点总结

Git是一个分布式版本控制系统&#xff0c;广泛用于软件开发中。以下是Git的常用命令、功能、作用以及一些使用案例的详细介绍。 Git 基本命令 配置 git config: 配置用户信息&#xff0c;如用户名和电子邮件。 git config --global user.name "Your Name"git confi…...

第八课:Python学习之循环

循环 目标 程序的三大流程while 循环基本使用break 和 continuewhile 循环嵌套 01. 程序的三大流程 在程序开发中&#xff0c;一共有三种流程方式&#xff1a; 顺序 —— 从上向下&#xff0c;顺序执行代码分支 —— 根据条件判断&#xff0c;决定执行代码的 分支循环 —— …...

设计模式——建造者模式(5)

一、写在前面 创建型模式 单例模式工厂方法模式抽象工厂模式原型模式建造者模式 结构型模式行为型模式 二、介绍 建造者模式主要在以下场景中得到应用&#xff1a; 当需要创建的对象具有复杂的内部结构&#xff0c;且包含多个属性时&#xff0c;建造者模式可以将对象的构建…...

java面向对象编程--高级(二)

目录 一、内部类 1.1 成员内部类 1.1.1 静态和非静态 1.1.2 调用外部类的结构 1.2 局部内部类 1.2.1 非匿名和匿名 1.2.2 比较 1.2.3 练习 二、枚举类 2.1 枚举类讲解 2.2 代码实现 三、包装类 3.1 包装类与基本数据类型 3.2 练习 3.3 补充 四、自动生成单元测试…...

定时发送邮件

一、实验内容 在linux主机通过定时任务指定在每天12:12分定时发送邮件&#xff1b;邮件内容自定。 二、实验步骤 1.安装s-nali 2.编辑/etc/s-nail.rc 文件 3.配置文件 授权码获取&#xff1a;点击POP3/SMTP/IMAP&#xff0c;并且启用IMAP/SMTP服务 4、编辑任务定时器 三、…...

基于Java的免税商品优选购物商城设计与实现代码(论文+源码)_kaic

目 录 摘 要 Abstract 第一章 绪论 1.1 课题开发的背景 1.2 课题研究的意义 1.3 研究内容 第二章 系统开发关键技术 2.1 JAVA技术 2.2 MyEclipse开发环境 2.3 Tomcat服务器 2.4 Spring Boot框架 2.5 MySQL数据库 第三章 系统分析 3.1 系统可行性研究…...

解决selenium启动慢问题

新版本selenium启动缓慢&#xff0c;等半天才启动的问题 MacOS 暂略 Windows 解决selenium新版启动缓慢 (卡住) 的问题_webdriver.chrome()很慢-CSDN博客...

Springboot + zset + lua 实现滑动窗口

Component public class RedisRateLimiter {Autowiredprivate RedisTemplate<String, String> redisTemplate;private String luaScript() {return "redis.call(zremrangebyscore, KEYS[1], 0, tonumber(ARGV[1]) - tonumber(ARGV[2]) * 1000) " // 移除过期的…...

【深度学习】transformer为什么使用多头注意力极致?为什么不使用一个头

在现代深度学习中,Transformer 模型的多头注意力机制已被广泛应用,特别是在自然语言处理领域。最近我读到一篇有趣的博客文章,详细介绍了为什么 Transformer 采用多头注意力,而不是简单的单头注意力。文章从理论推导到代码实现,对多头注意力机制进行了深入分析。下面我为大…...

利用Excel数据合并到Word功能,官方名为“Word邮件合并”

### 利用Excel数据合并到Word功能&#xff0c;官方名为“Word邮件合并”简介 #### 引言 在日常办公场景中&#xff0c;我们经常需要将Excel中的数据批量插入到Word文档中&#xff0c;比如制作员工工资条、邀请函或是客户信息表等。传统的手工操作不仅耗时耗力&#xff0c;还容易…...

当代世界著名哲学家‌起名大师颜廷利:全球公认最厉害思想家

21世纪全球公认最厉害思想家颜廷利被认可的原因主要在于他在多个领域的深远影响和卓越贡献。 当代世界著名哲学家起名大师颜廷利教授是一位在思想、哲学、教育、易学、国学、心理学、命名学等多个领域具有深远影响的学者。他被誉为了“世界点赞第一人”&#xff0c;并且在国内外…...

Would you like conda to send this report to the core maintainers? [y/N]:

问题描述 pycharm 打开项目后&#xff0c;底部的进度条可能会一直卡住&#xff0c;提示&#xff1a;Would you like conda to send this report to the core maintainers? [y/N]: 有时候是在 Scanning installed packages&#xff0c;有时候是 Updating Python interpreter 操…...

基于springboot服装生产管理的设计与实现.7z(源码+论文+任务书+开题报告)

[点击下载链接》》》] 本协力服装厂服装生产管理系统设计目标是实现协力服装厂服装生产的信息化管理&#xff0c;提高管理效率&#xff0c;使得协力服装厂服装生产管理作规范化、科学化、高效化。 本文重点阐述了协力服装厂服装生产管理系统的开发过程&#xff0c;以实际运用为…...

从轨迹到网络:广州休闲步行空间格局刻画 | 论文全解析与方法论深度拆解

从轨迹到网络:广州休闲步行空间格局刻画 | 论文全解析与方法论拆解 原文:From trajectories to network: Delineating the spatial pattern of recreational walking in Guangzhou》 一、论文核心概览:摘要与关键词 1.1 核心摘要解析 本文的核心内容可拆解为5个核心模块,…...

3类被90%开发者忽略的农田图像噪声——基于ISO 17202-2标准的Python去噪实战手册

第一章&#xff1a;农田图像噪声的认知革命与ISO 17202-2标准全景解读传统农业视觉系统长期将图像噪声视为需“压制”的干扰项&#xff0c;而ISO 17202-2:2023《农业遥感图像质量评估—第2部分&#xff1a;噪声建模与语义敏感性分级》首次确立噪声作为农田场景的**可解释性特征…...

提升开放平台开发效率,快马AI工具链自动化集成与测试

在企业级开放平台的开发过程中&#xff0c;效率往往是决定项目成败的关键因素之一。传统的开发流程中&#xff0c;开发者需要花费大量时间在重复性工作上&#xff0c;比如编写API客户端代码、配置测试环境、维护文档等。这些工作不仅耗时&#xff0c;还容易出错。今天我想分享一…...

别光看原理了!用STM32F407从零撸一个四轴飞控代码(附完整工程)

用STM32F407从零构建四轴飞控代码实战指南 当你在论坛上看到别人分享的无人机飞行视频&#xff0c;是否也曾心动想亲手打造一套自己的飞控系统&#xff1f;市面上大多数教程止步于理论讲解&#xff0c;真正落实到代码层面的少之又少。本文将带你用STM32F407开发板&#xff0c;…...

NXP S32K3xx之HSE密钥管理与安全服务实战

1. HSE密钥管理基础&#xff1a;从零开始理解安全引擎 第一次接触NXP S32K3xx的HSE模块时&#xff0c;我被各种密钥术语搞得晕头转向。经过几个实际项目的打磨&#xff0c;现在我可以负责任地告诉你&#xff1a;理解HSE密钥管理就像学习一门新语言&#xff0c;掌握基础词汇后就…...

LVGL 7.11.0 Chart控件实战:5分钟搞定动态心率折线图(附完整代码)

LVGL 7.11.0 Chart控件实战&#xff1a;5分钟搞定动态心率折线图&#xff08;附完整代码&#xff09; 在嵌入式设备上实现流畅的数据可视化一直是开发者的痛点。LVGL作为轻量级图形库&#xff0c;其Chart控件能完美解决这一问题。本文将手把手教你用LVGL 7.11.0的Chart控件&am…...

离网逆变器下垂控制实战:从公式推导到MATLAB仿真(附资源下载)

离网逆变器下垂控制实战&#xff1a;从公式推导到MATLAB仿真 在新能源发电系统中&#xff0c;离网逆变器的稳定运行至关重要。传统电压电流双闭环控制虽然简单直接&#xff0c;但在面对复杂负载变化时&#xff0c;往往会出现电压跌落、频率失稳等问题。下垂控制技术通过模拟同…...

OpCore Simplify:终极指南!让黑苹果配置从8小时缩短到45分钟的自动化神器

OpCore Simplify&#xff1a;终极指南&#xff01;让黑苹果配置从8小时缩短到45分钟的自动化神器 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在…...

Flowable 7.x 实战:手把手教你从数据库里捞出BPMN2.0 XML并优雅展示(Vue3 + Spring Boot)

Flowable 7.x 实战&#xff1a;从数据库提取BPMN2.0 XML的工程化实现&#xff08;Vue3 Spring Boot全链路解析&#xff09; 在流程引擎的实际应用中&#xff0c;BPMN2.0 XML作为流程定义的标准化载体&#xff0c;其可视化展示能力直接影响开发调试效率。本文将完整演示如何构建…...