STM32 FreeRTOS内存管理简介
在使用 FreeRTOS 创建任务、队列、信号量等对象时,通常都有动态创建和静态创建的方式。动态方式提供了更灵活的内存管理,而静态方式则更注重内存的静态分配和控制。
如果是1·的,那么标准 C 库 malloc() 和 free() 函数有时可用于此目的,但是有以下缺点:
它们在嵌入式系统上并不总是可用。
它们占用了宝贵的代码空间。
它们不是线程安全的。
它们不是确定性的 (执行函数所需时间将因调用而异)。
所以更多的时候需要的不是一个替代的内存分配实现。一个嵌入式/实时系统的 RAM 和定时要求可能与另一个非常不同,所以单一的 RAM 分配算法将永远只适用于一个应用程序子集。为了避免此问题,FreeRTOS 将内存分配 API 保留在其可移植层,提供了五种内存管理算法:
heap_1:最简单,不允许释放内存。
heap_2:允许释放内存,但不会合并相邻的空闲块。
heap_3:简单包装了标准 malloc() 和 free(),以保证线程安全。
heap_4:合并相邻的空闲块以避免碎片化。包含绝对地址放置选项。
heap_5:如同 heap_4,能够跨越多个不相邻内存区域的堆。
FreeRTOS内存管理算法
heap_1算法
heap_1 是最简单的实现方式。内存一经分配,它不允许内存再被释放。尽管如此,heap_1.c 还是适用于大量嵌入式应用程序。这是因为许多小型和深度嵌入的应用程序在系统启动时创建了所需的所有任务、队列、信号量等,并在程序的生命周期内使用所有这些对象(直到应用程序再次关闭或重新启动)。任何内容都不会被删除。

heap_2算法
heap_2 使用最佳适应算法,并且与方案 1 不同,它允许释放先前分配的块,它不将相邻的空闲块组合成一个大块。------空闲块不会合并
heap_2.c 适用于许多必须动态创建对象的小型实时系统 。
1、如果动态地创建和删除任务,且分配给正在创建任务的堆栈大小总是相同的,那么 heap2.c 可以在大多数情况下使用。
2、但是,如果分配给正在创建任务的堆栈的大小不是总相同,那么可用的空闲内存可能会被碎片化成许多小块,最终导致分配失败。
heap_2 使用最佳适应算法,该算法在空闲内存中选择与请求的内存大小最接近的块来分配内存。下面是一个简单的例子来说明最佳适应算法:
假设有一个空闲内存,其中包含以下块:
大小为 20 字节的空闲块。
大小为 15 字节的空闲块。
大小为 25 字节的空闲块。
现在有一个任务请求分配 18 字节的内存。最佳适应算法将选择大小为 20 字节的块,因为它与请求的大小最接近。在选择这个块后,分配器可能会将该块分割为两部分,一部分大小为 18 字节,用于任务的内存,另一部分大小为 2 字节,留作未分配的块。

heap_3算法
heap_3使用 C 库的 malloc 和 free 函数来进行内存分配和释放。它通过分配固定大小的块来管理内存,这些块的大小在配置 FreeRTOS 时进行定义,不会动态改变。
假设我们使用 Heap_3 管理内存,其中块的大小固定为 32 字节。初始时,整个内存被分割成大小为 32 字节的块:
块 1(32 字节)。
块 2(32 字节)。
块 3(32 字节)。
现在,有一个任务请求分配 20 字节的内存。Heap_3 算法将选择块 1,并将其分割成两部分:
分配给任务的内存块(20 字节)。
剩余未分配的块(12 字节)。
再假设另一个任务请求分配 40 字节的内存。由于没有足够大的块可供分配,heap_3 将返回分配失败的状态。
heap_3 的特点是块大小固定,这样可以简化内存管理。然而,也因为块大小不可变,可能导致内存碎片问题,即一些块可能无法完全被利用,从而浪费了一些内存。
heap_4算法
heap_4使用第一适应算法,并且会将相邻的空闲内存块合并成大内存块,减少内存碎片。
第一适应算法会在可用内存块中选择第一个足够大的内存块进行分配。

