FreeRTOS官方文件分析(五)API(3)-Task Utilities(任务实用程序)(1)

FreeRTOS提供了一系列的API函数,如uxTaskGetSystemState、vTaskGetInfo等,用于获取任务的系统状态、任务信息、运行时间统计、堆栈高水位线等,便于进行系统调试和性能分析。这些函数包括获取任务状态、任务句柄、堆栈使用情况和调度器状态等,但需要注意它们可能导致调度器暂停,适用于调试而非实时操作。
摘要由CSDN通过智能技术生成

官方文档

RTOS task (thread) utilities including API functions for tracing FreeRTOS, getting the RTOS tick count, getting a task handle, getting the RTOS kernel or RTOS scheduler state, listing the tasks in the embedded system, and obtaining run time task statistics.icon-default.png?t=M4ADhttps://www.freertos.org/a00021.html


目录

uxTaskGetSystemState(任务获取系统状态)

Return

Example usage

TaskStatus_t 定义

函数代码

vTaskGetInfo(任务获取lnfo)

Example usage

函数代码

xTaskGetApplicationTaskTag(任务获取应用程序任务标记)

Returns

Example usage

函数代码

xTaskGetCurrentTaskHandle(任务获取当前任务句柄)

Returns

函数代码

xTaskGetHandle(任务得到处理)

Returns

函数代码

xTaskGetldleTaskHandle(任务获取ldle任务句柄)

Returns

函数代码

uxTaskGetStackHighWaterMark(任务得到堆栈高水位线)

Returns

Example usage

函数代码

eTaskGetState(任务获取状态)

Returns

函数代码

pcTaskGetName

Returns

函数代码

xTaskGetTickCount(任务获取滴答计数)

xTaskGetTickCountFromlSR

Returns

函数代码

xTaskGetSchedulerState(任务获取调度程序状态)

Returns

函数代码


uxTaskGetSystemState(任务获取系统状态)

configUSE_TRACE_FACILITY必须定义为 1 才能使 uxTaskGetSystemState() 可用。

uxTaskGetSystemState() 为系统中的每个任务填充一个 TaskStatus_t 结构。 TaskStatus_t 结构包含任务句柄的成员、任务名称、任务优先级、任务状态和任务消耗的运行时间总量等。

注意:此函数仅用于调试用途,因为它的使用会导致调度程序长时间暂停。

//task.h
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
                                  const UBaseType_t uxArraySize,
                                  uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION;

pxTaskStatysArry指向 TaskStatus_t 结构数组的指针。对于RTOS控制下的每个任务,该数组必须至少包含一个TaskStatus_t结构。RTOS控制下的任务数量可以使用uxTaskGetNumberOfTasks() API函数确定。

uxArraySizepxTaskStatusArray 参数指向的数组的大小。大小指定为数组中的索引数(数组中包含的TaskStatus_t结构的数量数),而不是数组中的字节数。

pulTotaRunTime如果在 FreeRTOSConfig 中 configGENERATE_RUN_TIME_STATS 设置为1。那么 uxTaskGetSystemState()将 *pulTotalRunTime 设置为自目标启动以来的总运行时间(由运行时统计时钟定义)。pulTotalRunTime 可以设置为 NULL 以忽略总运行时间值。

Return

uxTaskGetSystemState() 填充的 TaskStatus_t 结构的数量。这应该等于uxTaskGetNumberOfTasks() API函数返回的数字,但如果在 UXArraySize 参数中传递的值太小,则该值将为零。

Example usage

