十二、FreeRTOS之FreeRTOS任务相关API函数

本节需要掌握以下内容:

1FreeRTOS任务相关API函数介绍(熟悉)

2,任务状态查询API函数实验(掌握)

3,任务时间统计API函数实验(掌握)

4,总结

一、FreeRTOS任务相关API函数介绍(熟悉)

函数

描述

uxTaskPriorityGet()

获取任务优先级

vTaskPrioritySet()

设置任务优先级

uxTaskGetNumberOfTasks()

获取系统中任务的数量

uxTaskGetSystemState()

获取所有任务状态信息

vTaskGetInfo()

获取指定单个的任务信息

xTaskGetCurrentTaskHandle()

获取当前任务的任务句柄

xTaskGetHandle()

根据任务名获取该任务的任务句柄

uxTaskGetStackHighWaterMark()

获取任务的任务栈历史剩余最小值

eTaskGetState()

获取任务状态

vTaskList()

以“表格”形式获取所有任务的信息

vTaskGetRunTimeStats()

获取任务的运行时间

学习资料可参考手册FreeRTOS开发指南11——FreeRTOS其他任务API函数”

 1.1 获取任务优先级函数

UBaseType_t  uxTaskPriorityGet(  const TaskHandle_t xTask  )

此函数用于获取指定任务的任务优先级,使用该函数需将宏 INCLUDE_uxTaskPriorityGet  

形参

描述

       xTask

要查找的任务句柄,NULL代表任务自身

返回值

描述

整数

任务优先级数值

 1.2 设置任务优先级函数

void vTaskPrioritySet( TaskHandle_t xTask , UBaseType_t uxNewPriority )

此函数用于改变某个任务的任务优先级,使用该函数需将宏 INCLUDE_vTaskPrioritySet  1

形参

描述

                     xTask

任务句柄,NULL代表任务自身

uxNewPriority

需要设置的任务优先级

 1.3 获取系统中任务的数量函数

UBaseType_t uxTaskGetNumberOfTasks( void )

此函数用于获取系统中任务的任务数量

返回值

描述

                      整型

系统中任务的数量         

1.4 获取所有任务状态信息

UBaseType_t  uxTaskGetSystemState(   TaskStatus_t * const pxTaskStatusArray,

                            const UBaseType_t uxArraySize,

                            configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime  )

 此函数用于获取系统中所有任务的任务状态信息,使用该函数需将宏 configUSE_TRACE_FACILITY 1

形参

描述

xTaskStatusArray

指向TaskStatus_t 结构体数组首地址

uxArraySize

接收信息的数组大小

pulTotalRunTime

系统总运行时间,为NULL 则省略总运行时间值

返回值

描述

             整型

获取信息的任务数量

 TaskStatus_t 类型定义如下:

typedef struct xTASK_STATUS

{

    TaskHandle_t   xHandle;                         /* 任务句柄 */

    const char *    pcTaskName;                       /* 任务名 */

    UBaseType_t  xTaskNumber;                       /* 任务编号 */

    eTaskState e  CurrentState;                      /* 任务状态 */

    UBaseType_t   uxCurrentPriority;                 /* 任务优先级 */

    UBaseType_t   uxBasePriority;                   /* 任务原始优先级*/

    configRUN_TIME_COUNTER_TYPE   ulRunTimeCounter;   /* 任务运行时间*/

    StackType_t *   pxStackBase;                      /* 任务栈基地址 */

    configSTACK_DEPTH_TYPE   usStackHighWaterMark;    /* 任务栈历史剩余最小值 */

} TaskStatus_t;

 1.5 获取指定单个的任务信息

void vTaskGetInfo(   TaskHandle_t   xTask,
                                 
TaskStatus_t *   pxTaskStatus,
                                 
BaseType_t   xGetFreeStackSpace,
                                 
eTaskState   eState  ) 

此函数用于获取指定的单个任务的状态信息,使用该函数需将宏 configUSE_TRACE_FACILITY  1

形参

描述

xTask

指定获取信息的任务的句柄

pxTaskStatus

接收任务信息的变量

xGetFreeStackSpace

任务栈历史剩余最小值,