假设有一个内存块链表,其中包含以下顺序的内存块:
大小为 40 字节的块。
大小为 30 字节的块。
大小为 15 字节的块。
大小为 20 字节的块。
如果一个任务需要申请 25 字节的内存,第一适应算法将选择大小为 40 字节的块,因为它是第一个足够大以容纳任务需求的内存块。(如果是heap_2的最佳适应算法,会选择30字节的块)
heap_5算法
heap_5使用与 heap_4 相同的第一适应和内存合并算法,允许堆跨越多个不相邻(非连续)内存区域。适用于内存地址不连续的复杂场景。
reeRTOS内存管理相关API函数介绍
内存管理相关函数如下:
| 函数 | 描述 |
| void * pvPortMalloc( size_t xWantedSize ); | 申请内存 |
| void vPortFree( void * pv ); | 释放内存 |
| size_t xPortGetFreeHeapSize( void ); | 获取当前空闲内存的大小 |
相关文章:
STM32 FreeRTOS内存管理简介
在使用 FreeRTOS 创建任务、队列、信号量等对象时,通常都有动态创建和静态创建的方式。动态方式提供了更灵活的内存管理,而静态方式则更注重内存的静态分配和控制。 如果是1的,那么标准 C 库 malloc() 和 free() 函数有时可用于此目的&#…...
【云岚到家】-day02-客户管理-认证授权
第二章 客户管理 1.认证模块 1.1 需求分析 1.基础概念 一般情况有用户交互的项目都有认证授权功能,首先我们要搞清楚两个概念:认证和授权 认证: 就是校验用户的身份是否合法,常见的认证方式有账号密码登录、手机验证码登录等 授权:则是该用…...
【达梦数据库】两地三中心环境总结
目录 架构监视器位置异步备库同步频率配置:dmtimer.ini断网测试异地切换过程&回切:允许丢数据模式切换回切 架构 2(1主1实时备库)1(实时备库)1(异步备库),分别为节点1、2、3、4监视器位置 …...
【springboot 集成 mybatis-plus】
springboot 集成 mybatis-plus 前言实战代码生成器自动填充字段 前言 正如MyBatis-Plus官网所说,MyBatis-Plus 是一个 MyBatis 的增强工具,提供了强大的CRUD操作,支持主键自动生成,代码生成器,自动填充字段等等&#…...
深入浅出 Go语言并发安全字典 sync.Map:原理、使用与优化
深入浅出 Go语言并发安全字典 sync.Map:原理、使用与优化 背景介绍 Go语言作为一种高效的并发编程语言,其标准库中提供了丰富的并发工具,如sync.WaitGroup、sync.Mutex等。然而,在实际开发中,我们经常需要在多个goroutine之间共享数据,这就涉及到并发安全的问题。传统的…...
【Go】Go数据类型详解—指针
1. 前言 在我看来,一门编程语言语法的核心就在于数据类型。而各类编程语言的基本数据类型大致相同:int整型、float浮点型、string字符串类型、bool布尔类型,但是在一些进阶数据类型上就有所不同了。本文将会介绍Go语言当中核心的数据类型——…...
道格拉斯-普克算法(DP)轮廓点精简(Python)
1、介绍 道格拉斯-普克算法由David H. Douglas和Thomas K. Peucker于1973年提出,主要用于简化曲线或折线。而实际中,激光点云的边缘点非常粗糙,如果直接将点进行连接,锯齿问题严重。经过DP算法处理后,数据显示会比较光…...
WPF如何跨线程更新界面
WPF如何跨线程更新界面 在WPF中,类似于WinForms,UI控件只能在UI线程(即主线程)上进行更新。WPF通过Dispatcher机制提供了跨线程更新UI的方式。由于WPF的界面基于Dispatcher线程模型,当你在非UI线程(例如后…...
Ubuntu 24.04 LTS 服务器折腾集
目录 Ubuntu 更改软件源Ubuntu 系统语言英文改中文windows 远程链接 Ubuntu 图形界面Windows 通过 openssh 连接 UbuntuUbuntu linux 文件权限Ubuntu 空闲硬盘挂载到 文件管理器的 other locationsUbuntu 开启 SMB 服务,并通过 windows 访问Ubuntu安装Tailscale&am…...
ROS机器人学习和研究的势-道-术-转型和变革的长期主义习惯
知易行难。说说容易做到难。 例如,不受成败评价影响,坚持做一件事情10年以上,专注事情本身。 机器人专业不合格且失败讲师如何让内心保持充盈的正能量(节选)-CSDN博客 时间积累 注册20年。 创作历程10年。 创作10年…...
Linux 管道操作
Linux 管道操作 在 Linux 中,管道(Pipe)是一个非常强大且常用的功能,它允许将一个命令的输出直接传递给另一个命令作为输入,从而能够高效地处理和分析数据。管道在多个命令之间建立数据流,减少了文件的读写…...
【Python】深入探讨Python中的单例模式:元类与装饰器实现方式分析与代码示例
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 单例模式(Singleton Pattern)是一种常见的设计模式,它确保一个类只有一个实例&…...
imbinarize函数用法详解与示例
一、函数概述 众所周知,im2bw函数可以将灰度图像转换为二值图像。但MATLAB中还有一个imbinarize函数可以将灰度图像转换为二值图像。imbinarize函数是MATLAB图像处理工具箱中用于将灰度图像或体数据二值化的工具。它可以通过全局或自适应阈值方法将灰度图像转换为二…...
【NextJS】PostgreSQL 遇上 Prisma ORM
NextJS 数据库 之 遇上Prisma ORM 前言一、环境要求二、概念介绍1、Prisma Schema Language(PSL) 结构描述语言1.1 概念1.2 组成1.2.1 Data Source 数据源1.2.2 Generators 生成器1.2.3 Data Model Definition 数据模型定义字段(数据)类型和约束关系&…...
ASP.NET Core - 配置系统之配置提供程序
ASP.NET Core - 配置系统之配置提供程序 3. 配置提供程序3.1 文件配置提供程序3.1.1 JSON配置提供程序3.1.2 XML配置提供程序3.1.3 INI配置提供程序 3.2 环境变量配置提供程序3.3 命令行配置提供程序3.4 内存配置提供程序3.5 配置加载顺序 3.6 默认配置来源 3. 配置提供程序 前…...
【LeetCode: 215. 数组中的第K个最大元素 + 快速选择排序】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
【Flink系列】10. Flink SQL
10. Flink SQL Table API和SQL是最上层的API,在Flink中这两种API被集成在一起,SQL执行的对象也是Flink中的表(Table),所以我们一般会认为它们是一体的。Flink是批流统一的处理框架,无论是批处理(…...
JavaScript网页设计案例-JavaScript实现数据脱敏的几种解决方式
数据脱敏是指对数据进行处理,使其在不改变原始数据含义的前提下,降低数据泄露的风险,保护用户隐私。 案例:JavaScript实现数据脱敏 1. 掩码脱敏 掩码脱敏是通过替换或隐藏数据中的部分字符来达到脱敏的效果。常见的掩码方式包括…...
第12篇:从入门到精通:掌握python高级函数与装饰器
第12篇:高级函数与装饰器 内容简介 本篇文章将深入探讨Python中的高级函数与装饰器。您将学习什么是高阶函数,掌握常用的高阶函数如map、filter、reduce的使用方法;理解闭包的概念及其应用;深入了解装饰器的定义与使用ÿ…...
审计文件标识作为水印打印在pdf页面边角
目录 说明 说明 将审计文件的所需要贴的编码直接作为水印贴在页面四个角落,节省辨别时间 我曾经写过一个给pdf页面四个角落加上文件名水印的python脚本,现在需要加一个图形界面进一步加强其实用性。首先通过路径浏览指定文件路径,先检测该路…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