/*此示例演示如何从uxTaskGetSystemState()提供的原始数据生成运行时统计信息的可读表。
人们可读的表格被写入pcWriteBuffer。(请参阅vTaskList()API函数,它实际上就是这样做的)*/
void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
{
TaskStatus_t *pxTaskStatusArray;
volatile UBaseType_t uxArraySize, x;
unsigned long ulTotalRunTime, ulStatsAsPercentage;

   /* 确保写入缓冲区不包含字符串。 */
   *pcWriteBuffer = 0x00;

   /* 拍摄任务数量的快照,以防在执行此函数时任务数量发生变化 */
   uxArraySize = uxTaskGetNumberOfTasks();

   /* 为每个任务分配TaskStatus_t结构。数组可以在编译时静态分配。 */
   pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );

   if( pxTaskStatusArray != NULL )
   {
      /* 生成每个任务的原始状态信息 */
      uxArraySize = uxTaskGetSystemState( pxTaskStatusArray,
                                 uxArraySize,
                                 &ulTotalRunTime );

      /* 用于百分比计算。 */
      ulTotalRunTime /= 100UL;

      /* A避免除以零错误。 */
      if( ulTotalRunTime > 0 )
      {
         /* 对于pxTaskStatusArray数组中的每个填充位置,将原始数据格式化为人类可读的ASCII数据。  */
         for( x = 0; x < uxArraySize; x++ )
         {
            /* 任务使用的运行时间占总运行时间的百分比是多少?
               这将始终向下舍入到最接近的整数。
               ulTotalRunTimeDiv100 已经被 100 除了。  */
            ulStatsAsPercentage =
                  pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;

            if( ulStatsAsPercentage > 0UL )
            {
               sprintf( pcWriteBuffer, "%stt%lutt%lu%%rn",
                                 pxTaskStatusArray[ x ].pcTaskName,
                                 pxTaskStatusArray[ x ].ulRunTimeCounter,
                                 ulStatsAsPercentage );
            }
            else
            {
               /* 如果此处的百分比为零,则任务消耗的运行时间不到总运行时间的1%。  */
               sprintf( pcWriteBuffer, "%stt%lutt<1%%rn",
                                 pxTaskStatusArray[ x ].pcTaskName,
                                 pxTaskStatusArray[ x ].ulRunTimeCounter );
            }

            pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
         }
      }

      /* 不再需要数组,释放它消耗的内存。 */
      vPortFree( pxTaskStatusArray );
   }
}

 

TaskStatus_t 定义

typedef struct xTASK_STATUS
{
   /* 与结构中的其余信息相关的任务的句柄。  */
   TaskHandle_t xHandle;

   /* 指向任务名称的指针。如果任务在结构填充后被删除,此值将无效!  */
   const signed char *pcTaskName;

   /* 任务的唯一编号。  */
   UBaseType_t xTaskNumber;

   /* 填充结构时任务存在的状态。 */
   eTaskState eCurrentState;

   /* 填充结构时任务运行的优先级(可以继承)。  */
   UBaseType_t uxCurrentPriority;

   /* 如果任务的当前优先级已被继承,则任务将返回的优先级,
      以避免在获取互斥时出现无限制的优先级反转。
      只有在 FreeRTOSConfig.h 中将 configUSE_MUTEXES 定义为1时才有效*/
   UBaseType_t uxBasePriority;

   /* 到目前为止分配给任务的总运行时间,由运行时统计时钟定义。
      仅当在 FreeRTOSConfig.h 中将 onfignate_RUN_TIME_STATS 定义为1时有效。 */
   unsigned long ulRunTimeCounter;

   /* 指向任务堆栈区域的最低地址。  */
   StackType_t *pxStackBase;

   /* 自创建任务以来,任务剩余的最小堆栈空间量。该值越接近于零,任务越容易溢出堆栈。  */
   configSTACK_DEPTH_TYPE usStackHighWaterMark;
} TaskStatus_t;

函数代码

//tasks.c
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )

    UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
                                      const UBaseType_t uxArraySize,
                                      uint32_t * const pulTotalRunTime )
    {
        UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;

        vTaskSuspendAll();
        {
            /* Is there a space in the array for each task in the system? */
            if( uxArraySize >= uxCurrentNumberOfTasks )
            {
                /* Fill in an TaskStatus_t structure with information on each
                 * task in the Ready state. */
                do
                {
                    uxQueue--;
                    uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady );
                } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */

                /* Fill in an TaskStatus_t structure with information on each
                 * task in the Blocked state. */
                uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked );
                uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked );

                #if ( INCLUDE_vTaskDelete == 1 )
                    {
                        /* Fill in an TaskStatus_t structure with information on
                         * each task that has been deleted but not yet cleaned up. */
                        uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted );
                    }
                #endif

                #if ( INCLUDE_vTaskSuspend == 1 )
                    {
                        /* Fill in an TaskStatus_t structure with information on
                         * each task in the Suspended state. */
                        uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended );
                    }
                #endif

                #if ( configGENERATE_RUN_TIME_STATS == 1 )
                    {
                        if( pulTotalRunTime != NULL )
                        {
                            #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
                                portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) );
                            #else
                                *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
                            #endif
                        }
                    }
                #else /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */
                    {
                        if( pulTotalRunTime != NULL )
                        {
                            *pulTotalRunTime = 0;
                        }
                    }
                #endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
        ( void ) xTaskResumeAll();

        return uxTask;
    }

