🚀 优质资源分享 🚀
学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
🧡 Python实战微信订餐小程序 🧡 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
💛Python量化交易实战💛 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
目录* 前言
- 8.1 C标准库的内存管理
- 8.2 freertos内存管理接口
- 8.3 freertos五种内存管理
- 8.4 heap5内存管理实现细节
前言
本章主要讲解内部存储空间(RAM)的管理。
详细分析heap5方案。
参考:
8.1 C标准库的内存管理
C标准库的内存管理用到的API是malloc()
和free()
,但是不建议在RTOS中直接调用,因为:
- C标准库的内存管理实现可能比较大,不适合小型嵌入式RAM不足的设备。
- 可能会产生内存碎片,对于安全性要求高的嵌入式设备不适合。
- 这两个函数会使得链接器配置得复杂。
- 待补充。
8.2 freertos内存管理接口
freertos的内存管理和内核实现是相互独立的,内核规定内存管理接口,而接口内容却是可由外部自由实现。
但是freertos官方也提供了几种内存分配算法:heap1、heap2、heap3、heap4、heap5。
所以,需要内存管理的有合适的算法可以单独使用freertos提供内存分配算法到自己的设备或系统中。
内存堆大小由宏configTOTAL_HEAP_SIZE
决定。(heap3方案除外)
/*
* Map to the memory management routines required for the port.
*/
void * pvPortMalloc( size\_t xSize ) PRIVILEGED\_FUNCTION; //内存申请函数
void vPortFree( void * pv ) PRIVILEGED\_FUNCTION; //内存释放函数
void vPortInitialiseBlocks( void ) PRIVILEGED\_FUNCTION; //初始化内存堆函数
size\_t xPortGetFreeHeapSize( void ) PRIVILEGED\_FUNCTION; //获取当前未分配的内存堆大小
size\_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED\_FUNCTION; //获取未分配的内存堆历史最小值
8.3 freertos五种内存管理
简单介绍。
8.3.1 heap1
特点:
- 只能申请不能释放。
- 不会产生内存碎片。
- 函数的执行时间是确定的。因为可直接查到空闲空间地址和大小。
应用:这种方案一般用在安全性要求较高的系统中。用于从不删除任务、队列、信号量、互斥量等的应用程序。
实现:
使用xNextFreeByte
来定位下一个空闲的内存堆位置。
因为freertos系统堆是一个大数组,所以,内存空间是连续的。
所以xNextFreeByte
值在heap1方案中实际保存的是已经被分配的内存大小,下次申请时跳过这些已申请的,剩下就是空闲空间。
pucAlignedHeap
是一个指向对齐后的内存堆起始地址。
用户提供的系统堆内存的起始地址不一定是对齐的内存地址,需要纠正,纠正后的系统堆内存起始地址保存在pucAlignedHeap
。
static size\_t xNextFreeByte = ( size\_t ) 0;
static uint8\_t *pucAlignedHeap = NULL;
API注意:
vPortInitialiseBlocks()
仅仅将静态局部变量xNextFreeByte
设置为0,表示内存没有被申请。xPortGetFreeHeapSize()
并不是释放内存,因为heap1方案不支持释放,所以该API是获取当前未分配的内存堆大小。
8.3.2 heap2
特点:
- 支持动态申请和释放。
- 链表管理,但是不支持拼接相邻空闲块。所以容易产生内存碎片。
- 申请时间具有不确定性,因为检索空闲块需要检索链表,空闲块多、内存碎片多时,检索会久点。但是效率比标准C库中的malloc函数高得多。
应用:不建议用于内存分配和释放是随机大小的应用程序。
实现:
heap2方案的内存管理链表:
typedef struct A\_BLOCK\_LINK {
struct A\_BLOCK\_LINK *pxNextFreeBlock;
size\_t xBlockSize;
} BlockLink\_t;
pxNextFreeBlock
:是指向下一个空闲内存块的指针。
xBlockSize
:记录当前内存块大小。(内存管理函链表结构体)
8.3.3 heap3
特点:
- 需要链接器设置一个堆,malloc()和free()函数由编译器提供。
- 具有不确定性。
- 很可能增大RTOS内核的代码大小。
configTOTAL_HEAP_SIZE
不起作用,因为堆空间由编译器决定提供的。一般在启动文件里设置。
实现:
heap3方案只是简单的封装了标准C库中的malloc()和free()函数。
重新封装后的malloc()和free()函数具有保护功能,采用的封装方式是操作内存前挂起调度器、完成后再恢复调度器。
8.3.4 heap4
和heap2方案类似,且支持相邻空闲块拼接,降低内存块碎片化几率。
特点:
- 支持动态申请和释放。
- 按地址升序,优先返回第一个满足size需求的空闲块。
- 链表管理,支持相邻空闲块拼接。
- 申请时间具有不确定性,因为检索空闲块需要检索链表,但是效率比标准C库中的malloc函数高得多。
应用:
- 可用于重复删除任务、队列、信号量、互斥量等的应用程序。
- 可用于分配和释放随机字节内存的应用程序。
8.3.5 heap5
heap_5.c方案在实现动态内存分配时与heap4.c方案一样&#x