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)队列可以保存有限个具有确定长度的数据单元,队列可以保存的最大单元数目 ...
随机推荐
- [hgoi#2019/2/18]比较水
T1--调换纸牌(card) Alex有 n张纸牌,每张纸牌上都有一个值ai,Alex把这些纸牌排成一排,希望将纸牌按值从小到大的顺序排好.现在他把这个任务交给你,你只能进行一种操作:选中一张牌,然后 ...
- FinalHttp的简要介绍与使用
http://blog.csdn.net/zhaokaiqiang1992/article/details/30291259?utm_source=tuicool 在之前的一篇文章中,我们简单的介绍了 ...
- 百度地图API 循环向 marker 添加 click事件
使用百度地图API,循环向marker添加InfoWindow时,所有的marker点击弹出的inforwindow为最后一个添加的infowindow,百度后,使用js闭包解决此问题,直接贴代码: ...
- c语言输入字符注意
1.c=getchar(); //getchar can't accept Space Tab 2. scanf("%c",&c); printf(" ...
- apache 基本vhost配置 【目的及过程】
转: apache 基本vhost配置 2012年04月18日 09:39:28 chamtianjiao 阅读数:74075 经常使用Apache虚拟主机进行开发和测试,但每次需要配置虚拟主 ...
- Harbor之Swagger REST API
目录 Swagger介绍 Harbor Swagger预览 整合本地Harbor与Swagger Swagger介绍 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTFu ...
- 函数和常用模块【day04】:递归(五)
本节内容 作用域.局部和全局变量 递归 函数式编程 高阶函数和eval()函数 一.概述 在函数内部,可以调用其他函数.但是一个函数在内部调用自身,这个函数被称为递归函数. 二.简单介绍 那递归具体是 ...
- docker基础篇
下载,安装 安装Windows社区版 官网地址:https://store.docker.com/editions/community/docker-ce-desktop-windows?tab=de ...
- java通过当前请求得到访问者ip的工具类
在我们开发的过程中,也许有下面的这样的需求,就是要记录一下每次访问服务器的ip,需要存到数据库,以便以后进行数据分析等... 下面给大家介绍一个通过当前请求得到访问者ip的工具类 IpUtil.jav ...
- 绕过/*,web.xml直接访问jsp【转】
web.xml中如果配置了/* 全匹配,那么不能用servet去响应页面返回了,因为全都被会/*拦截. <servlet> <servlet-name>validateAuth ...