#endif /* configUSE_TRACE_FACILITY */
/*----------------------------------------------------------*/

vTaskGetInfo(任务获取lnfo)

configUSE_TRACE_FACILITY 必须在 FreeRTOSConfig.h 中定义为 1 vTaskGetInfo() 可用。

uxTaskGetSystemState() 为系统中的每个任务填充 TaskStatus_t 结构,而 vTaskGetInfo() 只为单个任务填充 TaskStatus_t 结构。TaskStatus_t 结构包含任务句柄的成员、任务名称、任务优先级、任务状态以及任务消耗的运行时总量。

注意:此函数仅用于调试用途,因为它的使用会导致调度程序长时间暂停。

//task.h
void vTaskGetInfo( TaskHandle_t xTask,
                   TaskStatus_t * pxTaskStatus,
                   BaseType_t xGetFreeStackSpace,
                   eTaskState eState ) PRIVILEGED_FUNCTION;

xTask正在查询的任务的句柄。将 xTask 设置为 NULL 将返回调用任务的信息。

pxTaskStatuspxTaskStatus 指向的 TaskStatus_t 结构将填充有关 xTask 参数中传递的句柄引用的任务的信息。

xGetFreeStackSpaceTaskStatus_t 结构包含一个成员,用于报告所查询任务的堆栈最高水位线。堆栈高水位线是有史以来存在的最小堆栈空间量,因此数字越接近于零,任务越接近溢出堆栈。计算堆栈高水位线需要相对较长的时间,并且可能会使系统暂时无响应 —— 因此提供xGetFreeStackSpace 参数以允许跳过高水位线检查。只有在 xGetFreeStackSpace 未设置为 pdFALSE 时,高水印值才会写入 TaskStatus_t 结构。

eStateTaskStatus_t 结构包含一个成员,用于报告所查询任务的状态。由于不提供状态参数,因此不允许从任务结构中获取状态信息。要获取状态信息,请将 eState 设置为 eInvalid ,否则在 eState 中传递的值将在 TaskStatus_t 结构中报告为任务状态。

Example usage

void vAFunction( void )
{
TaskHandle_t xHandle;
TaskStatus_t xTaskDetails;

    /* 从任务名称中获取任务的句柄。 */
    xHandle = xTaskGetHandle( "Task_Name" );

    /* 检查句柄不为 NULL。 */
    configASSERT( xHandle );

    /* 使用句柄获取有关任务的更多信息。 */
    vTaskGetInfo( /* 被查询任务的句柄。 */
                  xHandle,
                  /* TaskStatus__t结构将包含xTask上的信息。 */
                  &xTaskDetails,
                  /* 在TaskStatus_t结构中包含堆栈高水位线值。*/
                  pdTRUE,
                  /* 在TaskStatus_t结构中包含任务状态。  */
                  eInvalid );
}

函数代码

