嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > FreeRTOS学习第5篇--任务优先级

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

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后续也不执行了。为此本次实验设计成功。