第三章 FreeRTOS任务实用工具API

目录

uxTaskGetSystemState()

vTaskGetInfo()

xTaskGetApplicationTaskTagTagxTaskGetApplicationTaskTagFromISR

xTaskGetCurrentTaskHandle

xTaskGetHandle

xTaskGetIdleTaskHandle

uxTaskGetStackHighWaterMarkuxTaskGetStackHighWaterMark2

eTaskGetState

pcTaskGetName

xTaskGetTickCount

xTaskGetTickCountFromISR

xTaskGetSchedulerState

uxTaskGetNumberOfTasks

vTaskList

vTaskStartTrace

ulTask​​EndTrace

vTaskGetRunTimeStats

vTaskSetApplicationTaskTag

xTaskCallApplicationTaskHook

vTaskSetThreadLocalStoragePointer

pvTaskGetThreadLocalStoragePointer

vTaskSetTimeOutState()

xTaskCheckForTimeOut()


 

uxTaskGetSystemState()

UBaseType_t uxTaskGetSystemState(
                       TaskStatus_t * const pxTaskStatusArray,
                       const UBaseType_t uxArraySize,
                       unsigned long * const pulTotalRunTime);

必须在FreeRTOSConfig.h中将configUSE_TRACE_FACILITY定义为1,才能使uxTaskGetSystemState()可用。

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

有关为单个任务而不是每个任务填充TaskStatus_t结构的版本,请参见vTaskGetInfo()。

注意:此功能仅用于调试用途,因为其使用会导致调度程序长时间处于挂起状态。

参数:

pxTaskStatusArray   指向TaskStatus_t结构数组的指针。对于受RTOS控制的每个任务,该数组必须至少包含一个TaskStatus_t结构。可以使用uxTaskGetNumberOfTasks() API函数来确定RTOS控制下的任务数。
uxArraySize   pxTaskStatusArray参数指向的数组的大小。该大小指定为数组中索引的数量(数组中包含的TaskStatus_t结构的数量),而不是数组中的字节数。
pulTotalRunTime   如果在FreeRTOSConfig.h中将configGENERATE_RUN_TIME_STATS设置为1,则* pulTotalRunTime将由uxTaskGetSystemState()设置为自目标启动以来的总运行时间(由运行时间统计时钟定义)。可以将pulTotalRunTime设置为NULL以忽略总运行时间值。

返回值:

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

用法示例:

/* This example demonstrates how a human readable table of run time stats
information is generated from raw data provided by uxTaskGetSystemState().
The human readable table is written to pcWriteBuffer.  (see the vTaskList()
API function which actually does just this). */
void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
{
TaskStatus_t *pxTaskStatusArray;
volatile UBaseType_t uxArraySize, x;
unsigned long ulTotalRunTime, ulStatsAsPercentage;

   /* Make sure the write buffer does not contain a string. */
   *pcWriteBuffer = 0x00;

   /* Take a snapshot of the number of tasks in case it changes while this
   function is executing. */
   uxArraySize = uxTaskGetNumberOfTasks();

   /* Allocate a TaskStatus_t structure for each task.  An array could be
   allocated statically at compile time. */
   pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );

   if( pxTaskStatusArray != NULL )
   {
      /* Generate raw status information about each task. */
      uxArraySize = uxTaskGetSystemState( pxTaskStatusArray,
                                 uxArraySize,
                                 &ulTotalRunTime );

      /* For percentage calculations. */
      ulTotalRunTime /= 100UL;

      /* Avoid divide by zero errors. */
      if( ulTotalRunTime > 0 )
      {
         /* For each populated position in the pxTaskStatusArray array,
         format the raw data as human readable ASCII data. */
         for( x = 0; x < uxArraySize; x++ )
         {
            /* What percentage of the total run time has the task used?
            This will always be rounded down to the nearest integer.
            ulTotalRunTimeDiv100 has already been divided by 100. */
            ulStatsAsPercentage =
                  pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;

            if( ulStatsAsPercentage > 0UL )
            {
               sprintf( pcWriteBuffer, "%stt%lutt%lu%%rn",
                                 pxTaskStatusArray[ x ].pcTaskName,
                                 pxTaskStatusArray[ x ].ulRunTimeCounter,
                                 ulStatsAsPercentage );
            }
            else
            {
               /* If the percentage is zero here then the task has
               consumed less than 1% of the total run time. */
               sprintf( pcWriteBuffer, "%stt%lutt<1%%rn",
                                 pxTaskStatusArray[ x ].pcTaskName,
                                 pxTaskStatusArray[ x ].ulRunTimeCounter );
            }

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

      /* The array is no longer needed, free the memory it consumes. */
      vPortFree( pxTaskStatusArray );
   }
}

The TaskStatus_t definition

typedef struct xTASK_STATUS
{
   /* The handle of the task to which the rest of the information in the
   structure relates. */
   TaskHandle_t xHandle;

   /* A pointer to the task's name.  This value will be invalid if the task was
   deleted since the structure was populated! */
   const signed char *pcTaskName;

   /* A number unique to the task. */
   UBaseType_t xTaskNumber;

   /* The state in which the task existed when the structure was populated. */
   eTaskState eCurrentState;

   /* The priority at which the task was running (may be inherited) when the
   structure was populated. */
   UBaseType_t uxCurrentPriority;

   /* The priority to which the task will return if the task's current priority
   has been inherited to avoid unbounded priority inversion when obtaining a
   mutex.  Only valid if configUSE_MUTEXES is defined as 1 in
   FreeRTOSConfig.h. */
   UBaseType_t uxBasePriority;

   /* The total run time allocated to the task so far, as defined by the run
   time stats clock.  Only valid when configGENERATE_RUN_TIME_STATS is
   defined as 1 in FreeRTOSConfig.h. */
   unsigned long ulRunTimeCounter;

   /* Points to the lowest address of the task's stack area. */
   StackType_t *pxStackBase;

   /* The minimum amount of stack space that has remained for the task since
   the task was created.  The closer this value is to zero the closer the task
   has come to overflowing its stack. */
   configSTACK_DEPTH_TYPE usStackHighWaterMark;
} TaskStatus_t;

vTaskGetInfo()

task.h

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

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

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

注意:此功能仅用于调试用途,因为其使用会导致调度程序长时间处于挂起状态。

参数:

任务   正在查询任务的句柄。将xTask设置为NULL将返回有关调用任务的信息。
pxTaskStatus   pxTaskStatus指向的TaskStatus_t结构将填充有关xTask参数中传递的句柄引用的任务的信息。
xGetFreeStackSpace   TaskStatus_t结构包含一个成员,用于报告要查询的任务的堆栈高水位线。堆栈高水位标记是已存在的最小堆栈空间量,因此数字越接近零,任务就越接近其堆栈溢出。计算堆栈高水位标记需要相对较长的时间,并且可以使系统暂时无响应–因此提供了xGetFreeStackSpace参数,以跳过高水位检查。如果xGetFreeStackSpace未设置为pdFALSE,则仅将高水印值写入TaskStatus_t结构。
房地产   TaskStatus_t结构包含一个成员,用于报告要查询的任务的状态。获取任务状态并不像简单分配那样快-因此提供eState参数可以从TaskStatus_t结构中省略状态信息。要获取状态信息,然后将eState设置为eInvalid-否则,在eState中传递的值将在TaskStatus_t结构中报告为任务状态。

用法示例:

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

    /* Obtain the handle of a task from its name. */
    xHandle = xTaskGetHandle( "Task_Name" );

    /* Check the handle is not NULL. */
    configASSERT( xHandle );

    /* Use the handle to obtain further information about the task. */
    vTaskGetInfo( /* The handle of the task being queried. */
                  xHandle,
                  /* The TaskStatus_t structure to complete with information
                  on xTask. */
                  &xTaskDetails,
                  /* Include the stack high water mark value in the
                  TaskStatus_t structure. */
                  pdTRUE,
                  /* Include the task state in the TaskStatus_t structure. */
                  eInvalid );
}

The TaskStatus_t definition