//tasks.c
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )

    void vTaskGetInfo( TaskHandle_t xTask,
                       TaskStatus_t * pxTaskStatus,
                       BaseType_t xGetFreeStackSpace,
                       eTaskState eState )
    {
        TCB_t * pxTCB;

        /* xTask is NULL then get the state of the calling task. */
        pxTCB = prvGetTCBFromHandle( xTask );

        pxTaskStatus->xHandle = ( TaskHandle_t ) pxTCB;
        pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName[ 0 ] );
        pxTaskStatus->uxCurrentPriority = pxTCB->uxPriority;
        pxTaskStatus->pxStackBase = pxTCB->pxStack;
        pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber;

        #if ( configUSE_MUTEXES == 1 )
            {
                pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority;
            }
        #else
            {
                pxTaskStatus->uxBasePriority = 0;
            }
        #endif

        #if ( configGENERATE_RUN_TIME_STATS == 1 )
            {
                pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter;
            }
        #else
            {
                pxTaskStatus->ulRunTimeCounter = 0;
            }
        #endif

        /* Obtaining the task state is a little fiddly, so is only done if the
         * value of eState passed into this function is eInvalid - otherwise the
         * state is just set to whatever is passed in. */
        if( eState != eInvalid )
        {
            if( pxTCB == pxCurrentTCB )
            {
                pxTaskStatus->eCurrentState = eRunning;
            }
            else
            {
                pxTaskStatus->eCurrentState = eState;

                #if ( INCLUDE_vTaskSuspend == 1 )
                    {
                        /* If the task is in the suspended list then there is a
                         *  chance it is actually just blocked indefinitely - so really
                         *  it should be reported as being in the Blocked state. */
                        if( eState == eSuspended )
                        {
                            vTaskSuspendAll();
                            {
                                if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
                                {
                                    pxTaskStatus->eCurrentState = eBlocked;
                                }
                            }
                            ( void ) xTaskResumeAll();
                        }
                    }
                #endif /* INCLUDE_vTaskSuspend */
            }
        }
        else
        {
            pxTaskStatus->eCurrentState = eTaskGetState( pxTCB );
        }

        /* Obtaining the stack space takes some time, so the xGetFreeStackSpace
         * parameter is provided to allow it to be skipped. */
        if( xGetFreeStackSpace != pdFALSE )
        {
            #if ( portSTACK_GROWTH > 0 )
                {
                    pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxEndOfStack );
                }
            #else
                {
                    pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxStack );
                }
            #endif
        }
        else
        {
            pxTaskStatus->usStackHighWaterMark = 0;
        }
    }

#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/

xTaskGetApplicationTaskTag(任务获取应用程序任务标记)

configUSE_APPLICATION_TASK_TAG 必须定义为 1 才能使这些功能可用。

xTaskGetApplicationTaskTagFromISR() 是 xTaskGetApplicationTaskTag() 的一个版本,它可以从中断服务程序 (ISR) 中调用。

返回与任务关联的“标签”值。 标签的含义和用途 值由应用程序编写者定义。 RTOS内核本身不会正常访问标签值。

此功能仅供高级用户使用。

TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;

xTask正在查询的任务的句柄。 任务可以通过使用NULL作为参数值来查询自己的标签值。

Returns

The 'tag' value of the task being queried.    正在查询的任务的“标签”值。

Example usage

/* 在本例中,一个整数被设置为任务标记值。  */
void vATask( void *pvParameters )
{
    /* 为当前正在执行的任务分配标签值 1。
      (void*)强制转换用于防止编译器警告。  */
    vTaskSetApplicationTaskTag( NULL, ( void * ) 1 );

    for( ;; )
    {
        /* 剩下的任务代码放在这里。 */
    }
}

void vAFunction( void )
{
TaskHandle_t xHandle;
int iReturnedTaskHandle;

   /* 从vATask()函数创建一个任务,将创建的任务的句柄存储在 xTask 变量中。  */

   /* Create the task. */
   if( xTaskCreate(
             vATask,         /* 指向实现任务的函数的指针。 */
             "Demo task",    /* 为任务指定的文本名称。 */
             STACK_SIZE,     /* 应为任务创建的堆栈的大小。这是用文字定义的,而不是字节。 */
             NULL,           /* 该任务不使用该参数。  */
             TASK_PRIORITY,  /* 分配给新创建任务的优先级。  */
             &xHandle        /* 正在创建的任务的句柄将放在xHandle中。  */
             ) == pdPASS )
   {
       /* 任务已成功创建。短时间延迟以允许任务运行。  */
       vTaskDelay( 100 );

       /* 为任务分配了什么标记值?
          返回的标记值存储在整数中,因此强制转换为整数以防止编译器发出警告。 */
       iReturnedTaskHandle = ( int ) xTaskGetApplicationTaskTag( xHandle );
   }
}

函数代码

//tasks.c
/*-----------------------------------------------------------*/
#if ( configUSE_APPLICATION_TASK_TAG == 1 )

    TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask )
    {
        TCB_t * pxTCB;
        TaskHookFunction_t xReturn;

        /* If xTask is NULL then set the calling task's hook. */
        pxTCB = prvGetTCBFromHandle( xTask );

        /* Save the hook function in the TCB.  A critical section is required as
         * the value can be accessed from an interrupt. */
        taskENTER_CRITICAL();
        {
            xReturn = pxTCB->pxTaskTag;
        }
        taskEXIT_CRITICAL();

        return xReturn;
    }

#endif /* configUSE_APPLICATION_TASK_TAG */
/*-----------------------------------------------------------*/

