方案:
heap1.c 方案具有以下特点:
1、 用于从不删除任务、队列、信号量、互斥量等的应用程序(实际上大多数使用FreeRTOS的应用程序都符合这个条件)。
2、 函数的执行时间是确定的并且不会产生内存碎片。heap_1.c 管理方案使用两个静态变量对系统管理的内存进行跟踪内存分配。
heap1.c 方案具有以下特点:
1、 用于从不删除任务、队列、信号量、互斥量等的应用程序(实际上大多数使用FreeRTOS的应用程序都符合这个条件)。
2、 函数的执行时间是确定的并且不会产生内存碎片。heap_1.c 管理方案使用两个静态变量对系统管理的内存进行跟踪内存分配。
heap_3.c 方案具有以下特点:
1、 需要链接器设置一个堆,malloc()和 free()函数由编译器提供。
2、 具有不确定性。
3、 很可能增大 RTOS内核的代码大小。
heap_3.c 方案只是简单的封装了标准 C 库中的 malloc()和 free()函数,并且能满足常用的编译器。重新封装后的 malloc()和 free()函数具有保护功能,采用的封装方式是操作内存前挂起调度器、完成后再恢复调度器。要 注 意 的 是 在 使 用 heap_3.c 方 案 时 ,FreeRTOSConfig.h 文 件 中 的configTOTAL_HEAP_SIZE 宏定义不起作用。在 STM32 系列的工程中,这个由编译器定义的堆都在启动文件里面设置。
heap_4.c 方案具有以下特点:
1、可用于重复删除任务、队列、信号量、互斥量等的应用程序
2、可用于分配和释放随机字节内存的应用程序,但并不像 heap2.c 那样产生严重的内存碎片。
3、具有不确定性,但是效率比标准 C库中的 malloc 函数高得多。
heap_5.c 方案
在实现动态内存分配时与 heap4.c 方案一样,采用最佳匹配算法和合并算法,并且允许内存堆跨越多个非连续的内存区,也就是允许在不连续的内存堆中实现内存分配,比如用户在片内 RAM 中定义一个内存堆,还可以在外部 SDRAM 再定义一个或多个内存堆,这些内存都归系统管理。
推荐使用heap_4.c、heap_5.c
API函数
1、内存申请函数:pvPortMalloc()
void *pvPortMalloc( size_t xWantedSize );
2、内存释放函数:vPortFree()
void vPortFree( void *pv );
3、获取当前内存剩余大小函数:单位字节
size_t xPortGetFreeHeapSize( void );
伪代码:
uint8_t *Test_Ptr = NULL;
static void Test_Task(void* parameter)
{
uint32_t g_memsize;
while (1) {
if ( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON ) {
/* KEY1 被按下 */
if (NULL == Test_Ptr) {
/* 获取当前内存大小 */
g_memsize = xPortGetFreeHeapSize();
printf(" 系统当前内存大小为 %d 字节 , 开始申请内存\n",g_memsize);
Test_Ptr = pvPortMalloc(1024);
if (NULL != Test_Ptr) {
printf(" 内存申请成功!\n");
printf(" 申请到的内存地址为%#x\n",(int)Test_Ptr);
/* 获取当前内剩余存大小 */
g_memsize = xPortGetFreeHeapSize();
printf(" 系统当前内存剩余存大小为 %d 字节!\n",g_memsize);
//向 向 Test_Ptr 中写入当数据: 当前系统时间
sprintf((char*)Test_Ptr," 当前系统 TickCount = %d
\n",xTaskGetTickCount());
printf(" 写入的数据是 %s \n",(char*)Test_Ptr);
}
} else {
printf(" 请先按下 KEY2 释放内存再申请\n");
}
}
if ( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON ) {
/* KEY2 被按下 */
if (NULL != Test_Ptr) {
printf(" 释放内存!\n");
vPortFree(Test_Ptr); // 释放内存
Test_Ptr=NULL;
/* 获取当前内剩余存大小 */
g_memsize = xPortGetFreeHeapSize();
printf(" 系统当前内存大小为 %d 字节 , 内存释放完成\n",g_memsize);
} else {
printf(" 请先按下 KEY1 申请内存再释放\n");
}
注:本文章取至野火[野火®]《FreeRTOS 内核实现与应用开发实战—基于STM32》内存管理