天天看點

ESP32 FreeRTOS-任務優先級(3)ESP32-FreeRTOS序列:前言:一、擷取任務優先級二、設定任務優先級三、綜合示例

提示:好記性不如爛筆頭。本部落格作為學習筆記,有錯誤的地方希望指正

ESP32-FreeRTOS序列:

ESP32 FreeRTOS-任務的建立與删除 (1)

ESP32 FreeRTOS-任務輸入參數(2)

ESP32 FreeRTOS-任務優先級(3)

ESP32 FreeRTOS-調試任務實用工具(4)

文章目錄

  • ESP32-FreeRTOS序列:
  • 前言:
  • 一、擷取任務優先級
  • 二、設定任務優先級
  • 三、綜合示例

前言:

  參考資料: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

  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

  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
}

           

繼續閱讀