typedef struct xTASK_STATUS
{
   /* The handle of the task to which the rest of the information in the
   structure relates. */
   TaskHandle_t xHandle;

   /* A pointer to the task's name.  This value will be invalid if the task was
   deleted since the structure was populated! */
   const signed char *pcTaskName;

   /* A number unique to the task. */
   UBaseType_t xTaskNumber;

   /* The state in which the task existed when the structure was populated. */
   eTaskState eCurrentState;

   /* The priority at which the task was running (may be inherited) when the
   structure was populated. */
   UBaseType_t uxCurrentPriority;

   /* The priority to which the task will return if the task's current priority
   has been inherited to avoid unbounded priority inversion when obtaining a
   mutex.  Only valid if configUSE_MUTEXES is defined as 1 in
   FreeRTOSConfig.h. */
   UBaseType_t uxBasePriority;

   /* The total run time allocated to the task so far, as defined by the run
   time stats clock.  Only valid when configGENERATE_RUN_TIME_STATS is
   defined as 1 in FreeRTOSConfig.h. */
   unsigned long ulRunTimeCounter;

   /* Points to the lowest address of the task's stack area. */
   StackType_t *pxStackBase;

   /* The minimum amount of stack space that has remained for the task since
   the task was created.  The closer this value is to zero the closer the task
   has come to overflowing its stack. */
   configSTACK_DEPTH_TYPE usStackHighWaterMark;
} TaskStatus_t;

xTaskGetApplicationTaskTagTag
xTaskGetApplicationTaskTagFromISR

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

为了使这些功能可用,必须将configUSE_APPLICATION_TASK_TAG定义为1。有关更多信息,请参见RTOS配置文档。

xTaskGetApplicationTaskTagTagFromISR()是xTaskGetApplicationTaskTagTag()的一个版本,可以从中断服务例程(ISR)进行调用。

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

此功能仅适用于高级用户。

参数:

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

返回值:

被查询任务的“标签”值。

用法示例:

/* In this example, an integer is set as the task tag value. */
void vATask( void *pvParameters )
{
    /* Assign a tag value of 1 to the currently executing task.
    The (void *) cast is used to prevent compiler warnings. */
    vTaskSetApplicationTaskTag( NULL, ( void * ) 1 );

    for( ;; )
    {
        /* Rest of task code goes here. */
    }
}

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

   /* Create a task from the vATask() function, storing the handle to the
   created task in the xTask variable. */

   /* Create the task. */
   if( xTaskCreate(
             vATask,         /* Pointer to the function that implements
                                the task. */
             "Demo task",    /* Text name given to the task. */
             STACK_SIZE,     /* The size of the stack that should be created
                                for the task.  This is defined in words, not
                                bytes. */
             NULL,           /* The task does not use the
                              parameter. */
             TASK_PRIORITY,  /* The priority to assign to the newly created
                                task. */
             &xHandle        /* The handle to the task being created will be
                                placed in xHandle. */
             ) == pdPASS )
   {
       /* The task was created successfully.  Delay for a short period to allow
       the task to run. */
       vTaskDelay( 100 );

       /* What tag value is assigned to the task?  The returned tag value is
       stored in an integer, so cast to an integer to prevent compiler
       warnings. */
       iReturnedTaskHandle = ( int ) xTaskGetApplicationTaskTag( xHandle );
   }
}

xTaskGetCurrentTaskHandle

TaskHandle_t xTaskGetCurrentTaskHandle(void);
 

必须将INCLUDE_xTaskGetCurrentTaskHandle设置为1才能使用此功能。

返回值:

当前正在运行(正在调用)的任务的句柄。


xTaskGetHandle

TaskHandle_t xTaskGetHandle(const char * pcNameToQuery);

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

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

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

参数:

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

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

返回值:

如果可以找到具有在pcNameToQuery中传递的名称的任务,则返回任务的句柄,否则返回NULL。


xTaskGetIdleTaskHandle

TaskHandle_t xTaskGetIdleTaskHandle(void);
 

必须将INCLUDE_xTaskGetIdleTaskHandle设置为1才能使用此功能。

返回值:

与空闲任务关联的任务句柄。启动RTOS计划程序时,将自动创建空闲任务。


uxTaskGetStackHighWaterMark
uxTaskGetStackHighWaterMark2

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

