Error in suspendtask

Hi guys, I’m trying to implement a menu using freertos. There are 7 screens showing tasks in total, and when switching menus all tasks are suspended first and then one task is resumed. When I create a task, I can hang all the tasks without any problem, but when I switch, the task cannot be hung without any problem. Here is my code and debugging result.

void appStartTask(void){
	 queueKeyHandle = xQueueCreate(2,sizeof(uint8_t));
	 smaMutexHandle = xSemaphoreCreateMutex();
	
	 tmrSingleHandler = xTimerCreate("singleTimer",
	                                 6000,
	                                 pdFALSE,
																	 (void *) 1,
																		singleTimerCallBack
	                                 );
																	 
	 tmrCycleHandler = xTimerCreate("cycleTimer",
	                                 500,
	                                 pdTRUE,
																	 (void *) 2,
																		cycleTimerCallBack
	                                 );
	 taskENTER_CRITICAL();
	 xTaskCreate(keyTask,         /*任务函数*/
							"keyTask",        /*任务名*/
							256,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							1,                /*任务优先级,越小越高*/
							&keyTaskHandle);  /*任务句柄*/
 	 xTaskCreate(walkTask,        /*任务函数*/
							"walkTask",       /*任务名*/
							256,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							4,                /*任务优先级,越小越高*/
							&walkTaskHandle); /*任务句柄*/
	 xTaskCreate(timeCheckTask,   /*任务函数*/
							"timeCheckTask",  /*任务名*/
							512,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&timeCheckTaskHandle); /*任务句柄*/
	 xTaskCreate(MainMenuTask,    /*任务函数*/
							"MainMenu",       /*任务名*/
							512,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&mainMenuTaskHandle); /*任务句柄*/	
   xTaskCreate(timeSetTask,     /*任务函数*/
							"timeSetTask",    /*任务名*/
							512,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&timeSetTaskHandle); /*任务句柄*/
   xTaskCreate(alarmSetTask,    /*任务函数*/
							"alarmSetTask",   /*任务名*/
							512,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&alarmSetTaskHandle); /*任务句柄*/	
   xTaskCreate(secondTask,      /*任务函数*/
							"secondTask",     /*任务名*/
							512,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&secondTaskHandle); /*任务句柄*/	
   xTaskCreate(alarmDispTask,    /*任务函数*/
							"alarmDispTask",  /*任务名*/
							256,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&alarmDispTaskHandle); /*任务句柄*/								
	 xTaskCreate(heartTask,        /*任务函数*/
							"heartMesu",      /*任务名*/
							512,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&heartTaskHandle); /*任务句柄*/
   xTaskCreate(stepTask,        /*任务函数*/
							"stepTask",       /*任务名*/
							256,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&stepTaskHandle); /*任务句柄*/	
   xTaskCreate(infoMenuTask,    /*任务函数*/
							"infoMenuTask",     /*任务名*/
							512,              /*任务堆栈大小,单位为word,128word = 4B*/
							NULL,             /*任务参数*/
							3,                /*任务优先级,越小越高*/
							&infoTaskHandle); /*任务句柄*/								
	taskEXIT_CRITICAL();
	suspendScreen();
	vTaskResume(mainMenuTaskHandle);
 }
 static void keyTask(void * pvParameters){
	 keyvalue ucKeyValue;
	 while(1){
		  printf("key task\n");
			ucKeyValue = KeyScan();
		  if(ucKeyValue == PWRLong){
					suspendScreen();
					LCD_Clear(WHITE);
					pageNum = pageNone;
			}
			if(ucKeyValue == MODEDown){
				  printf("mode down\n");
					suspendScreen();
				  if(++pageNum > TOTAL_PAGE) pageNum = pageNone;
				  printf("key task end\n");
				  resumeScreen(pageNum);
			}
			if(ucKeyValue != 0){
					xQueueSendToBack(queueKeyHandle, &ucKeyValue, 100);
				  xTimerStart(tmrSingleHandler, 10); 
			}
			vTaskDelay(pdMS_TO_TICKS(100));                     /*延时500MS*/
	 }
 }
 static void suspendScreen(void){
	  printf("suspendall\n");
	  
	  vTaskSuspend(mainMenuTaskHandle);
	  printf("suspend1\n");
	  vTaskSuspend(timeSetTaskHandle);
	  printf("suspend2\n");
	  vTaskSuspend(infoTaskHandle);
	  printf("suspend3\n");
	  vTaskSuspend(secondTaskHandle);
	  printf("suspend4\n");
	  vTaskSuspend(heartTaskHandle);
	  printf("suspend5\n");
	  vTaskSuspend(alarmSetTaskHandle);
	  printf("suspend6\n");
	  vTaskSuspend(stepTaskHandle);
	  
	  printf("suspend ok\n");
	 
	  HAL_GPIO_WritePin(led0_GPIO_Port, led0_Pin, GPIO_PIN_RESET);
	  HAL_GPIO_WritePin(led1_GPIO_Port, led1_Pin, GPIO_PIN_RESET);
 }

this is debugging result

First you should check the return codes of xTaskCreate etc.
(BTW you don’t need to enclose task creation by a critical section in case you think you have to.)
Did you defined configASSERT and enabled stack checking ?
Maybe the stack of the key task or other tasks overflows and corrupts some data causing wrong application behavior or a crash.
But more important don’t use task suspend/resume for task synchronization. They are not really designed for this purpose. They are working asynchronously and e.g. might stop a task right in the middle of any operation currently in progress. This usually causes problems besides other issues.
It’s common practice to tell tasks that there is something to do and the tasks process incoming events (like START/STOP) when appropriate using task notifications, semaphores or queues etc. which ARE designed for task synchronization purposes.
I’d propose to rethink your design and get rid of hard-to-get-right task suspend/resume.

As @hs2 pointed out, use of suspend/resume is a architecture/design smell. If you describe the problem that you are trying to solve, we may be able to suggest other solutions.

If you are convinced that it is the right design for your case, would you please elaborate the problem you are facing - what are you observing and what do you expect?

First of all, thank you for your valuable advice, it’s very helpful and as a newbie I will learn the sync method you suggested, but first I’m about to double check my stack usage.
As for the effect I want, when I press modedown, my display tasks will all be suspended, and then resumed with a display task I want. But as you can see, after I press the button, the program stays at vTaskSuspend(infoTaskHandle); it doesn’t printf any more.

Can you break it in debugger and see what it is doing when it appears hang?

Ok, thanks for the heads up. I did a test and suspended all the display tasks twice in a row after creating all the tasks, then breakpoint debugging and found that the program finally stopped at taskSELECT_HIGHEST_PRIORITY_TASK() in vTaskSuspend(heartTaskHandle);, as shown below.

Thank you, my enthusiastic friends. I have determined that it was a problem with my memory allocation, thank you both for your valuable advice.

Thank you for reporting back.