内存管理实验使用 heap_4.c 方案进行内存管理测试, 创建了两个任务,分别是 Default任务与内存管理测试任务,内存管理测试任务通过检测按键是否按下来申请内存或释放内存,当申请内存成功就像该内存写入一些数据,如当前系统的时间等信息,并且通过串口输出相关信息; Default 任务是定时输出系统时间信息,表示系统处于运行状态。在不需要再使用内存时,注意要及时释放该段内存,避免内存泄露。
创建工程RTOS_Heap4,
配置HCLK,使用内部晶振,频率为180MHZ(根据板子设置)
将SYS中时基源(Timebase Source)改为除SysTick之外的任意定时器即可,如:
配置板载的按键KEY1和KEY2
配置FreeRTOS,使用CMSIS_V1,内存分配策略使用heap_4.c
定义两个任务,DefaultTask和TestTask
Ctrl + S生成代码
修改代码,
1,在main.h中添加
/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stdio.h" /* USER CODE END Includes */
2,在mian.c中添加
/* USER CODE BEGIN PV */ uint8_t *Test_Ptr = NULL; /* USER CODE END PV */ ... ... ... /* USER CODE BEGIN PFP */ int _write(int file , char *ptr,int len) { int i = 0; for(i = 0;i<len;i++) ITM_SendChar((*ptr++)); return len; } /* USER CODE END PFP */ ... ... ... /* USER CODE BEGIN 2 */ printf("starting... "); /* USER CODE END 2 */
3,在main.c中修改2个任务入口函数的内容
/* USER CODE BEGIN Header_StartDefaultTask */ /** * @brief Function implementing the defaultTask thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void const * argument) { /* USER CODE BEGIN 5 */ /* Infinite loop */ for(;;) { printf("Current system clock is %ld ",xTaskGetTickCount()); osDelay(1000); } /* USER CODE END 5 */ }
/* USER CODE BEGIN Header_StartTestTask */ /** * @brief Function implementing the TestTask thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_StartTestTask */ void StartTestTask(void const * argument) { /* USER CODE BEGIN StartTestTask */ uint32_t g_memsize; /* Infinite loop */ for(;;) { if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1) { osDelay(5); if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1) { while(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1); /* KEY1 被按下 */ if (NULL == Test_Ptr) { /* 获取当前内存大小 */ g_memsize = xPortGetFreeHeapSize(); printf("System current memory size is %ld bytes, start applying for memory ",g_memsize); Test_Ptr = pvPortMalloc(1024); if (NULL != Test_Ptr) { printf("Memory application successful! "); printf("The requested memory address is %#x ",(int)Test_Ptr); /* 获取当前内剩余存大小 */ g_memsize = xPortGetFreeHeapSize(); printf("System current memory remaining memory size is %ld bytes! ",g_memsize); //向 Test_Ptr 中写入当数据:当前系统时间 sprintf((char*)Test_Ptr,"The current system TickCount = %ld ",xTaskGetTickCount()); printf("The written data is %s ",(char*)Test_Ptr); } } else { printf("Press KEY2 to free memory before applying "); } } } if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1) { osDelay(5); if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1) { while(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1); /* KEY2 被按下 */ if (NULL != Test_Ptr) { printf("free the memory "); vPortFree(Test_Ptr); //释放内存 Test_Ptr=NULL; /* 获取当前内剩余存大小 */ g_memsize = xPortGetFreeHeapSize(); printf("System current memory size is %ld bytes, memory release is complete ",g_memsize); } else { printf("Please press KEY1 to apply for memory release "); } } } osDelay(10); } /* USER CODE END StartTestTask */ }
修改完毕后点击 小锤子 构建工程,然后点击Debug,按如下步骤配置ITM调试
全速运行之前一定要先点击SWV ITM data Console 页面中的红色圆圈
现象: