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

STM32 FreeRTOS内存管理简介

在使用 FreeRTOS 创建任务、队列、信号量等对象时,通常都有动态创建和静态创建的方式。动态方式提供了更灵活的内存管理,而静态方式则更注重内存的静态分配和控制。

如果是的,那么标准 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是批流统一的处理框架,无论是批处理&#xff08…...

JavaScript网页设计案例-JavaScript实现数据脱敏的几种解决方式

数据脱敏是指对数据进行处理,使其在不改变原始数据含义的前提下,降低数据泄露的风险,保护用户隐私。 案例:JavaScript实现数据脱敏 1. 掩码脱敏 掩码脱敏是通过替换或隐藏数据中的部分字符来达到脱敏的效果。常见的掩码方式包括…...

第12篇:从入门到精通:掌握python高级函数与装饰器

第12篇:高级函数与装饰器 内容简介 本篇文章将深入探讨Python中的高级函数与装饰器。您将学习什么是高阶函数,掌握常用的高阶函数如map、filter、reduce的使用方法;理解闭包的概念及其应用;深入了解装饰器的定义与使用&#xff…...

审计文件标识作为水印打印在pdf页面边角

目录 说明 说明 将审计文件的所需要贴的编码直接作为水印贴在页面四个角落,节省辨别时间 我曾经写过一个给pdf页面四个角落加上文件名水印的python脚本,现在需要加一个图形界面进一步加强其实用性。首先通过路径浏览指定文件路径,先检测该路…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言:多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...

JDK 17 序列化是怎么回事

如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...