內存管理實驗使用 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...\n"); /* 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\n",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\n",g_memsize); Test_Ptr = pvPortMalloc(1024); if (NULL != Test_Ptr) { printf("Memory application successful! \n"); printf("The requested memory address is %#x\n",(int)Test_Ptr); /* 獲取當前內剩余存大小 */ g_memsize = xPortGetFreeHeapSize(); printf("System current memory remaining memory size is %ld bytes! \n",g_memsize); //向 Test_Ptr 中寫入當數據:當前系統時間 sprintf((char*)Test_Ptr,"The current system TickCount = %ld\n",xTaskGetTickCount()); printf("The written data is %s \n",(char*)Test_Ptr); } } else { printf("Press KEY2 to free memory before applying\n"); } } } 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 \n"); vPortFree(Test_Ptr); //釋放內存 Test_Ptr=NULL; /* 獲取當前內剩余存大小 */ g_memsize = xPortGetFreeHeapSize(); printf("System current memory size is %ld bytes, memory release is complete\n",g_memsize); } else { printf("Please press KEY1 to apply for memory release\n"); } } } osDelay(10); } /* USER CODE END StartTestTask */ }
修改完畢后點擊 小錘子 構建工程,然后點擊Debug,按如下步驟配置ITM調試
全速運行之前一定要先點擊SWV ITM data Console 頁面中的紅色圓圈
現象: