内存管理二
内存管理应用实例
本实例介绍FreeRTOS内存管理中heap_4方法的内存申请和释放函数的使用,并观察申请和释放过程中内存大小的变化情况
使用STM32CubeMX将FreeRTOS移植到工程中,创建一个任务,分别使用按键控制内存的申请、释放、使用和查询剩余空闲堆空间
- Malloc_Task:用于完成内存的申请、释放、使用以及查询剩余空闲堆空间功能
1. STM32CubeMX设置
- RCC设置外接HSE,时钟设置为72M
- PA0设置为GPIO输入模式、下拉模式;PE2/PE3/PE4设置为GPIO输入模式、上拉模式
- USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位;
- 激活FreeRTOS,添加任务,设置任务名称、优先级、堆栈大小、函数名称等参数
- 使用默认的heap_4内存分配方法
- 使用FreeRTOS操作系统,建议将HAL库的Timebase Source从SysTick改为其他定时器,选好定时器后,系统会自动配置TIM
- 输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码
2. MDK-ARM软件编程
- 创建按键驱动文件key.c和key.h,参考按键输入例程
- 添加Malloc_Task任务函数代码
void Malloc_Task(void const * argument){
uint8_t *buf;
uint8_t i,key;
uint32_t freemem;
printf("Toal Heap Size: %d bytes\r\n",configTOTAL_HEAP_SIZE);
for(;;){
key = KEY_Scan(0);
switch(key){
case KEY_UP_PRES:
buf = pvPortMalloc(30);
printf("KEY_UP_PRES------Address of Malloced Memory: %#x\r\n",(int)buf);
break;
case KEY_DOWN_PRES:
if(buf != NULL)
vPortFree(buf);
printf("KEY_DOWN_PRES----Memory of buf was freed\r\n");
buf = NULL;
break;
case KEY_LEFT_PRES:
printf("KEY_LEFT_PRES----");
if(buf != NULL){
i++;
sprintf((char*)buf,"The Malloced Buf was used %d times",i);
printf("%s\r\n",buf);
}
else
printf("Buf Memory was not malloced\r\n");
break;
case KEY_RIGHT_PRES:
freemem = xPortGetFreeHeapSize();
printf("KEY_RIGHT_PRES---Free Size of Heap: %d\r\n",freemem);
break;
}
osDelay(10);
}
}
3. 下载验证
编译无误下载到开发板后,打开串口调试助手后,打印出内存堆总的大小为3073字节,可见与STM32CubeMX中的设置的内存堆大小一致
- 按下KEY_RIGHT按键,查询到此时剩余的内存堆大小为2448字节
由于前面已经创建了一些用户任务和系统任务,所以被用掉一部分内存
- 按下KEY_UP按键,申请30个字节的内存,并打印出申请到的内存首地址
- 按下KEY_RIGHT按键,查询到此时剩余的内存堆大小为2408字节
申请了30个字节内存,但是查询显示内存堆被用掉40字节(2448-2408),是由于加上了结构体BlockLink_t的大小然后做8字节对齐后导致的
- 按下KEY_LEFT按键3次,打印出内存空间被使用3次
- 按下KEY_DOWN按键,释放内存
- 按下KEY_RIGHT按键,此时剩余的内存堆大小为2448字节,说明内存释放成功
- 按下KEY_LEFT按键,由于此时内存已经被释放,无法使用buf内存空间
注意: 内存申请和释放是要成对出现的,在一段内存没有被释放之前不能再次为其分配内存,否则容易出现内存泄漏现象
本例中,连续申请5次内存后,显示剩余内存为2248字节;之后连续5次释放内存,显示剩余内存为2288字节,也就是实际上只释放了一次内存。这就是内存泄漏,泄漏了160个字节的内存
关注我的公众号,在公众号里发如下消息,即可获取相应的工程源代码:
FreeRTOS内存管理实例