当为“pdFALSE 则跳过这个步骤,

当为“pdTRUE”则检查历史剩余最小堆栈

eState

任务状态,可直接赋值,如想获取代入“eInvalid

eTaskState类型定义如下

1.6 获取当前任务的任务句柄

TaskHandle_t    xTaskGetCurrentTaskHandle( void )

返回值

描述

                      TaskHandle_t

当前任务的任务句柄

TaskHandle_t xTaskGetHandle(const char * pcNameToQuery);

1.7 根据任务名获取该任务的任务句柄

TaskHandle_t xTaskGetHandle(const char * pcNameToQuery)

此函数用于通过任务名获取任务句柄 , 使用该函数需将宏 INCLUDE_xTaskGetHandle 1

形参

描述

pcNameToQuery

                                             任务名

返回值

描述

    TaskHandle

                                 任务句柄

1.8 获取任务的任务栈历史剩余最小值

UBaseType_t    uxTaskGetStackHighWaterMark( TaskHandle_t  xTask )

此函数用于获取指定任务的任务栈历史最小剩余堆栈;

使用该函数需将宏 INCLUDE_uxTaskGetStackHighWaterMark 1

形参

描述

              xTask

                       任务句柄

返回值

描述

    UBaseType_t

                  任务栈的历史剩余最小值

1.9 获取任务状态

eTaskState    eTaskGetState(TaskHandle_t xTask)

此函数用于查询某个任务的运行状态,使用此函数需将宏 INCLUDE_eTaskGetState 1

形参

描述

              xTask

        待获取状态任务的任务句柄

返回值

描述

     eTaskState

                                任务状态

1.10 以“表格”形式获取所有任务的信息

 void   vTaskList(char * pcWriteBuffer)

此函数用于以“表格”的形式获取系统中任务的信息 ;

使用此函数需将宏 configUSE_TRACE_FACILITY configUSE_STATS_FORMATTING_FUNCTIONS 1

形参

描述

        pcWriteBuffer

        接收任务信息的缓存指针

表格如下所示:

 1.11  Void    vTaskGetRunTimeStats( char * pcWriteBuffer )

此函数用于统计任务的运行时间信息,使用此函数需将宏 configGENERATE_RUN_TIME_STAT configUSE_STATS_FORMATTING_FUNCTIONS 1

形参

描述

       pcWriteBuffer

             接收任务运行时间信息的缓存指针

 Task:任务名称

Abs Time:任务实际运行的总时间(绝对时间)

% Time:占总处理时间的百分比

 ,任务状态查询API函数实验(掌握)

2.1、实验目的:

学习 FreeRTOS 任务运行时间统计相关 API 函数的使用

2.2、实验设计:

将设计三个任务:start_tasktask1task2

三个任务的功能如下:

  • start_task:用来创建task1task2任务
  • task1:LED0500ms闪烁一次,提示程序正在运行
  • task2:用于展示任务状态信息查询相关API函数的使用

2.3 实验代码

demo.c

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );


/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************/

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();               /* 进入临界区 */
    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler );
                
    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler );
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}

/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{
    while(1)
    {
        LED0_TOGGLE();
        vTaskDelay(500);
    }
}