要使这些功能可用,必须将INCLUDE_uxTaskGetStackHighWaterMark定义为1。有关更多信息,请参见RTOS配置文档。

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

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

参数:

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

返回值:

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

用法示例:

    void vTask1( void * pvParameters )
    {
        UBaseType_t uxHighWaterMark;

        /* Inspect our own high water mark on entering the task. */
        uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );

        for( ;; )
        {
            /* Call any function. */
            vTaskDelay( 1000 );

            /* Calling the function will have used some stack space, we would 
            therefore now expect uxTaskGetStackHighWaterMark() to return a 
            value lower than when it was called on entering the task. */
            uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
        }
    }

eTaskGetState

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

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

另请参见vTaskGetInfo()。

参数:

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

返回值:

下表列出了eTaskGetState()将针对xTask参数引用的任务可能存在的每个可能状态返回的值。

状态
返回值
就绪态 eReady
运行态 eRunning(调用任务正在查询自己的优先级)
阻塞态 eBlocked
挂起态 eSuspended
删除态 eDeleted(任务TCB正在等待清理)

pcTaskGetName

char * pcTaskGetName(TaskHandle_t xTaskToQuery);

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

参数:

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

返回值:

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


xTaskGetTickCount

volatile TickType_t xTaskGetTickCount(void);

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

返回值:

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


xTaskGetTickCountFromISR

volatile TickType_t xTaskGetTickCountFromFromISR(void);

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

返回值:

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


xTaskGetSchedulerState

BaseType_t xTaskGetSchedulerState(void);

 

返回值:

以下常量之一(在task.h中定义):taskSCHEDULER_NOT_STARTED,taskSCHEDULER_RUNNING,taskSCHEDULER_SUSPENDED。

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


uxTaskGetNumberOfTasks

UBaseType_t uxTaskGetNumberOfTasks(void);

 

返回值:

RTOS内核当前正在管理的任务数。这包括所有准备就绪,已阻止和已暂停的任务。空闲任务已删除但尚未释放的任务也将包括在计数中。


vTaskList

void vTaskList(char * pcWriteBuffer);	

要使此功能可用,必须在FreeRTOSConfig.h中将configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS定义为1。有关更多信息,请参见配置部分。

注意:此功能将在其持续时间内禁用中断。它不适合正常的应用程序运行时使用,而是作为调试辅助。

vTaskList()调用uxTaskGetSystemState(),然后将uxTaskGetSystemState()生成的原始数据格式化为人类可读(ASCII)表,该表显示每个任务的状态,包括任务堆栈的高水位标记(高水位标记越小,任务越接近其堆栈溢出)。 单击此处查看生成的输出示例。

在ASCII表中,以下字母用于表示任务的状态:

  • 'B' –已屏蔽
  • 'R' –准备就绪
  • 'D' –删除(等待清理)
  • 'S' –暂停或被阻止,没有超时

vTaskList()是仅出于方便目的而提供的实用程序函数。它不被视为内核的一部分。有关 实用程序函数的信息,请参见vTaskGetRunTimeStats(),该实用程序函数会生成类似的运行时任务利用率信息表。

参数:

pcWriteBuffer   将上述详细信息写入ASCII格式的缓冲区。假定此缓冲区足够大以包含生成的报告。每个任务大约40个字节就足够了。

vTaskStartTrace

void vTaskStartTrace(char * pcBuffer,unsigned long ulBufferSize);

