ESP32 FreeRTOS-任务优先级(3)

提示:好记性不如烂笔头。本博客作为学习笔记,有错误的地方希望指正

ESP32-FreeRTOS序列:

ESP32 FreeRTOS-任务的创建与删除 (1)
ESP32 FreeRTOS-任务输入参数(2)
ESP32 FreeRTOS-任务优先级(3)
ESP32 FreeRTOS-调试任务实用工具(4)

前言:

  参考资料:FreeRTOS API参考
  第一篇的时候我们介绍了任务的创建,第二篇的时候我们讲述了创建任务的时候可以给任务传入一些参数,这篇我们继续来对创建任务函数中的参数分析,这里主要讲述的是任务优先级。
xTaskCreate API原型:

BaseType_t xTaskCreate(    TaskFunction_t pvTaskCode,
                            const char * const pcName,
                            configSTACK_DEPTH_TYPE usStackDepth,
                            void *pvParameters,
                            UBaseType_t uxPriority,
                            TaskHandle_t *pxCreatedTask
                          );

  在往里面找我们找到typedef unsigned int UBaseType_t;这样任务优先级的参数类型,是一个整形的数据类型。对于freeRTOS的任务优先级和UCOSII他们的有些不一样,FreeRTOS的任务优先级的最大数从0-(configMAX_PRIORITIES - 1),FreeRTOS中优先级的数值越大,即优先级别越大,ucos操作系统中任务的优先级数字越小,优先级越大。这个configMAX_PRIORITIES的值是在FreeRTOSConfig.h文件中有配置,最大值ESP32中默认为25,最大值根据用户需求可以自行设置。
  此外一个任务的优先级我们可以通过API来获取它当前的优先级,还可以设置它的优先级。

一、获取任务优先级

获取任务优先级API

UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );

  INCLUDE_uxTaskPriorityGet必须定义为1,才能使该函数可用。更多信息请参见RTOS配置文档。获取任意任务的优先级。
参数:
  xTask要查询的任务句柄。传递NULL句柄会导致返回调用任务的优先级。
返回:
  xTask的优先级。
使用示例:

void vAFunction( void )
 {
    
    
 TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to obtain the priority of the created task.
     // It was created with tskIDLE_PRIORITY, but may have changed
     // it itself.
     if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
     {
    
    
         // The task has changed its priority.
     }

     // ...

     // Is our priority higher than the created task?
     if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
     {
    
    
         // Our priority (obtained using NULL handle) is higher.
     }
 }

二、设置任务优先级

设置任务优先级 API

void vTaskPrioritySet( TaskHandle_t xTask,UBaseType_t uxNewPriority );

  INCLUDE_vTaskPrioritySet必须定义为1,才能使该函数可用。更多信息请参见RTOS配置文档。设置任意任务的优先级。
  如果所设置的优先级高于当前正在执行的任务,则在函数返回之前将发生上下文切换。
参数:
  xTask正在设置优先级的任务句柄。NULL句柄设置调用任务的优先级。uxNewPriority任务要设置的优先级。
  优先级被断言小于configMAX_PRIORITIES。如果configASSERT未定义,优先级将静默地封顶为(configMAX_PRIORITIES - 1)。
使用示例

 void vAFunction( void )
 {
    
    
 TaskHandle_t xHandle;
     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
     // ...
     // Use the handle to raise the priority of the created task.
     vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 )
     // ...
     // Use a NULL handle to raise our priority to the same value.
     vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
 }

三、综合示例

  我的这个示例中没有开启宏定义的时候APP_task_One默认的优先级是3。

  • 不开启动宏定义时,APP_task_Two的也是3,这个时候两个任务是按照时间片来执行的,谁先创建就先执行谁,不开启宏定义的时候就是APP_task_Two先执行,因它在先创建。
  • 开启APP_task_One_Priorty_Two宏定义的时候就是先执行APP_task_Two,因为此时它的任务优先级的数值(3>2)
  • 当开启APP_task_One_Priorty_Four的时候就是先执行APP_task_One,这个时候APP_task_One 的优先级的数值比APP_task_Two高(4>3);
  • 当开启APP_task_Six_Set_Priorty的时候,默认APP_task_One的优先级和APP_task_Two一样,但是APP_task_Two先创建,即它先执行,执行3s以后我们设置了APP_task_One的优先级为6,(6>3),即后面都是APP_task_One的优先级大于APP_task_Two的优先级,后面就会先执行APP_task_One的任务。
/**
 * @file 3_TaskPriority.c
 * @author WSP
 * @brief 
 * @version 0.1
 * @date 2022-10-06
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#include "System_Include.h"

const static char * TAG = "Task_Parameter";
//  APP_task 任务的一些变量
TaskHandle_t APP_task_One_handle = NULL;
TaskHandle_t APP_task_Two_handle = NULL;

// 根据宏定义来修改测试代码中不同部分
#define APP_task_Six_Set_Priorty    1

/**
 * @brief APP_task
 * @param arg 任务传入的参数
 * @return NULL
 */
void APP_task_One(void * arg)
{
    
    
    while (1){
    
    
        vTaskDelay(1000/portTICK_PERIOD_MS);
        ESP_LOGI(TAG,"APP_task_One");
    }
}
/**
 * @brief APP_task
 * @param arg 任务传入的参数
 * @return NULL
 */
void APP_task_Two(void *arg)
{
    
    
    while (1){
    
    
        vTaskDelay(1000/portTICK_PERIOD_MS);
        ESP_LOGI(TAG,"APP_task_Two");
    }
}
/**
 * @brief   创建函数初始化
 * @param   NULL
 * @return  NULL
 */
void Priority_Task_Init(void)
{
    
    
    // 创建任务二
    xTaskCreate(APP_task_Two,               // 创建任务
                "APP_task_Two",             // 创建任务名
                2048,                       // 任务堆栈
                NULL,                       // 任务参数
                3 ,                         // 任务优先级
                &APP_task_Two_handle);      // 任务句柄

    // 创建任务一
    xTaskCreate(APP_task_One,               // 创建任务
                "APP_task_One",             // 创建任务名
                2048,                       // 任务堆栈
                NULL,
            #if APP_task_One_Priorty_Two    // 任务优先级 2 低优先级,高优先级先执行(数值越大优先级越高)
                2,                         
            #elif APP_task_One_Priorty_Four // 任务优先级 4 低优先级,高优先级先执行(数值越大优先级越高)
                4,  
            #else
                3,                          // 默认3   两个任务一样的优先级 谁先创建谁先输出 按照时间片刻来执行                
            #endif
                &APP_task_One_handle);      // 任务句柄 

    vTaskDelay(3000/portTICK_PERIOD_MS);    // 延时等待
    ESP_LOGI(TAG,"APP_task_Two priorty:%d",uxTaskPriorityGet(APP_task_One_handle));
#if APP_task_Six_Set_Priorty                // 设置任务优先级   
    vTaskPrioritySet(APP_task_One_handle,6);// 设置任务优先级    
    ESP_LOGI(TAG,"APP_task_Two priorty:%d",uxTaskPriorityGet(APP_task_One_handle));
#endif
}

猜你喜欢

转载自blog.csdn.net/believe666/article/details/127189433
今日推荐