freertos源码解析-2内存管理

内存管理

  • freertos支持动态分配内存和静态分配内存
  • Freertos的内存分配是在portable层中实现,与内核实现分开。目录:Source/Portable/MemMang
    freertos源码解析-2内存管理_第1张图片

静态内存管理

特点

  1. 对象可以分配在特定的内存地址处;
  2. 最大内存占用可以在链接时确定,而不是运行时;
  3. 用户不需要关心内存分配失败的处理方式;
  4. 允许在不使用动态内存分配的地方使用RTOS。

定义宏 configSUPPORT_STATIC_ALLOCATION = 1 使用静态内存分配。既可以使用以下函数,里面使用的内存分配是静态内存分配方式。
freertos源码解析-2内存管理_第2张图片

动态内存管理

大多数使用freertos的场合,还是使用的动态内存分配。freertos提供了五种动态内存分配方法。如第一张图所示。
动态分配RTOS对象的特点:

  1. 最大可能减少系统使用的最大RAM;
  2. 当创建object时需要更少的函数参数;
  3. 内存再RTOS的API函数函数中自动分配;
  4. 应用程序不需要关心内存分配本身;
  5. RTOS内存分配API函数,会返回heap的使用信息,使得用户可以优化heap的使用;
  6. 内存分配的方法有多种方式,可以适应于不同的应用场合。

内核对象内存分配,分配的内存来自:special freertos heap。即ucHeap[ configTOTAL_HEAP_SIZE ]也就是说,freertos运行起来后,里面动态分配的内存都是在ucheap中分配。栈也是从ucheap分配的

五种动态内存分配方法

  • Heap1:适用于一旦创建好,就不需要删除的应用。(区别于静态分配)(自从freertos支持静态内存分配后,heap1分配方法很少被使用)
  • Heap2:分配内存采用best fit算法;内存可以释放,但是不会被合并。
  • Heap3:封装C标准的malloc函数和free函数,实现线程安全。使用条件:需要linker建立堆,编译器库实现malloc和free;不是确定性的;会增加RTOS内核的体积。
  • Heap4:分配内存采用first fit策略(即选择第一个满足分配要求的内存块),释放内存后,相邻内存会被合并。所有内存块被按照地址从低到高保存在链表中,相邻内存块如果地址连续,则可以合并。
  • Heap5:分配和释放策略类似于heap4。heap5同时允许使用多个非连续的内存区块作为系统的内存。
    使用vPortDefineHeapRegions()函数初始化;创建任何对象都会调用pvPortMalloc(0函数,在此之前必须调用vPortDefineHeapRegions()函数初始化初始化。vPortDefineHeapRegions()函数参数是一个HeapRegion结构体的数组,
const HeapRegion_t xHeapRegions[] =
{
    { ( uint8_t * ) 0x80000000UL, 0x10000 },
    { ( uint8_t * ) 0x90000000UL, 0xa0000 },
    { NULL, 0 } /* Terminates the array. */
};//各地址片段必须按顺序放置在数组中

Freertos操作系统是个大程序,那么这个程序运行过程中需要堆和栈。堆用于保存TCB或者队列、信号量等内核结构变量。栈用于保存每个任务的运行环境和过程变量or局部变量。于是在freertos编译的时候,定义了一个大的数组,ucHeap[ configTOTAL_HEAP_SIZE ]。

freertos源码解析-2内存管理_第3张图片整个ucheap是一个大数组,heap本来是堆的意思,但是这里可以说是堆,也可以说不是,自己灵活变通理解。每个任务函数需要用到的栈从这个heap中分配;内核控制变量:TCB和队列、信号量等也从heap中分配,都是使用pvPortMalloc()函数。
The xPortGetFreeHeapSize()可以返回剩余的heap空间大小;但是不能提供碎片信息。

参考资料

《Mastering the FreeRTOS™ Real Time Kernel》
《cortex M3 权威指南》
《freertos 开发手册》
freertos

公众号:嵌入式软件和硬件
在这里插入图片描述

你可能感兴趣的:(freertos)