freeRTOS中文实用教程5--内存管理
1.前言
不同的嵌入式系统具有不同的内存配置和时间要求。所以单一的内存分配算法只可能适合部分应用程序。
FreeRTOS 将内存分配作为可移植层面(相对于基本的内核代码部分而言)。这使得不同的应用程序可以提供适合自身的具体实现。
本章期望让读者了解以下事情:
- FreeRTOS 在什么时候分配内存。
- FreeRTOS 提供的三种内存分配方案范例
2.FreeRTOS内存管理概述
(1)当内核请求内存时,其调用pvPortMalloc()而不是直接调用malloc();当释放内存时,调用vPortFree()而不是直接调用free()。
pvPortMalloc()具有与malloc()相同的函数原型;vPortFree()也具有与free()相同的函数原型。
(2)FreeRTOS 自带有三种pvPortMalloc()与vPortFree()实现范例.FreeRTOS 的用户可以选用其中一种,也可以采用自己的内存管理方式
这三个范例对应三个源文件:heap_1.c,heap_2.c,heap_3.c——这三个文件都放在目录FreeRTOS\Source\Portable\MemMang 中
(3)早期版本的FreeRTOS 所采用的原始内存池和内存块分配方案已经被移除了,因为定义内存块和内存池的大小需要较深入的努力和理解。
(4)选择内存分配方案时不必考虑一些复杂的因素,比如确定性与内存碎片等,而只需要从性能上考虑,比如代码大小和简易性
在小型嵌入式系统中,通常是在启动调度器之前创建任务,队列和信号量。
这种情况表明,动态分配内存只会出现在应用程序真正开始执行实时功能之前,而且内存一旦分配就不会再释放
3. 内存分配方案范例
3.1 heap_1.c原理说明
(1)Heap_1.c 实现了一个非常基本的pvPortMalloc()版本,而且没有实现vPortFree()
如果应用程序不需要删除任务,队列或者信号量,则具有使用heap_1 的潜质
(2)这种分配方案是将FreeRTOS 的内存堆空间看作一个简单的数组。
当调用pvPortMalloc()时,则将数组又简单地细分为更小的内存块。
(3)数组的总大小(字节为单位)在FreeRTOSConfig.h 中由configTOTAL_HEAP_SIZE定义。
以这种方式定义一个巨型数组会让整个应用程序看起来耗费了许多内存——即使是在数组没有进行任何实际分配之前。
(4)需要为每个创建的任务在堆空间上分配一个任务控制块(TCB)和一个栈空间
3.2 heap_1.c内存分配示例

(1)A 表示数组在没有任何任务创建时的情形,这里整个数据是空的。
(2)B 表示数组在创建了一个任务后的情形。
(3)C 表示数组在创建了三个任务后的情形。
3.3 heap_2.c原理说明
(1)Heap_2.c 也是使用了一个由configTOTAL_HEAP_SIZE 定义大小的简单数组
(2)不同于heap_1 的是,heap_2 采用了一个最佳匹配算法来分配内存,并且支持内存释放
(3)由于声明了一个静态数组,所以会让整个应用程序看起来耗费了许多内存——即使是在数组没有进行任何实际分配之前
(4)最佳匹配算法保证pvPortMalloc()会使用最接近请求大小的空闲内存块
举例:堆空间中包含了三个空闲内存块,分别为5 字节,25 字节和100 字节大小。pvPortMalloc()被调用以请求分配20 字节大小的内存空间。
匹配请求字节数的最小空闲内存块是具有25字节大小的内存块——所以pvPortMalloc()会将这个25 字节块再分为一个20 字节块和一个5 字节块3,然后返回一个指向20 字节块的指针。
剩下的5 字节块则保留下来,留待以后调用pvPortMalloc()时使用
(5)Heap_2.c 并不会把相邻的空闲块合并成一个更大的内存块,所以会产生内存碎片——如果分配和释放的总是相同大小的内存块,则内存碎片就不会成为一个问题
(6)Heap_2.c 适合用于那些重复创建与删除具有相同栈空间任务的应用程序
3.4 heap_2.c内存分配示例

