FreeRTOS学习第5篇--任务优先级

发布时间:2023年12月29日

FreeRTOS学习第5篇–任务优先级

本文目标:学习与使用FreeRTOS中的任务优先级。

按照本文的描述,应该可以跑通实验并举一反三。

本文实验条件:拥有C语言基础,装有编译和集成的开发环境,比如:Keil uVision5

任务优先级

每个任务都有一个优先级,用来决定哪些任务可以被执行。在FreeRTOS中任务优先级数值越小,任务优先级越低。不过有时也记不住,直接看封装层的信息比较好,在文件cmsis_os2.h中定义了相关的优先级,看英文意思就是越往后优先级就越高的。

/// Priority values.
typedef enum {
  osPriorityNone          =  0,         ///< No priority (not initialized).
  osPriorityIdle          =  1,         ///< Reserved for Idle thread.
  osPriorityLow           =  8,         ///< Priority: low
  osPriorityLow1          =  8+1,       ///< Priority: low + 1
  osPriorityLow2          =  8+2,       ///< Priority: low + 2
  osPriorityLow3          =  8+3,       ///< Priority: low + 3
  osPriorityLow4          =  8+4,       ///< Priority: low + 4
  osPriorityLow5          =  8+5,       ///< Priority: low + 5
  osPriorityLow6          =  8+6,       ///< Priority: low + 6
  osPriorityLow7          =  8+7,       ///< Priority: low + 7
  osPriorityBelowNormal   = 16,         ///< Priority: below normal
  osPriorityBelowNormal1  = 16+1,       ///< Priority: below normal + 1
  osPriorityBelowNormal2  = 16+2,       ///< Priority: below normal + 2
  osPriorityBelowNormal3  = 16+3,       ///< Priority: below normal + 3
  osPriorityBelowNormal4  = 16+4,       ///< Priority: below normal + 4
  osPriorityBelowNormal5  = 16+5,       ///< Priority: below normal + 5
  osPriorityBelowNormal6  = 16+6,       ///< Priority: below normal + 6
  osPriorityBelowNormal7  = 16+7,       ///< Priority: below normal + 7
  osPriorityNormal        = 24,         ///< Priority: normal
  osPriorityNormal1       = 24+1,       ///< Priority: normal + 1
  osPriorityNormal2       = 24+2,       ///< Priority: normal + 2
  osPriorityNormal3       = 24+3,       ///< Priority: normal + 3
  osPriorityNormal4       = 24+4,       ///< Priority: normal + 4
  osPriorityNormal5       = 24+5,       ///< Priority: normal + 5
  osPriorityNormal6       = 24+6,       ///< Priority: normal + 6
  osPriorityNormal7       = 24+7,       ///< Priority: normal + 7
  osPriorityAboveNormal   = 32,         ///< Priority: above normal
  osPriorityAboveNormal1  = 32+1,       ///< Priority: above normal + 1
  osPriorityAboveNormal2  = 32+2,       ///< Priority: above normal + 2
  osPriorityAboveNormal3  = 32+3,       ///< Priority: above normal + 3
  osPriorityAboveNormal4  = 32+4,       ///< Priority: above normal + 4
  osPriorityAboveNormal5  = 32+5,       ///< Priority: above normal + 5
  osPriorityAboveNormal6  = 32+6,       ///< Priority: above normal + 6
  osPriorityAboveNormal7  = 32+7,       ///< Priority: above normal + 7
  osPriorityHigh          = 40,         ///< Priority: high
  osPriorityHigh1         = 40+1,       ///< Priority: high + 1
  osPriorityHigh2         = 40+2,       ///< Priority: high + 2
  osPriorityHigh3         = 40+3,       ///< Priority: high + 3
  osPriorityHigh4         = 40+4,       ///< Priority: high + 4
  osPriorityHigh5         = 40+5,       ///< Priority: high + 5
  osPriorityHigh6         = 40+6,       ///< Priority: high + 6
  osPriorityHigh7         = 40+7,       ///< Priority: high + 7
  osPriorityRealtime      = 48,         ///< Priority: realtime
  osPriorityRealtime1     = 48+1,       ///< Priority: realtime + 1
  osPriorityRealtime2     = 48+2,       ///< Priority: realtime + 2
  osPriorityRealtime3     = 48+3,       ///< Priority: realtime + 3
  osPriorityRealtime4     = 48+4,       ///< Priority: realtime + 4
  osPriorityRealtime5     = 48+5,       ///< Priority: realtime + 5
  osPriorityRealtime6     = 48+6,       ///< Priority: realtime + 6
  osPriorityRealtime7     = 48+7,       ///< Priority: realtime + 7
  osPriorityISR           = 56,         ///< Reserved for ISR deferred thread.
  osPriorityError         = -1,         ///< System cannot determine priority or illegal priority.
  osPriorityReserved      = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
} osPriority_t;

FreeRTOS 中任务的最高优先级是通过 FreeRTOSConfig.h 文件中的 configMAX_PRIORITIES 进行

配置的,用户实际可以使用的优先级范围是 0 到 configMAX_PRIORITIES – 1。这是我工程中优先级的宏定义,用户可以使用的优先级号是 0,1,2,3,4 …55,不包含 55

在这里插入图片描述

设计实验

基于以上信息的了解,我在我的硬件操作平台来设计一些实验来看一下相关的实验现象,创建3个优先级相同的任务,过一段时间后,我在我其中一个任务中设置一个更高的优先级,直接霸占cpu资源,让另两个任务没办法继续执行。基于这个设想,下面是相关代码片段。

任务一StartDefaultTask任务相关代码片段

osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {
		HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
		HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
		HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);
	  mdelay(100);
  }
  /* USER CODE END StartDefaultTask */
}
/* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

任务二ColorLED_Test任务相关代码片段

static StackType_t g_pucStackOfColorTask[75];
static StaticTask_t g_TCBofColorTask;
static TaskHandle_t xColorTaskHandle;
void ColorLED_Test(void * pvParameters)
{
    uint32_t color = 0;

    ColorLED_Init();

    while (1)
    {
        //LCD_PrintString(0, 0, "Show Color: ");
        //LCD_PrintHex(0, 2, color, 1);
        
        ColorLED_Set(color);

        color += 200000;
        color &= 0x00ffffff;
        mdelay(1000);
    }    
}
/* 创建任务: 色 */
  xColorTaskHandle = xTaskCreateStatic(ColorLED_Test, "ColorTask", 75, NULL, osPriorityNormal, g_pucStackOfColorTask, &g_TCBofColorTask);

任务三IRReceiver_Task相关代码片段

void IRReceiver_Task(void * pvParameters)
{
    uint8_t dev, data;
		OLED_Init();
    IRReceiver_Init();

		while(1)
		{
			OLED_ShowString(0,0,"IR Receiver: ",16);
			OLED_ShowString(0,16,"Device  Data",16);
			if (!IRReceiver_Read(&dev, &data))
			{
					OLED_ShowString(0, 32, "                ",16);
					OLED_ShowNum(0,32,dev,4,16);
					OLED_ShowNum(64,32,data,4,16);
					OLED_ShowString(0, 48, "                ",16);
					OLED_ShowString(0,48,"Key name: ",16);
					OLED_ShowString(80,48,(u8 *)IRReceiver_CodeToString(data),16);
				    // 某个按键值
					if(data == 48)
					{
						// 设置优先级
						vTaskPrioritySet(defaultTaskHandle, osPriorityAboveNormal2);
					}
					// 某个按键 
					if(data == 24)
					{
						// 设置优先级
						vTaskPrioritySet(xColorTaskHandle, osPriorityAboveNormal1);
					}
					
			}
			OLED_Refresh(); // 刷新屏幕
		}

}
xTaskCreate( IRReceiver_Task, "IRReceiver_Task", configMINIMAL_STACK_SIZE, NULL, osPriorityNormal, NULL );

其中要使用vTaskPrioritySet的函数,则需要在配置文件中配置相应的宏,默认是打开的。

在这里插入图片描述

实验现象

下载代码到板子上,一开始时,这三个任务的优先级都是osPriorityNormal级别的,都在按部就班的运行各自的功能函数,但是当我在IRReceiver_Task任务中按下相应的按键时,把对应的优先级任务提高之后,这三个任务中就只有一个高优先级的任务在执行了,直接霸占了cpu资源,让另两个任务都没法得到执行,连IRReceiver_Task后续也不执行了。为此本次实验设计成功。

本文中使用的测试工程

https://download.csdn.net/download/weixin_44317448/88666471

文章来源:https://blog.csdn.net/weixin_44317448/article/details/135232244
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。