xTaskGetCurrentTaskHandle(任务获取当前任务句柄)

INCLUDE_xTaskGetCurrentTaskHandle 必须设置为 1 才能使该函数可用。

//task.h
TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;
//返回调用任务的句柄。 

Returns

The handle of the currently running (calling) task.  当前运行(调用)任务的句柄。

函数代码

//tasks.c
/*-----------------------------------------------------------*/
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )

    TaskHandle_t xTaskGetCurrentTaskHandle( void )
    {
        TaskHandle_t xReturn;

        /* A critical section is not required as this is not called from
         * an interrupt and the current TCB will always be the same for any
         * individual execution thread. */
        xReturn = pxCurrentTCB;

        return xReturn;
    }

#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
/*-----------------------------------------------------------*/

xTaskGetHandle(任务得到处理)

INCLUDE_xTaskGetHandle 必须在 FreeRTOSConfig.h 中设置为 1 才能使 xTaskGetHandle() 可用。

从任务名称中查找任务的句柄。

注意:此功能需要相对较长的时间才能完成,并且只应 每个任务调用一次。 一旦获得了任务的句柄,就可以 存储在本地以供重复使用。

//task.h
TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION;     
/*lint !e971 Unqualified char types are allowed for strings and single characters only. */

pcNameToQuery

将为其返回句柄的任务的文本名称(作为标准的以C NULL结尾的字符串)。

有关设置任务文本名称的信息,请参阅xTaskCreate()和xTaskCreateStatic()API函数的pcName参数。

Returns

If a task that has the name passed in pcNameToQuery can be located then the handle of the task is returned, otherwise NULL is returned.  如果可以找到具有在 pcNameToQuery 中传递的名称的任务,则 返回任务的句柄,否则返回NULL。

函数代码

//tasks.c
#if ( INCLUDE_xTaskGetHandle == 1 )

    TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
    {
        UBaseType_t uxQueue = configMAX_PRIORITIES;
        TCB_t * pxTCB;

        /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */
        configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN );

        vTaskSuspendAll();
        {
            /* Search the ready lists. */
            do
            {
                uxQueue--;
                pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[ uxQueue ] ), pcNameToQuery );

                if( pxTCB != NULL )
                {
                    /* Found the handle. */
                    break;
                }
            } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */

            /* Search the delayed lists. */
            if( pxTCB == NULL )
            {
                pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList, pcNameToQuery );
            }

            if( pxTCB == NULL )
            {
                pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pcNameToQuery );
            }

            #if ( INCLUDE_vTaskSuspend == 1 )
                {
                    if( pxTCB == NULL )
                    {
                        /* Search the suspended list. */
                        pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList, pcNameToQuery );
                    }
                }
            #endif

            #if ( INCLUDE_vTaskDelete == 1 )
                {
                    if( pxTCB == NULL )
                    {
                        /* Search the deleted list. */
                        pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination, pcNameToQuery );
                    }
                }
            #endif
        }
        ( void ) xTaskResumeAll();

        return pxTCB;
    }

#endif /* INCLUDE_xTaskGetHandle */
/*-----------------------------------------------------------*/

xTaskGetldleTaskHandle(任务获取ldle任务句柄)

INCLUDE_xTaskGetIdleTaskHandle 必须设置为 1 才能使用此函数。

//task.h
TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;

Returns

The task handle associated with the Idle task. The Idle task is created automatically when the RTOS scheduler is started.

与空闲任务关联的任务句柄。 启动 RTOS 调度程序时会自动创建空闲任务。

函数代码

//tasks.c
/*----------------------------------------------------------*/
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )

    TaskHandle_t xTaskGetIdleTaskHandle( void )
    {
        /* If xTaskGetIdleTaskHandle() is called before the scheduler has been
         * started, then xIdleTaskHandle will be NULL. */
        configASSERT( ( xIdleTaskHandle != NULL ) );
        return xIdleTaskHandle;
    }

#endif /* INCLUDE_xTaskGetIdleTaskHandle */
/*----------------------------------------------------------*/

uxTaskGetStackHighWaterMark(任务得到堆栈高水位线)

INCLUDE_uxTaskGetStackHighWaterMark 必须定义为 1 才能使这些函数可用。

