FreeRTOS其他任务API函数(STM32F103C8T6任务优先级堆栈历史最小值,运行时间等)

本文详细介绍了FreeRTOS中的关键任务管理函数,如获取任务优先级、状态、栈信息、任务列表等,并提醒读者注意配置选项和内存管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.函数 uxTaskPriorityGet() 

       此函数用于获取指定任务的任务优先级,若使用此函数,需在 FreeRTOSConfig.h 文件中设 置配置项 INCLUDE_uxTaskPriorityGet 为 1,此函数的函数原型如下所示:

2.函数 vTaskPrioritySet()

        此函数用于设置指定任务的优先级,若使用此函数,需在 FreeRTOSConfig.h 文件中设置配 置项 INCLUDE_vTaskPrioritySet 为 1,此函数的函数原型如下所示:

3.函数 uxTaskGetSystemState()

       此函数用于获取所有任务的状态信息,若使用此函数,需在 FreeRTOSConfig.h 文件中设置 配置项 configUSE_TRACE_FACILITY 为 1,此函数的函数原型如下所示:

        函数 uxTaskGetSystemState()的形参 pxTaskStatusArray 指向变量类型为 TaskStatus_t 的变量 的首地址,可以是一个数组,用来存放多个TaskStatus_t类型的变量,函数 uxTaskGetSystemState() 使用将任务的状态信息,写入到该数组中,形参 uxArraySize 指示该数组的大小,其中变量类型 TaskStatus_t 的定义如下所示:

       该结构体变量就包含了任务的一些状态信息,获取到的每个任务都有与之对应的 TaskStatus_t 结构体来保存该任务的状态信息。

4.函数 vTaskGetInfo()

       此函数用于获取指定任务的任务信息,若使用此函数,需在 FreeRTOSConfig.h 文件中设置 配置项 configUSE_TRACE_FACILITY 为 1,此函数的函数原型如下所示:

       函数 vTaskGetInfo()的形参描述,如下表所示:

       函数 vTaskGetInfo()无返回值。 函数 vTaskGetInfo()的形参 eState 用来表示任务的状态,其变量类型为 eTaskState,变量类 型 eTaskState 的定义如下所示:

       形参 eState 用于决定形参 pxTaskStatus 结构体中成员变量 eCurrentState 的值,表示任务的 状态,如果传入的 eState 为 eInvalid,那么 eCurrentState 为任务当前的状态,否则 eCurrentState 为 eState。

5.函数 xTaskGetApplicationTaskTag()

       此函数用于获取指定任务的 Tag,若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置 项 configUSE_APPLICATION_TASK_TAG 为 1,此函数的函数原型如下所示:

6.函数 xTaskGetCurrentHandle()

此函数用于获取当前 系统正在运行的 任务的任务句柄, 若使用此函数,需 在 FreeRTOSConfig.h 文件中设置配置项 INCLUDE_xTaskGetCurrentTaskHandle 为 1,此函数的函 数原型如下所示:

7.函数 xTaskGetHandle()

此函数用于通过任务名获取任务句柄,若使用此函数,需在 FreeRTOSConfig.h 文件中设置 配置项 INCLUDE_xTaskGetHandle 为 1,此函数的函数原型如下所示:

8.函数 xTaskGetIdleTaskHandle()

       此函数用于获取空闲任务的任务句柄,若使用此函数,需在 FreeRTOSConfig.h 文件中设置 配置项 INCLUDE_xTaskGetIdleTaskHandle 为 1,此函数的函数原型如下所示:

9.函数 uxTaskGetStackHighWaterMark()

        此函数用于获取指定任务 的 任务栈的历史剩余最小值, 若 使用此函数 , 需 在 FreeRTOSConfig.h 文件中设置配置项 INCLUDE_uxTaskGetStackHighWaterMark 为 1,此函数的函数原型如下所示:

10.函数 eTaskGetState()

       此函数用于获取指定任务的状态,若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置 项 INCLUDE_eTaskGetState 为 1,此函数的函数原型如下所示:

11.函数 pcTaskGetName()

        此函数用于获取指定任务的任务名,此函数的函数原型如下所示:

12.函数 xTaskGetTickCount()

        此函数用于获取系统时钟节拍计数器的值,此函数的函数原型如下所示:

13.函数 xTaskGetTickCountFromISR()

       此函数用于在中断中获取系统时钟节拍计数器的值,此函数的函数原型如下所示:

14.函数 xTaskGetSchedulerState()

      此函数用于获取任务调度器的运行状态,此函数的函数原型如下所示:

15.函数 uxTaskGetNumberOfTasks()

       此函数用于获取系统中任务的数量,此函数的函数原型如下所示:

       函数 uxTaskGetNumberOfTasks()无形参。

       函数 uxTaskGetNumberOfTasks()的返回值,如下表所示:

16.函数 vTaskList()

         此函数用于以“表格”的形式获取系统中任务的信息,若使用此函数,需在 FreeRTOSConfig.h 文 件 中 同 时 设 置 配 置 项 configUSE_TRACE_FACILITY 和配置项 configUSE_STATS_FORMATTING_FUNCTIONS 为 1,此函数的函数原型如下所示:

        函数 vTaskList()无返回值。 

        函数 vTaskList()获取到的任务信息示例,如下图所示:

17.函数 vTaskGetRunTimeStats() 

          此函数用于获取指定任务的运行时间、运行状态等信息,若使用此函数,需在 FreeRTOSConfig.h 文 件 中 同 时 设 置 配 置 项 configGENERATE_RUN_TIME_STATS 、 configUSE_STATS_FORMATTING_FUNCTIONS、configSUPPORT_DYNAMIC_ALLOCATION 为 1,此函数的函数原型如下所示:  

         函数 vTaskGetRunTimeState()无返回值。

18.函数 vTaskSetApplicationTaskTag()

          此函数用于设置指定任务的 Tag,若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置 项 configUSE_APPLICATION_TASK_TAG 为 1,此函数的函数原型如下所示:

         函数 vTaskSetApplicationTaskTag()无返回值。

19.函数 SetThreadLocalStoragePointer()

        此函数用于设置指定任务的独有数据数组指针,此函数的函数原型如下所示:

20.函数  GetThreadLocalStoragePointer()

        此函数用于获取指定任务的独有数据数组指针,此函数的函数原型如下所示:

1.API程序示例:
        主要还是在之前MPU6050的例程程序基础上做了一下以上函数的验证。总体还是比较好用的,主要注意一下两点:
        1.以上API函数在使用时,需要确认下在 FreeRTOSConfig.h中进行配置,否则编译无法通过。
        2.内存配置和释放的两个函数:pvPortMalloc()和vPortFree()需要配对使用。之前就是用了free()来释放直接宕机了。
        以下是FreeRTOSConfig.h的配置:

以下是程序源码解析,后续使用只要参考以下函数直接运用即可:

void api_task(void *pvParameters)
{
     uint32_t i                  = 0;
     UBaseType_t task_num        = 0;
     TaskStatus_t *status_array  = NULL;
     TaskHandle_t task_handle    = NULL;
     TaskStatus_t *task_info     = NULL;
     eTaskState   task_state     = eInvalid;
     char *task_state_str        = NULL;
     char *task_info_buf         = NULL;
    
     printf("\r\n");
     printf("/*------函数uxTaskGetSystemState()的使用------*/");
    
     task_num = uxTaskGetNumberOfTasks();
     status_array = pvPortMalloc(task_num * sizeof(TaskStatus_t));
    
     task_num = uxTaskGetSystemState((TaskStatus_t *)status_array, (UBaseType_t)task_num, (uint32_t *)NULL);
        
     printf("\r\n任务名\t\优先级\t\t任务编号\r\n");
    
     for(i = 0; i < task_num; i++)
     {
         printf("%s\t%s%ld\t\t%ld\r\n",
                        status_array[i].pcTaskName,
                        strlen(status_array[i].pcTaskName) > 7 ? "":"\t",
                        status_array[i].uxCurrentPriority,
                        status_array[i].xTaskNumber);
     }
     vPortFree(status_array);    
     
     printf("\r\n");
     printf("/*------函数vTaskGetInfo()的使用------*/");
     
     task_info = pvPortMalloc(sizeof(TaskStatus_t));
     task_handle = xTaskGetHandle("mpu6050_task");
     vTaskGetInfo(  (TaskHandle_t)task_handle,
                    (TaskStatus_t*)task_info,
                    (BaseType_t)pdTRUE,
                    (eTaskState)eInvalid);
     
     printf("\r\n任务名:\t\t\t%s\r\n", task_info->pcTaskName);
     printf("任务编号:\t\t%ld\r\n", task_info->xTaskNumber);
     printf("任务状态:\t\t%d\r\n", task_info->eCurrentState);
     printf("任务当前优先级:\t\t%ld\r\n", task_info->uxCurrentPriority);
     printf("任务基优先级:\t\t%ld\r\n", task_info->uxBasePriority);
     printf("任务堆栈基地址:\t\t0x%p\r\n", task_info->pxStackBase);
     printf("任务堆栈历史剩余最小值:\t%d\r\n", task_info->usStackHighWaterMark);
     
     vPortFree(task_info);
     
     printf("\r\n");
     printf("/*------函数eTaskGetState()的使用------*/\r\n");
     
     task_state_str = pvPortMalloc(10);
     task_handle = xTaskGetHandle("mpu6050_task");
     task_state  = eTaskGetState(task_handle);
     
     sprintf(task_state_str, task_state == eRunning ? "Runing" :
             task_state == eReady ? "Ready":
             task_state == eBlocked ? "Blocked":
             task_state == eSuspended ? "Suspended":
             task_state == eDeleted ? "Deleted":
             task_state == eInvalid ? "Invalid":
             "");
     printf("任务状态值:º%d, 对应状态为:%s\r\n", task_state, task_state_str);
     vPortFree(task_state_str);
     
     printf("\r\n");
     printf("/*------函数vTaskList()的使用------*/\r\n");
     
     task_info_buf = pvPortMalloc(500);
     vTaskList(task_info_buf);
     printf("任务名\t\t状态\t优先级\t剩余栈\t任务序号\r\n");
     printf("%s\r\n", task_info_buf);
     vPortFree(task_info_buf);
     
     while(1)
     {
          vTaskDelay(1000);
     }
}

 下载验证:

1.程序运行时间程序示例:
FreeRTOS 系统配置
       使用 FreeRTOS 获取系统任务运行时间信息的 API 函数,需要在 FreeRTOSConfig.h 文件中 开启相关配置,如下所示:

      

       要使用 FreeRTOS 获取系统任务运行时间信息的 API 函数,须在 FreeRTOSConfig.h 文件中 将配置项 configGENERATE_RUN_TIME_STATS 定义为 1,并且如果配置项 configGENERATE _RUN_TIME_STATS 被定义为 1,还需定义两个宏,分别为 portCONFIGURE_TIMER_FOR _RUN_TIME_STATS()、portGET_RUN_TIME_COUNTER_VALUE(),其中,宏 portCONFIGURE _TIMER_FOR_RUNTIME_STATE()用于初始化配置用于任务运行时间统计的时基定时器,因为 任务运行时间统计功能需要一个硬件定时器作为时基,这个时基定时器的计时精度需高于系统 时钟节拍 的 精 度 10 至 100 倍 数 , 这 样 统 计 的 时 间 才 会 比 较 准 确 ; 宏 portGET_RUN_TIME_COUNTER_VALUE()用于获取该功能时基硬件定时器计数的计数值。本 实验使用函数ConfigureTimeForRunTimeStats()来进行该功能时基硬件定时器的初始化配置,使 用全局变量 FreeRTOSRunTimeTicks 来传递该功能时基硬件定时器计数的计数值。

       在实际编写程序时,由于定时器的中断处理和例程有出入,所以实际的源码如下所示,为了调试方便,将函数放到了"WS2812B.h"中。

#define configGENERATE_RUN_TIME_STATS 1
#if configGENERATE_RUN_TIME_STATS
#include "WS2812B.h"
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ConfigureTimeForRunTimeStats()
extern uint32_t FreeRTOSRunTimeTicks;
#define portGET_RUN_TIME_COUNTER_VALUE() FreeRTOSRunTimeTicks

       然后,在"WS2812B.h"中定义以上函数以及FreeRTOSRunTimeTicks值。

uint32_t FreeRTOSRunTimeTicks;

void HAL_TIM_PeriodElapsedCallback(TIM_TimeBaseInitTypeDef *htim)
{
    if(htim == (&TIM3_TimeBaseStructure))
    {
       FreeRTOSRunTimeTicks++;
    }
}

void ConfigureTimeForRunTimeStats(void)
{
    FreeRTOSRunTimeTicks = 0;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    TIM3_Init(9, 719);
}

void TIM3_IRQHandler(void)
{
    if ( TIM_GetITStatus(TIM3 , TIM_IT_Update) != RESET )
    {
       TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);
       HAL_TIM_PeriodElapsedCallback(&TIM3_TimeBaseStructure);
    }
}

       最后,在main.c文件中,增加vTaskGetRunTimeStats()函数的调试即可:

       在上述例程中的while(1)中增加,按照1S的频率打印任务运行时间。

 while(1)
     {
          runtime_info = pvPortMalloc(100);
          vTaskGetRunTimeStats(runtime_info);
          
          printf("任务名\t\t运行时间\t运行所占百分比\r\n");
          printf("\r\n%s\r\n",runtime_info);
         
          vPortFree(runtime_info);
          vTaskDelay(1000);
     }

下载验证:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

moon2shine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值