这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STM32F103ZET6】14:实测STM32F1的任务的挂起与恢复功能

共1条 1/1 1 跳转至

【STM32F103ZET6】14:实测STM32F1的任务的挂起与恢复功能

高工
2025-11-17 20:05:33     打赏

在上一篇的帖子中,介绍了任务的挂起与恢复函数,今天和大家实际分享一下具体的实现过程。

基本思路:在LED的闪烁任务中,添加对串口1任务的挂起与恢复,通过串口工具监测串口任务执行的时间,直观的了解任务的挂起与恢复过程。

挂起状态与阻塞状态的区别:

阻塞(Blocked): 任务在等待一个事件(如延时、信号量、队列等),事件发生后会自动切换到就绪状态。有时间限制。

挂起(Suspended): 任务无限期地休眠,只能通过明确的 vTaskResume() 调用才能唤醒。不消耗任何CPU时间,也不等待任何事件。

一:添加串口1的输出任务:

首先使能单片机串口1的基本参数:

14-1.png

使用cube MX配置串口输出详细过程:请移步:NUCLEO-U083RC学习历程2-串口输出测试-电子产品世界论坛

二:在RTOS中,添加串口1的输出任务:

2.1  配置参数如下所示:

14-2.png

这里串口的任务是第四个任务,可以配置不同的优先级别,不过这里只是为了直观的看到测试现象,不进行修改也是可以的。

三:代码的编写:

1.函数 vTaskSuspend()  任务的挂起 

此函数用于挂起任务,若使用此函数,需要在FreeRTOSConfigh 文件中将宏INCLUDE vTaskSuspend 配置为1。无论优先级如何,被挂起的任务都将不再被执行,直到任务被恢复。此函数并不支持嵌套,不论使用此函数重复挂起任务多少次,只需调用一次恢复任务的函数,那么任务就不再被挂起。函数原型如下所示:

void vTaskSuspend( TaskHandle_t xTaskToSuspend )

当然也需要我们使能该函数的功能:

#define INCLUDE_vTaskSuspend                 1
#ifndef INCLUDE_vTaskSuspend
	#define INCLUDE_vTaskSuspend 0
#endif

特点:将一个任务置于“休眠”状态。被挂起的任务,无论其优先级高低,都不会被调度器执行。

  它不会消耗任何CPU时间。

  挂起操作可以任务自己挂起自己,或者被其他任务/中断服务程序挂起。

  挂起是累积的,即调用 vTaskSuspend() 多少次,就需要调用 vTaskResume() 多少次才能唤醒(除非使xTaskResumeFromISR,但通常不累积)。

2.函数 vTaskResume()

此函数用于在任务中恢复被挂起的任务,若使用此函数,需要在 FreeRTOSConfig.h 文件中将宏 INCLUDE vTaskSuspend 配置为 1。不论一个任务被函数 vTaskSuspendO)挂起多少次,只需要使用函数 vTakResumeO)恢复一次,就可以继续运行。函数原型如下所示:

	void vTaskResume( TaskHandle_t xTaskToResume )

当然也需要我们使能该函数的功能:

将一个被挂起的任务唤醒,使其重新进入就绪状态。

如果被恢复的任务在所有就绪任务中拥有最高优先级,它将会立即运行。

3.创建串口的输出任务:

osThreadId usart1sendTaskHandle;
  /* definition and creation of usart1sendTask */
  osThreadDef(usart1sendTask, StartTask04, osPriorityLow, 0, 128);
  usart1sendTaskHandle = osThreadCreate(osThread(usart1sendTask), NULL);

串口1的输出任务:

void StartTask04(void const * argument)
{
  /* USER CODE BEGIN StartTask04 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1000);
		HAL_UART_Transmit(&huart1,outbuffer,sizeof (outbuffer),100);
  }
  /* USER CODE END StartTask04 */
}

4.在LED灯任务中,挂起与恢复串口的任务:

void StartTask02(void const * argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(500);
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
		
		usart1count++ ;
		if(usart1count >=10) usart1count = 0 ;
		if(usart1count >=5) vTaskSuspend(usart1sendTaskHandle);
		else vTaskResume(usart1sendTaskHandle);
  }
  /* USER CODE END StartTask02 */
}

五:实际测试图片如下所示:

14-3.png

可以,在LED闪烁3S内恢复串口输出的任务,2S内挂起串口的输出任务。基本的功能,验证完毕。

使用时候的注意事项:

并不是所用的任务,都可以被挂起的;例如不要挂起空闲任务(Idle Task),因为FreeRTOS需要它来清理内存。

不同的任务恢复,调用的函数不一样。谨慎使用挂起功能,特别是从中断服务程序中恢复任务时,要使用 xTaskResumeFromISR()。




关键词: STM32F103ZET6     任务     恢复     挂起    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]