
复习回顾欢迎友友指正一起进步~#RTOS内存管理介绍RTOS学习中通常会使用这些对象 任务(task) 队列(queue) 信号量(semaphores) 事件( event group)这些对象定义地时候在内存 中通常是动态分配内存使用分配不用释放也就是通过堆来申请内存或者释放内存这样做有一个好处简化了程序设计不需要提前在代码里静态定义一大堆全局结构体 / 数组不用预先预估最大资源数量。。动态分配内存是C语言中的知识但是与RTOS联系紧密相关函数有 mallc(申请内存) free(释放内存)但是这些函数在RTOS系统里面并不适用原因是嵌入式系统资源紧缺函数定义实现过于复杂代码占用空间太大。因为上述的缺点在RTOS中并不使用mallc free对堆进行分配和释放而是通过 pvPortMalloc vPortFree 这两个函数进行内存的分配与释放pvPortMalloc对堆的内存进行分配 vPortFree 进行释放堆的内存。——最关键是标准malloc/free没有锁保护。如果两个任务同时调用 malloc会破坏内存链表 → 堆损坏、随机死机。 RTOS 多任务并发环境不加锁绝对不能直接用标准 malloc。pvPortMalloc内部会自动关中断 / 加临界区保护。pvPortMalloc对应着C语言中的mallc vPortFree对应着C语言中的free函数也就是平替。堆栈的前置概念Cortex-M里链接https://blog.csdn.net/m0_56944463/article/details/167692566?fromshareblogdetailsharetypeblogdetailsharerId167692566sharereferPCsharesourcem0_56944463sharefromfrom_link参考韦东山的讲解Heap_1精简总结heap_2就是不能合并空间嘛4就是比2多了能合并空闲空间5又比4多了可以把不连续的内存把它们拼成一个虚拟堆来用。一般是用4。即使现在芯片有多块SRAM的情况但是他们的物理地址是连续的所以4也够用。首次自适应算法假设堆中有3块空闲内存5字节、200字节、100字节pvPortMalloc想申请20字节找出第1个能满足pvPortMalloc的内存200字节把它划分为20字节、180字节返回这20字节的地址剩下的180字节仍然是空闲状态留给后续的pvPortMalloc使用Heap_4的使用过程举例如下A创建了3个任务B删除了一个任务空闲内存有2部分顶层的被删除任务的TCB空间、被删除任务的Stack空间合并起来的C分配了一个Queue从第1个空闲块中分配空间D分配了一个User数据从Queue之后的空闲块中分配E释放的QueueUser前后都有一块空闲内存F释放了User数据User前后的内存、User本身占据的内存合并为一个大的空闲内存针对heap4最能缓解碎片问题——内存池预分配固定大小块heap_4在频繁创建/删除任务时会逐渐累积内存碎片和分配时间不确定这两个核心问题。碎片化问题但若分配和释放的大小不一长时间运行后空闲内存会被分割成许多不连续的小块即“伪碎片”可能因为无法找到一块足够大的连续内存而导致任务创建失败。非确定性分配时间heap_4的分配操作需要遍历空闲链表来寻找合适的内存块其最坏执行时间是O(n)即可能扫描几乎整个链表。对于硬实时系统这种时间抖动是不可接受的因为它会破坏任务的确定性响应。内存池或称固定大小块分配器的核心思想是用空间换确定性预先分配一大块连续内存并将其划分为固定大小的块通过一个空闲链表Free List来管理。1、彻底消除外部碎片由于所有块大小完全相同任何被释放的块都可以被后续的分配请求完美重用。不会产生无法利用的小空闲块从根本上消除了外部碎片。2、保证 O(1) 的分配/释放时间分配时只需从空闲链表头部取出一个块并更新头指针释放时只需将块重新挂回链表头部。整个过程仅涉及几次指针操作没有任何搜索或合并动。欢迎友友指正有输出一起进步~