[此功能与FreeRTOS V7.1.0中已删除的旧版跟踪实用程序有关,用户可能会发现更易于使用且功能更强大的更新的 跟踪挂钩宏。

启动RTOS内核活动跟踪。跟踪记录何时运行哪个任务的标识。

跟踪文件以二进制格式存储。单独的DOS实用程序convtrce.exe可用于将其转换为制表符分隔的文本文件,该文件可在电子表格中查看和绘制。

参数:

pcBuffer  跟踪将写入其中的缓冲区。
ulBufferSize  pcBuffer的大小(以字节为单位)。跟踪将一直持续到缓冲区已满或调用ulTask​​EndTrace()为止。

ulTask​​EndTrace

unsigned long ulTask​​EndTrace(void);
 

[此功能与FreeRTOS V7.1.0中已删除的旧版跟踪实用程序有关,用户可能会发现更易于使用且功能更强大的更新的跟踪挂钩宏。

停止RTOS内核活动跟踪。请参见vTaskStartTrace()。

返回值:

已写入跟踪缓冲区的字节数。


vTaskGetRunTimeStats

void vTaskGetRunTimeStats(char * pcWriteBuffer);

有关此功能的完整说明,请参见“ 运行时统计”页面。

configGENERATE_RUN_TIME_STATS,configUSE_STATS_FORMATTING_FUNCTIONS和configSUPPORT_DYNAMIC_ALLOCATION必须都定义为1,此功能才可用。然后,应用程序还必须提供portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()和portGET_RUN_TIME_COUNTER_VALUE的定义,以配置外设定时器/计数器并分别返回定时器的当前计数值。计数器应至少是滴答计数频率的10倍。

注意:此功能将在其持续时间内禁用中断。它不适合正常的应用程序运行时使用,而是作为调试辅助。vTaskGetRunTimeStats()

调用uxTaskGetSystemState(),然后将uxTaskGetSystemState()生成的原始数据格式化为人类可读(ASCII)表,该表显示每个任务在运行状态下所花费的时间(每个任务所消耗的CPU时间) 。数据以绝对值和百分比值形式提供。绝对值的分辨率取决于应用程序提供的运行时统计时钟的频率。

vTaskGetRunTimeStats()是仅出于方便目的而提供的实用程序函数。它不被视为内核的一部分。有关 生成每个任务状态信息的实用程序功能,请参见vTaskList()。

参数:

pcWriteBuffer  执行时间将以ASCII形式写入的缓冲区。假定此缓冲区足够大以包含生成的报告。每个任务大约40个字节就足够了。

vTaskSetApplicationTaskTag

void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue);
 

必须将configUSE_APPLICATION_TASK_TAG定义为1,此功能才能使用。有关更多信息,请参见RTOS配置文档。

可以为每个任务分配一个“标签”值。该值仅用于应用程序– RTOS内核本身不以任何方式使用它。该RTOS跟踪宏文档页面提供了一个应用程序可能如何利用此功能的一个很好的例子。

参数:

任务  为其分配了标签值的任务的句柄。将xTask传递为NULL会将标记分配给调用任务。
pxTagValue  分配给任务标签的值。这是TaskHookFunction_t类型,允许将功能指针分配为标签,尽管实际上可以分配任何值。请参见下面的示例。

用法示例:

/* In this example an integer is set as the task tag value.  
See the RTOS trace hook macros documentation page for an 
example how such an assignment can be used. */
void vATask( void *pvParameters )
{
  /* Assign a tag value of 1 to myself. */
  vTaskSetApplicationTaskTag( NULL, ( void * ) 1 );

  for( ;; )
  {
    /* Rest of task code goes here. */
  }
}
/***********************************************/

/* In this example a callback function is being assigned as the task tag.
First define the callback function - this must have type TaskHookFunction_t
as per this example. */
static BaseType_t prvExampleTaskHook( void * pvParameter )
{
  /* Perform some action - this could be anything from logging a value,
  updating the task state, outputting a value, etc. */

  return 0;
}

/* Now define the task that sets prvExampleTaskHook as its hook/tag value.
This is in fact registering the task callback, as described on the
xTaskCallApplicationTaskHook() documentation page. */
void vAnotherTask( void *pvParameters )
{
  /* Register our callback function. */
  vTaskSetApplicationTaskTag( NULL, prvExampleTaskHook );

  for( ;; )
  {
    /* Rest of task code goes here. */
  }
}

/* As an example use of the hook (callback) we can get the RTOS kernel to call the
hook function of each task that is being switched out during a reschedule. */
#define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook( pxCurrentTCB,
                                    0 )
  

xTaskCallApplicationTaskHook

BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );

 

必须将configUSE_APPLICATION_TASK_TAG定义为1,此功能才能使用。有关更多信息,请参见RTOS配置文档。

