目录
- FreeRTOS学习第5篇--任务优先级
- 任务优先级
- 设计实验
- 任务一StartDefaultTask任务相关代码片段
- 任务二ColorLED_Test任务相关代码片段
- 任务三IRReceiver_Task相关代码片段
- 实验现象
- 本文中使用的测试工程
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