上图展示了当任务创建,删除以及再创建过程中,最佳匹配算法是如何工作的
(1)A 表示数组在创建了三个任务后的情形。数组的顶部还剩余一个大空闲块。
(2) B 表示数组在删除了一个任务后的情形。顶部的大空闲块保持不变,并多出了两个小的空闲块,分别是被删除任务的TCB 和任务栈。
(3) C 表示数组在又创建了一个任务后的情形。创建一个任务会产生两次调用pvPortMalloc(),一次是分配TCB,一次是分配任务栈
注:(1)调用pvPortMalloc()发生在xTaskCreate() API 函数内部
(2)每个TCB 都具有相同大小,所以最佳匹配算法可以确保之前被删除的任务占用的TCB 空间被重新分配用作新任务的TCB 空间。
(3)新建任务的栈空间与之前被删除任务的栈空间大小相同,所以最佳匹配算法会保证之前被删除任务占用的栈空间会被重新分配用作新任务的栈空间。数组顶部的大空闲块依然保持不变。
(4)Heap_2.c 虽然不具备确定性,但是比大多数标准库实现的malloc()与free()更有效率
3.5 heap_3.c原理说明
(1)Heap_3.c 简单地调用了标准库函数malloc()和free(),但是通过暂时挂起调度器使得函数调用具备线程安全特性
(2)内存堆空间大小不受configTOTAL_HEAP_SIZE 影响,而是由链接器配置
3.6 heap_3.c内存分配举例
4.参考文献
[1]FreeRTOS中文实用教程
freeRTOS中文实用教程5--内存管理的更多相关文章
- freeRTOS中文实用教程4--资源管理互斥
1.前言 访问一个被多任务共享,或是被任务与中断共享的资源时,需要采用”互斥”技术以保证数据在任何时候都保持一致性.这样做的目的是要确保任务从开始访问资源就具有排它性,直至这个资源又恢复到完整状态 F ...
- freeRTOS中文实用教程4--资源管理概述
1.前言 多任务系统中存在一种潜在的风险.当一个任务在使用某个资源的过程中,即还没有完全结束对资源的访问时,便被切出运行态,使得资源处于非一致,不完整的状态 2.并发抢占导致错误的场景 (1)访问外设 ...
- freeRTOS中文实用教程3--中断管理之中断嵌套
1.前言 最新的 FreeRTOS 移植中允许中断嵌套.中断嵌套需要在 FreeRTOSConfig.h 中设置configKERNEL_INTERRUPT_PRIORITY 和configMAX_S ...
- freeRTOS中文实用教程3--中断管理之计数信号量
1.前言 在中断不频繁的系统中,使用二值信号量没有问题,但是中断频繁发生时,则会有中断丢失的问题. 因为中断发生时延迟任务执行,延迟任务执行的过程中,如果又来了两次中断,则只会处理第一次,第二次将会丢 ...
- freeRTOS中文实用教程3--中断管理之中断服务例程中使用队列
1.前言 消息队列不仅可以用于事件通信,还可以用来传递数据 2.实例说明消息队列的执行过程 3.主要API API名称 说明 参数 返回值 xQueueSendFromISR()完全等同于 xQueu ...
- freeRTOS中文实用教程3--中断管理之延迟中断处理
1.前言 嵌入式实时操作系统需要对整个系统环境产生的事件作出响应.可以采用中断方式也可以采用轮询方式来进行处理.如果采用中断方式,则希望ISR(中断服务例程)的处理时间越短越好. 注:必须说明的是,只 ...
- freeRTOS中文实用教程6--错误排查
1.前言 本章主要是为刚接触FreeRTOS 的用户指出那些新手通常容易遇到的问题.这里把最主要的篇幅放在栈溢出以及栈溢出侦测上 2.printf-stdarg.c 当调用标准C 库函数时,栈空间使用 ...
- freeRTOS中文实用教程1--任务
1.前言 FreeRTOS是小型多任务嵌入式操作系统,硬实时性.本章主要讲述任务相关特性及调度相关的知识. 2. 任务的总体特点 任务的状态 (1)任务有两个状态,运行态和非运行态 (2)任务由非运行 ...
- freeRTOS中文实用教程2--队列
1.前言 freeRTOS中所有任务的通信和同步机制都是基于队列来实现. 2.队列的特点 图 队列的读写操作 队列的数据存储 (1)队列可以保存有限个具有确定长度的数据单元,队列可以保存的最大单元数目 ...
随机推荐
- 自学Linux Shell14.1-理解输入输出
点击返回 自学Linux命令行与Shell脚本之路 14.1-理解输入输出(点击这里获得更多) 两种显示脚本输出的方法: 在显示器屏幕上显示输出 将输出重定向到文件中 1. 标准文件描述符 linux ...
- 【BZOJ3879】SvT(后缀自动机,虚树)
[BZOJ3879]SvT(后缀自动机,虚树) 题面 BZOJ 题解 看着这个东西,询问若干个前缀两两之间的\(lcp\)? 显然\(lcp\)就是\(SAM\)构建出来的\(parent\)数上的\ ...
- uoj【UNR #3】To Do Tree 【贪心】
题目链接 uojUNR3B 题解 如果不输出方案,是有一个经典的三分做法的 但是要输出方案也是可以贪心的 设\(d[i]\)为\(i\)节点到最深的儿子的距离 贪心选择\(d[i]\)大的即可 #in ...
- CF1131D Gourmet choice(并查集,拓扑排序)
这题CF给的难度是2000,但我感觉没这么高啊…… 题目链接:CF原网 题目大意:有两个正整数序列 $a,b$,长度分别为 $n,m$.给出所有 $a_i$ 和 $b_j(1\le i\le n,1\ ...
- JDK源码分析(2)LinkedList
JDK版本 LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表.它也可以被当作堆栈.队列或双端队列进行操作. LinkedList 实现 ...
- 【ATcoder s8pc_3 F】 寿司
http://s8pc-3.contest.atcoder.jp/tasks/s8pc_3_f (题目链接) 题意 有一个长度为$N$的数列$A$,初始为$0$.$Q$次操作,每次两个参数$x,y$. ...
- 利用NEST2.0 在C#中操作Elasticsearch
前言:本文主要演示了如何通过c#来操作elasticsearch,分两个方面来演示: 索引数据 搜索数据 Note: 注意我索引数据和搜索数据是两个不同的例子,没有前后依赖关系 准备工作:需要在vis ...
- 【POJ3613】Cow Relays 离散化+倍增+矩阵乘法
题目大意:给定一个 N 个顶点,M 条边的无向图,求从起点到终点恰好经过 K 个点的最短路. 题解:设 \(d[1][i][j]\) 表示恰好经过一条边 i,j 两点的最短路,那么有 \(d[r+m] ...
- Flash与JavaScript互动
最近做的一个项目需要用javascript来实现自动复制文本到剪切板,但测试时发现只有ie6.0支持. 到百度搜索后才发现,原来ie7.0.firefox是不支持这样的操作的,随后又搜索了一下,找到一 ...
- git branch 分支管理
在多人协作的情况下,master通常是稳定的分支.可以再建一些"develop","testing"等名称的分支.主管master的人做开发的话最好也建立自己的 ...