本文由嵌入式企鹅圈原创团队成员朱衡德(Hunter_Zhu)供稿.
近几年来,FreeRTOS在嵌入式操作系统排行榜中一直位居前列,作为开源的嵌入式操作系统之一,它支持许多不同架构的处理器以及多种编译工具链,具有轻量级、容易移植和使用的特点。本篇文章将会对FreeRTOS提供的几种内存分配策略进行介绍,FreeRTOS允许开发者根据自己的项目实际需要选择不同的内存分配策略或者自定义分配内存策略。
一、FreeRTOS内存分配源码
FreeRTOS在创建任务、队列、互斥量、信号量、软件定时以及事件组的时候需要从RAM中分配内存,源码目录:FreeRTOSv9.0.0\FreeRTOS\Source\portable\MemMang下提供了5中内存分配机制的实现,本文将会讲解heap1.c, heap2.c, heap4.c三种。
二、配置FreeRTOS内存大小
在FreeRTOSConfig.h头文件中宏configTOTAL_HEAP_SIZE用于配置内核可用的RAM大小:
在heap1.c, heap2.c, heap3.c源文件中,分配的内存实际上是用一个静态数组ucHeap来表示:
在MDK编译后生成的.map文件里面可以查看ucHeap符号信息:
ucHeap属于RW数据,在RAM中运行时的地址是0x20002788,大小是前面分配的20*1024字节。
三、heap1.c内存分配机制
heap1.c是FreeRTOS提供的多种内存分配策略中最简单的一种,其使用一个全局静态变量xNextFreeByte来记录未分配使用的内存空间的位置,每分配一次就会往后进行偏移。另外,在这种方式中,已经分配的内存不会再释放。
3.1void *pvPortMalloc(size_t xWantedSize)
应用程序调用此函数请求分配内存,需要注意的是函数中有两个地方为满足字节对齐的要求进行调整(cortex-m3为例,8字节对齐):
1)为确保从静态数组ucHeap中分配给应用程序的内存块是8字节对齐,函数会判断xWantedSize是否为8的倍数,如果不是,就会添补字节,因此有时候分配到的内存比实际请求的内存还要多;
2)确保从静态数组ucHeap中第一个8字节对齐的地方开始进行内存分配,用静态变量pucAlignedHeap记录首次对齐的地址作为有效空间的首地址;
内存分配示意图:
上图中可以看到ucHeap前面和后面都有因字节对齐而丢弃的空间,所丢弃的空间大小要求的字节对齐数,对于cortex-m3系列是8,实际有效的分配空间为:
即ucHeap数组实际大小减去字节对齐数。
3.2void vPortFree( void *pv )
在这种分配策略中,对于已经分配的内存不进行释放。
前面主要主要介绍了heap1.c中内存分配的策略,也提到了内存分配过程中字节对齐,在heap2.c和heap4.c中字节对齐的操作和heap1.c中一样。对于heap2.c和heap4.c的内存分配原理会在下篇”轻量级操作系统FreeRTOS的内存管理机制(二)”中进行讲解。