可以为每个任务分配一个“标签”值。通常,此值仅供应用程序使用,RTOS内核不会访问它。但是,可以使用标记将钩子(或回调)函数分配给任务-通过调用xTaskCallApplicationTaskHook()执行钩子函数。每个任务可以定义自己的回调,也可以根本不定义回调。

尽管可以使用第一个函数参数来调用任何任务的钩子函数,但是任务钩子函数最常见的用法是使用跟踪钩子宏,如以下示例所示。

任务挂钩函数必须具有TaskHookFunction_t类型,即带有void *参数,并返回BaseType_t类型的值。void *参数可用于将任何信息传递给hook函数。

参数:

任务  正在调用其挂钩函数的任务的句柄。将NULL作为xTask传递时,将调用与当前正在执行的任务相关联的hook函数。
pvParameter  传递给挂钩函数的值。这可以是指向结构的指针,也可以只是数字值。

用法示例:

/* In this example a callback function is being assigned as the task tag.
First define the callback function - this must have type TaskHookFunction_t
as per this example. */
static BaseType_t prvExampleTaskHook( void * pvParameter )
{
   /* Perform some action - this could be anything from logging a value,
   updating the task state, outputting a value, etc. */

   return 0;
}

/* Now define the task that sets prvExampleTaskHook as its hook/tag value.
This is in fact registering the task callback, as described on the
xTaskCallApplicationTaskHook() documentation page. */
void vAnotherTask( void *pvParameters )
{
   /* Register our callback function. */
   vTaskSetApplicationTaskTag( NULL, prvExampleTaskHook );

   for( ;; )
   {
      /* Rest of task code goes here. */
   }
}

/* As an example use of the hook (callback) we can get the RTOS kernel to
call the hook function of each task that is being switched out during a
reschedule. */
#define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook( pxCurrentTCB, 0 )
  

vTaskSetThreadLocalStoragePointer

无效vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, 
                                        BaseType_t xIndex, 
                                        无效* pvValue)

在任务的线程本地存储数组中设置一个值 。

此功能仅适用于高级用户。

参数:

xTaskToSet  线程本地数据正在写入的任务的句柄。通过使用NULL作为参数值,任务可以写入其自己的线程本地数据。
索引  线程本地存储阵列中要写入数据的索引。

可用数组索引的数量由FreeRTOSConfig.h中的configNUM_THREAD_LOCAL_STORAGE_POINTERS 编译时配置常量 设置 。

pv值  要写入由xIndex参数指定的索引的值。

用法示例:

请参阅线程本地存储阵列 文档页面上提供的示例。


pvTaskGetThreadLocalStoragePointer

无效* pvTaskGetThreadLocalStoragePointer(
                                 TaskHandle_t xTaskToQuery,
                                 BaseType_t xIndex);

从任务的线程本地存储数组中检索一个值 。

此功能仅适用于高级用户。

参数:

xTaskToQuery  从中读取线程本地数据的任务的句柄。通过使用NULL作为参数值,任务可以读取自己的线程本地数据。
索引  到线程本地存储阵列中的索引,将从中读取数据。

可用数组索引的数量由FreeRTOSConfig.h中的configNUM_THREAD_LOCAL_STORAGE_POINTERS 编译时配置常量 设置 。

返回值:

存储在任务xTaskToQuery的线程本地存储数组的索引位置xIndex中的值。

用法示例:

请参阅线程本地存储阵列 文档页面上提供的示例。


vTaskSetTimeOutState()

void vTaskSetTimeOutState(TimeOut_t * const pxTimeOut);

此功能仅适用于高级用户。

任务可以进入阻止状态以等待事件。通常,任务不会无限期地处于“阻塞”状态,而是将指定超时期限。如果超时时间在任务等待事件发生之前到期,则该任务将从“阻塞”状态中删除。

如果任务在等待事件发生时多次进入和退出“阻止”状态,则必须调整每次任务进入“阻止”状态所用的超时时间,以确保在“阻止”状态下花费的所有时间总计不超过最初指定的超时期限。xTaskCheckForTimeOut()执行调整时要考虑偶发计数溢出之类的偶发事件,否则这会使手动调整容易出错。