uxTaskGetStackHighWaterMark2() 是 uxTaskGetStackHighWaterMark() 的一个版本,它 返回用户可定义的类型,以消除 UBaseType_t 类型在 8 位架构上的数据类型宽度限制。

任务使用的堆栈会随着任务的执行和中断的处理而增长和缩小。 uxTaskGetStackHighWaterMark() 返回最小值 自任务开始执行以来可用于任务的剩余堆栈空间量 - 即未使用的堆栈量 当任务堆栈处于其最大(最深)值时。 这就是所谓的堆栈“高水位线”。

UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;

xTask正在查询的任务的句柄。任务可以通过传递NULL作为xTask参数来查询自己的高水位线。

Returns

返回的值是以字表示的高水位线(例如,在32位机器上,返回值为1表示堆栈的4个字节未使用)。如果返回值为零,则任务可能已溢出堆栈。如果返回值接近于零,则任务接近于溢出堆栈。

Example usage

void vTask1( void * pvParameters )
{
    UBaseType_t uxHighWaterMark;

        /* 在进入任务时检查我们自己的高水位线。 */
        uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );

        for( ;; )
        {
            /* 调用任何函数。  */
            vTaskDelay( 1000 );

            /* 调用该函数会占用一些堆栈空间,因此我们现在希望uxTaskGetStackHighWaterMark()
                                        返回的值低于输入任务时调用它时的值。  */
            uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
        }
}

函数代码

//tasks.c
/*-----------------------------------------------------------*/
#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )

    UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
    {
        TCB_t * pxTCB;
        uint8_t * pucEndOfStack;
        UBaseType_t uxReturn;

        pxTCB = prvGetTCBFromHandle( xTask );

        #if portSTACK_GROWTH < 0
            {
                pucEndOfStack = ( uint8_t * ) pxTCB->pxStack;
            }
        #else
            {
                pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack;
            }
        #endif

        uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack );

        return uxReturn;
    }

#endif /* INCLUDE_uxTaskGetStackHighWaterMark */
/*-----------------------------------------------------------*/

eTaskGetState(任务获取状态)

INCLUDE_eTaskGetState 必须在 FreeRTOSConfig.h 中设置为 1 才能使 eTaskGetState() 可用。

以枚举类型返回执行 eTaskGetState() 时任务存在的状态。

//task.h
eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;

xTask主题任务(正在查询的任务)的句柄。

Returns

返回任务存在的状态。

返回值:

状态返回值
ReadyeReady
RunningeRunning (the calling task is querying its own priority)
BlockedeBlocked
SuspendedeSuspended
DeletedeDeleted (the tasks TCB is waiting to be cleaned up)

函数代码

//tasks.c
/*-----------------------------------------------------------*/

#if ( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_xTaskAbortDelay == 1 ) )

    eTaskState eTaskGetState( TaskHandle_t xTask )
    {
        eTaskState eReturn;
        List_t const * pxStateList, * pxDelayedList, * pxOverflowedDelayedList;
        const TCB_t * const pxTCB = xTask;

        configASSERT( pxTCB );

        if( pxTCB == pxCurrentTCB )
        {
            /* The task calling this function is querying its own state. */
            eReturn = eRunning;
        }
        else
        {
            taskENTER_CRITICAL();
            {
                pxStateList = listLIST_ITEM_CONTAINER( &( pxTCB->xStateListItem ) );
                pxDelayedList = pxDelayedTaskList;
                pxOverflowedDelayedList = pxOverflowDelayedTaskList;
            }
            taskEXIT_CRITICAL();

            if( ( pxStateList == pxDelayedList ) || ( pxStateList == pxOverflowedDelayedList ) )
            {
                /* The task being queried is referenced from one of the Blocked
                 * lists. */
                eReturn = eBlocked;
            }

            #if ( INCLUDE_vTaskSuspend == 1 )
                else if( pxStateList == &xSuspendedTaskList )
                {
                    /* The task being queried is referenced from the suspended
                     * list.  Is it genuinely suspended or is it blocked
                     * indefinitely? */
                    if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
                    {
                        #if ( configUSE_TASK_NOTIFICATIONS == 1 )
                            {
                                BaseType_t x;

                                /* The task does not appear on the event list item of
                                 * and of the RTOS objects, but could still be in the
                                 * blocked state if it is waiting on its notification
                                 * rather than waiting on an object.  If not, is
                                 * suspended. */
                                eReturn = eSuspended;

                                for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ )
                                {
                                    if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION )
                                    {
                                        eReturn = eBlocked;
                                        break;
                                    }
                                }
                            }
                        #else /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
                            {
                                eReturn = eSuspended;
                            }
                        #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
                    }
                    else
                    {
                        eReturn = eBlocked;
                    }
                }
            #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */

            #if ( INCLUDE_vTaskDelete == 1 )
                else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) )
                {
                    /* The task being queried is referenced from the deleted
                     * tasks list, or it is not referenced from any lists at
                     * all. */
                    eReturn = eDeleted;
                }
            #endif

            else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */
            {
                /* If the task is not in any other state, it must be in the
                 * Ready (including pending ready) state. */
                eReturn = eReady;
            }
        }

        return eReturn;
    } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */

#endif /* INCLUDE_eTaskGetState */
/*-----------------------------------------------------------*/

pcTaskGetName

没有执行条件。

从任务的句柄中查找任务的名称。

char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION;     
/*lint !e971 Unqualified char types are allowed for strings and single characters only. */

xTaskToQuery正在查询的任务的句柄。 xTaskToQuery 可以设置为 NULL 来查询调用任务的名称。

Returns

指向主题任务名称的指针,它是标准的以 NULL 结尾的 C 字符串。

函数代码

//tasks.c
/*-----------------------------------------------------------*/

char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{
    TCB_t * pxTCB;

    /* If null is passed in here then the name of the calling task is being
     * queried. */
    pxTCB = prvGetTCBFromHandle( xTaskToQuery );
    configASSERT( pxTCB );
    return &( pxTCB->pcTaskName[ 0 ] );
}
/*-----------------------------------------------------------*/

xTaskGetTickCount(任务获取滴答计数)

无法从ISR调用此函数。改为使用 xTaskGetTickCountFromISR()


xTaskGetTickCountFromlSR

可以从 ISR 调用的 xTaskGetTickCount() 版本。

TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION;

Returns

自调用 vTaskStartScheduler 以来的滴答计数。

函数代码

//tasks.c
/*-----------------------------------------------------------*/
TickType_t xTaskGetTickCountFromISR( void )
{
    TickType_t xReturn;
    UBaseType_t uxSavedInterruptStatus;

    /* RTOS ports that support interrupt nesting have the concept of a maximum
     * system call (or maximum API call) interrupt priority.  Interrupts that are
     * above the maximum system call priority are kept permanently enabled, even
     * when the RTOS kernel is in a critical section, but cannot make any calls to
     * FreeRTOS API functions.  If configASSERT() is defined in FreeRTOSConfig.h
     * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
     * failure if a FreeRTOS API function is called from an interrupt that has been
     * assigned a priority above the configured maximum system call priority.
     * Only FreeRTOS functions that end in FromISR can be called from interrupts
     * that have been assigned a priority at or (logically) below the maximum
     * system call  interrupt priority.  FreeRTOS maintains a separate interrupt
     * safe API to ensure interrupt entry is as fast and as simple as possible.
     * More information (albeit Cortex-M specific) is provided on the following
     * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
    portASSERT_IF_INTERRUPT_PRIORITY_INVALID();

    uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR();
    {
        xReturn = xTickCount;
    }
    portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );

    return xReturn;
}
/*-----------------------------------------------------------*/

xTaskGetSchedulerState(任务获取调度程序状态)

在FreeRTOSConfig.h中,INCLUDE_xTaskGetSchedulerState 或 configUSE_TIMERS 必须设置为1使该功能可用。

BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;

Returns

以下常量之一(在task.h中定义):

taskSCHEDULER_NOT_STARTED,

taskSCHEDULER_RUNNING,

taskSCHEDULER_SUSPENDED。

函数代码

//tasks.c
/*-----------------------------------------------------------*/

#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )

    BaseType_t xTaskGetSchedulerState( void )
    {
        BaseType_t xReturn;

        if( xSchedulerRunning == pdFALSE )
        {
            xReturn = taskSCHEDULER_NOT_STARTED;
        }
        else
        {
            if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
            {
                xReturn = taskSCHEDULER_RUNNING;
            }
            else
            {
                xReturn = taskSCHEDULER_SUSPENDED;
            }
        }

        return xReturn;
    }

#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/

晚安 ~

这一部分有些多 ~ 分两部分吧!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值