官方文档
目录
uxTaskGetSystemState(任务获取系统状态)
xTaskGetApplicationTaskTag(任务获取应用程序任务标记)
xTaskGetCurrentTaskHandle(任务获取当前任务句柄)
xTaskGetldleTaskHandle(任务获取ldle任务句柄)
uxTaskGetStackHighWaterMark(任务得到堆栈高水位线)
xTaskGetSchedulerState(任务获取调度程序状态)
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函数确定。
uxArraySize:pxTaskStatusArray 参数指向的数组的大小。大小指定为数组中的索引数(数组中包含的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 将返回调用任务的信息。
pxTaskStatus:pxTaskStatus 指向的 TaskStatus_t 结构将填充有关 xTask 参数中传递的句柄引用的任务的信息。
xGetFreeStackSpace:TaskStatus_t 结构包含一个成员,用于报告所查询任务的堆栈最高水位线。堆栈高水位线是有史以来存在的最小堆栈空间量,因此数字越接近于零,任务越接近溢出堆栈。计算堆栈高水位线需要相对较长的时间,并且可能会使系统暂时无响应 —— 因此提供xGetFreeStackSpace 参数以允许跳过高水位线检查。只有在 xGetFreeStackSpace 未设置为 pdFALSE 时,高水印值才会写入 TaskStatus_t 结构。
eState:TaskStatus_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
返回任务存在的状态。
返回值:
状态 | 返回值 |
---|---|
Ready | eReady |
Running | eRunning (the calling task is querying its own priority) |
Blocked | eBlocked |
Suspended | eSuspended |
Deleted | eDeleted (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 ) ) */
/*-----------------------------------------------------------*/
晚安 ~
这一部分有些多 ~ 分两部分吧!