vTaskSetTimeOutState()与xTaskCheckForTimeOut()一起使用。调用vTaskSetTimeOutState()设置初始条件,然后可以调用xTaskCheckForTimeOut()来检查超时条件,并在未发生超时的情况下调整剩余的块时间。

参数:

pxTimeOut   指向结构的指针,该结构将被初始化以保存确定是否发生超时所必需的信息。

用法示例:

xTaskCheckForTimeOut() 文档页面 上提供了一个示例。


xTaskCheckForTimeOut()

BaseType_t xTaskCheckForTimeOut(TimeOut_t * const pxTimeOut,
                                 TickType_t * const pxTicksToWait);

此功能仅适用于高级用户。

任务可以进入阻止状态以等待事件。通常,任务不会无限期地处于“阻塞”状态,而是将指定超时期限。如果超时时间在任务等待事件发生之前到期,则该任务将从“阻塞”状态中删除。

如果任务在等待事件发生时多次进入和退出“阻止”状态,则必须调整每次任务进入“阻止”状态所用的超时时间,以确保在“阻止”状态下花费的所有时间总计不超过最初指定的超时期限。xTaskCheckForTimeOut()执行调整时要考虑偶发计数溢出之类的偶发事件,否则这会使手动调整容易出错。

xTaskCheckForTimeOut()与vTaskSetTimeOutState()一起使用。调用vTaskSetTimeOutState()设置初始条件,然后可以调用xTaskCheckForTimeOut()来检查超时条件,并在未发生超时的情况下调整剩余的块时间。

参数:

pxTimeOut   指向结构的指针,该结构保存确定是否发生超时所需的信息。使用vTaskSetTimeOutState()初始化pxTimeOut。
pxTicksToWait   用于传递调整后的阻止时间,这是考虑到已经处于“阻止”状态的时间之后剩余的阻止时间。

返回值:

如果返回pdTRUE,则没有块时间剩余,并且发生了超时。

如果返回pdFALSE,则剩余一些块时间,因此不会发生超时。

用法示例:

/* Driver library function used to receive uxWantedBytes from an Rx buffer that
is filled by a UART interrupt.  If there are not enough bytes in the Rx buffer
then the task enters the Blocked state until it is notified that more data has
been placed into the buffer.  If there is still not enough data then the task
re-enters the Blocked state, and xTaskCheckForTimeOut() is used to re-calculate
the Block time to ensure the total amount of time spent in the Blocked state does
not exceed MAX_TIME_TO_WAIT. This continues until either the buffer contains at
least uxWantedBytes bytes, or the total amount of time spent in the Blocked state
reaches MAX_TIME_TO_WAIT – at which point the task reads however many bytes are
available up to a maximum of uxWantedBytes. */
size_t xUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes )
{
size_t uxReceived = 0;
TickType_t xTicksToWait = MAX_TIME_TO_WAIT;
TimeOut_t xTimeOut;

   /* Initialize xTimeOut.  This records the time at which this function was
   entered. */
   vTaskSetTimeOutState( &xTimeOut );

   /* Loop until the buffer contains the wanted number of bytes, or a timeout
   occurs. */
   while( UART_bytes_in_rx_buffer( pxUARTInstance ) < uxWantedBytes )
   {
      /* The buffer didn't contain enough data so this task is going to
      enter the Blocked state.  Adjusting xTicksToWait to account for any time
      that has been spent in the Blocked state within this function so far to
      ensure the total amount of time spent in the Blocked state does not exceed
      MAX_TIME_TO_WAIT. */
      if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE )
      {
         /* Timed out before the wanted number of bytes were available, exit the
         loop. */
         break;
      }

      /* Wait for a maximum of xTicksToWait ticks to be notified that the receive
      interrupt has placed more data into the buffer. */
      ulTaskNotifyTake( pdTRUE, xTicksToWait );
   }

   /* Attempt to read uxWantedBytes from the receive buffer into pucBuffer.  The
   actual number of bytes read (which might be less than uxWantedBytes) is
   returned. */
   uxReceived = UART_read_from_receive_buffer( pxUARTInstance,
                                               pucBuffer,
                                               uxWantedBytes );

   return uxReceived;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章