char task_buff[500];
/* 任务二,实现任务状态查询API函数使用 */
void task2( void * pvParameters )
{
    UBaseType_t priority_num = 0;
    UBaseType_t task_num = 0;
    UBaseType_t task_num2 = 0;
    TaskStatus_t * status_array = 0;
    TaskStatus_t * status_array2 = 0;
    TaskHandle_t task_handle = 0;
    UBaseType_t task_stack_min = 0;
    eTaskState state = 0;
    
    uint8_t i = 0;
    
    vTaskPrioritySet( task2_handler,4 );
    priority_num = uxTaskPriorityGet( NULL );
    printf("task2任务优先级为%ld\r\n",priority_num);
    
    task_num = uxTaskGetNumberOfTasks();
    printf("任务数量:%ld\r\n",task_num);/*一共有五个任务,创建任务调度器得时候还创建了空闲任务和软件定时任务*/
    
    status_array = mymalloc(SRAMIN,(sizeof(TaskStatus_t) * task_num));
    task_num2 = uxTaskGetSystemState( status_array,task_num,NULL);
    printf("任务名\t\t任务优先级\t任务编号\r\n");
    for(i = 0; i < task_num2; i++)
    {
        printf("%s\t\t%ld\t%ld\r\n",
                status_array[i].pcTaskName,
                status_array[i].uxCurrentPriority,
                status_array[i].xTaskNumber);
    }/*任务编号就是第几个创建的*/
    
    status_array2 = mymalloc(SRAMIN,sizeof(TaskStatus_t));
    vTaskGetInfo( task2_handler,status_array2,pdTRUE,eInvalid);
    printf("任务名:%s\r\n",status_array2->pcTaskName);
    printf("任务优先级:%ld\r\n",status_array2->uxCurrentPriority);
    printf("任务编号:%ld\r\n",status_array2->xTaskNumber);
    printf("任务状态:%d\r\n",status_array2->eCurrentState);
    
    task_handle = xTaskGetHandle( "task1" );
    printf("任务句柄:%#x\r\n",(int)task_handle);
    printf("task1的任务句柄:%#x\r\n",(int)task1_handler);
    
    state = eTaskGetState( task2_handler );
    printf("当前task2的任务状态为:%d\r\n",state);
    
    vTaskList( task_buff );
    printf("%s\r\n",task_buff);
    while(1) 
    {
        task_stack_min = uxTaskGetStackHighWaterMark( task2_handler );
        printf("task2历史剩余最小堆栈为%ld\r\n",task_stack_min);
        vTaskDelay(1000);
    }
}

三,任务时间统计API函数实验(掌握)

3.1、实验目的:

学习 FreeRTOS 任务运行时间统计相关 API 函数的使用

3.2、实验设计:

将设计三个任务:start_tasktask1task2

三个任务的功能如下:

  • start_task:用来创建task1task2任务
  • task1:LED0500ms闪烁一次,提示程序正在运行
  • task2:用于展示任务运行时间统计相关API函数的使用

3.3 时间统计API函数使用流程

1、将宏 configGENERATE_RUN_TIME_STATS 1

2、将宏 configUSE_STATS_FORMATTING_FUNCTIONS  1

3、当将此宏 configGENERATE_RUN_TIME_STAT  1之后,还需要实现2个宏定义:

portCONFIGURE_TIMER_FOR_RUNTIME_STATE() :用于初始化用于配置任务运行时间统计的时基定时器;

注意:这个时基定时器的计时精度需高于系统时钟节拍精度的10100

portGET_RUN_TIME_COUNTER_VALUE():用于获取该功能时基硬件定时器计数的计数值 。

下面是官网说明,不知道为什么官网上说配配置3个宏,少配了这个宏configUSE_STATS_FORMATTING_FUNCTIONS ,如果不置1,会报错,默认情况是1。

3.4 实验代码

时基定时器的实现:

uint32_t FreeRTOSRunTimeTicks;
/* 时基定时器的初始化 */
void ConfigureTimeForRunTimeStats(void)
{
    btim_timx_int_init(10-1, 90-1);  /* 100倍的系统时钟节拍 10us */
    FreeRTOSRunTimeTicks = 0;		 /* 初始化里面清0,中断里面++ */
}


一定记得在.h里面声明

demo.c

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );


/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************/

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();               /* 进入临界区 */
    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler );
                
    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler );
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}

/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{
    while(1)
    {
        LED0_TOGGLE();
        vTaskDelay(500);
    }
}

char task_buff[500];
/* 任务二,实现任务运行时间统计API函数的使用 */
void task2( void * pvParameters )
{
    uint8_t key = 0;
    while(1)
    {
        key = key_scan(0);
        if(key == KEY0_PRES)
        {
            vTaskGetRunTimeStats(task_buff);
            printf("%s\r\n",task_buff);
        }
         vTaskDelay(10);/*延迟防抖一下就行了*/
    }
}

这个函数一般在调试的过程中会用到,在正式产品中一般不会出现,出厂的时候会被删除的。

四、总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

I am Supreme

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

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

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

打赏作者

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

抵扣说明:

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

余额充值