FreeRTOS实时操作系统的任务应用函数详解

目录
  • 1.获取任务系统状态
    • 1.1函数描述
    • 1.2参数描述
    • 1.3返回值
    • 1.4用法举例
  • 2.获取当前任务句柄
    • 2.1函数描述
    • 2.2返回值
  • 3.获取空闲任务句柄
    • 3.1函数描述
    • 3.2返回值
  • 4.获取任务堆栈最大使用深度
    • 4.1函数描述
    • 4.2参数描述
    • 4.3返回值
    • 4.4用法举例
  • 5.获取任务状态
    • 5.1函数描述
    • 5.2参数描述
    • 5.3返回值
  • 6.获取任务描述内容
    • 6.1函数描述
    • 6.2参数描述
    • 6.3返回值
  • 7.获取系统节拍次数
    • 7.1函数描述
    • 7.2返回值
  • 8.获取调度器状态
    • 8.1函数描述
    • 8.2返回值
  • 9.获取任务总数
    • 9.1函数描述
    • 9.2返回值
  • 10.获取所有任务详情
    • 10.1函数描述
    • 10.2参数描述
  • 11.获取任务运行时间
    • 11.1函数描述
    • 11.2参数描述
    • 11.3用法举例
      • 11.3.1使能函数宏
      • 11.3.2定时初始化定时器代码
      • 11.3.3定义配置定时器和获取定时时间宏
  • 12.设置任务标签值
    • 12.1函数描述
    • 12.2参数描述
    • 12.3用法举例
  • 13.获取任务标签值
    • 13.1函数描述
    • 13.2参数描述
    • 13.3返回值
  • 14.执行任务的应用钩子函数
    • 14.1函数描述
    • 14.2参数描述
  • 15.设置线程本地存储指针
    • 15.1函数描述
    • 15.2参数描述
    • 15.3用法举例
  • 16.读取线程本地存储指针
    • 16.1函数描述
    • 16.2参数描写
    • 16.3返回值
    • 16.4用法举例
      • 16.4.1存储一个整形数
      • 16.4.2存储结构提
  • 17.设置超时状态
    • 17.1函数描述
    • 17.2参数描述
    • 17.3用法举例
  • 18.超时检测
    • 18.1函数描述
    • 18.2参数描述
    • 18.3返回值
    • 18.4用法举例

任务应用函数是一组辅助类函数,一般用于调试信息输出、获取任务句柄、获取任务状态、操作任务标签值等等。

1.获取任务系统状态

1.1函数描述

         UBaseType_t uxTaskGetSystemState(
                       TaskStatus_t * constpxTaskStatusArray,
                       const UBaseType_tuxArraySize,
                       unsigned long * constpulTotalRunTime );

该函数向TaskStatus_t结构体填充相关信息,系统中每一个任务的信息都可以填充到TaskStatus_t结构体数组中,数组大小由uxArraySize指定。结构体TaskStatus_t定义如下:

typedef struct xTASK_STATUS
{
   /* 任务句柄*/
   TaskHandle_t xHandle;
   /* 指针,指向任务名*/
   const signed char *pcTaskName;
   /*任务ID,是一个独一无二的数字*/
   UBaseType_t xTaskNumber;
   /*填充结构体时,任务当前的状态(运行、就绪、挂起等等)*/
   eTaskState eCurrentState;
   /*填充结构体时,任务运行(或继承)的优先级。*/
   UBaseType_t uxCurrentPriority;
   /* 当任务因继承而改变优先级时,该变量保存任务最初的优先级。仅当configUSE_MUTEXES定义为1有效。*/
   UBaseType_t uxBasePriority;
   /* 分配给任务的总运行时间。仅当宏configGENERATE_RUN_TIME_STATS为1时有效。*/
   unsigned long ulRunTimeCounter;
   /* 从任务创建起,堆栈剩余的最小数量,这个值越接近0,堆栈溢出的可能越大。 */
   unsigned short usStackHighWaterMark;
}TaskStatus_t;

注意,这个函数仅用来调试用,调用此函数会挂起所有任务,直到函数最后才恢复挂起的任务,因此任务可能被挂起很长时间。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY必须设置为1,此函数才有效。

1.2参数描述

pxTaskStatusArray:指向TaskStatus_t类型的结构体数组。这个数组至少要包含1个元素。RTOS控制的任务数量可以使用API函数uxTaskGetNumberOfTasks()获取。

uxArraySize:参数pxTaskStatusArray指向的数组大小,也就是该数组的索引数目。

pulTotalRunTime:如果在文件FreeRTOSConfig.h中设置宏configGENERATE_RUN_TIME_STATS为1,则该函数将总运行时间写入*pulTotalRunTime中。pulTotalRunTime可以设置为NULL,表示忽略总运行时间。

1.3返回值

被填充的TaskStatus_t结构体数量。这个值应该等于通过调用API函数uxTaskGetNumberOfTasks()返回的值,但如果传递给uxArraySize参数的值太小,则返回0。

1.4用法举例

/*本例演示如是使用uxTaskGetSystemState()函数来获取运行时间信息,并将其转化为程序员更易识别的字符格式,这些转化后的字符保存到pcWriteBuffer中。*/
void vTaskGetRunTimeStats(signed char *pcWriteBuffer )
{
   TaskStatus_t*pxTaskStatusArray;
   volatileUBaseType_t uxArraySize, x;
   unsignedlong ulTotalRunTime, ulStatsAsPercentage;
    /* 防御性代码,确保字符串有合理的结束*/
  *pcWriteBuffer = 0x00;
    /* 获取任务总数目*/
  uxArraySize = uxTaskGetNumberOfTasks ();
    /*为每个任务的TaskStatus_t结构体分配内存,也可以静态的分配一个足够大的数组 */
  pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ));
    if(pxTaskStatusArray != NULL )
   {
      /*获取每个任务的状态信息 */
     uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize,&ulTotalRunTime );
       /* 百分比计算 */
     ulTotalRunTime /= 100UL;
      /* 避免除零错误 */
      if(ulTotalRunTime > 0 )
      {
         /* 将获得的每一个任务状态信息部分的转化为程序员容易识别的字符串格式*/
        for( x = 0; x < uxArraySize; x++ )
         {
           /* 计算任务运行时间与总运行时间的百分比。*/
           ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter /ulTotalRunTime;
           if( ulStatsAsPercentage > 0UL )
           {
              sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n",
                                pxTaskStatusArray[ x ].pcTaskName,
                                pxTaskStatusArray[ x ].ulRunTimeCounter,
                                ulStatsAsPercentage );
           }
           else
           {
              /* 任务运行时间不足总运行时间的1%*/
              sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n",
                                pxTaskStatusArray[ x ].pcTaskName,
                                 pxTaskStatusArray[x ].ulRunTimeCounter );
           }
           pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
         }
      }
      /* 释放之前申请的内存*/
     vPortFree( pxTaskStatusArray );
   }
}

2.获取当前任务句柄

2.1函数描述

TaskHandle_t xTaskGetCurrentTaskHandle(void );

在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetCurrentTaskHandle必须设置为1,此函数才有效。

2.2返回值

返回当前任务(调用该函数的任务)的句柄。

3.获取空闲任务句柄

3.1函数描述

TaskHandle_t xTaskGetIdleTaskHandle(void );

在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetIdleTaskHandle必须设置为1,此函数才有效。

3.2返回值

返回空闲任务句柄。空闲任务在RTOS调度器启动时自动创建。

4.获取任务堆栈最大使用深度

4.1函数描述

UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );

任务的堆栈空间会随着任务执行以及中断处理而增长或缩小。该函数可以返回任务启动后的最小剩余堆栈空间。换句话说,可以间接估算出一个任务最多需要多少堆栈空间。在文件FreeRTOSConfig.h中,宏INCLUDE_uxTaskGetStackHighWaterMark 必须设置成1,此函数才有效。

4.2参数描述

xTask:任务句柄。NULL表示查看当前任务的堆栈使用情况。

4.3返回值

返回最小剩余堆栈空间,以字为单位。比如一个32为架构处理器,返回值为1表示有4字节堆栈空间没有使用过。如果返回值为0,则任务很可能已经发生了堆栈溢出。

4.4用法举例

     void vTask1( void * pvParameters )
     {
         UBaseType_tuxHighWaterMark;
         /* 入口处检测一次 */
         uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL );

         for( ;; )
         {
             /* 正常调用函数 */
             vTaskDelay( 1000 );
             /* 测量堆栈使用情况 */
             uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL );
         }
    }

5.获取任务状态

5.1函数描述

eTaskState eTaskGetState( TaskHandle_txTask );

返回一个枚举类型的任务状态值。在文件FreeRTOSConfig.h中,宏INCLUDE_eTaskGetState必须设置为1,此函数才有效。

5.2参数描述

xTask:任务句柄

5.3返回值

下表列出返回值和对应的任务状态。

6.获取任务描述内容

6.1函数描述

char * pcTaskGetTaskName( TaskHandle_txTaskToQuery );

获取任务的描述内容,在文件FreeRTOSConfig.h中,宏INCLUDE_pcTaskGetTaskName必须设置成1,此函数才有效。

6.2参数描述

xTaskToQuery:任务的句柄。NULL表示获取当前任务的描述内容指针。

6.3返回值

一个指针,指向任务描述字符串。

7.获取系统节拍次数

7.1函数描述

volatile TickType_t xTaskGetTickCount(void );

这个函数不能在ISR中调用。在ISR中用xTaskGetTickCountFromISR(),原型为volatileTickType_t xTaskGetTickCountFromISR( void )。

7.2返回值

返回从vTaskStartScheduler函数调用后的系统时钟节拍次数。

8.获取调度器状态

8.1函数描述

BaseType_t xTaskGetSchedulerState( void);

获取调度器当前状态。在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetSchedulerState或configUSE_TIMERS必须定义为1,此函数才有效。

8.2返回值

&&&返回值是以下常量之一(定义在task.h):taskSCHEDULER_NOT_STARTED(未启动)、taskSCHEDULER_RUNNING(正常运行)、taskSCHEDULER_SUSPENDED(挂起)。

9.获取任务总数

9.1函数描述

UBaseType_t uxTaskGetNumberOfTasks(void );

&&&获取RTOS内核当前管理的任务总数。包含所有就绪、阻塞和挂起状态的任务。对于一个删除的任务,如果它的堆栈空间还没有被空闲任务释放掉,则这个被删除的任务也含在计数值中。

9.2返回值

&&&返回RTOS内核当前管理的任务总数。

10.获取所有任务详情

10.1函数描述

void vTaskList( char *pcWriteBuffer );

&&&将每个任务的状态、堆栈使用情况等以字符的形式保存到参数pcWriteBuffer指向的区域。vTaskList()函数调用usTaskGetSystemState()函数,然后将得到的信息格式化为程序员易读的字符形式。输出的内容例子如下图所示,图中State一栏中,B表示阻塞、R表示就绪、D表示删除(等待清除内存)、S表示挂起或阻塞。

&&&注意,调用这个函数会挂起所有任务,这一过程可能持续较长时间,因此本函数仅在调试时使用。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS必须定义为1,此函数才有效。

10.2参数描述

pcWriteBuffer:任务的信息会写入这个缓冲区,为ASCII表单形式。这个缓冲区要足够大,以容纳生成的报告,每个任务大约需要40个字节。

11.获取任务运行时间

11.1函数描述

void vTaskGetRunTimeStats( char*pcWriteBuffer );

这个函数用于统计每个任务的运行时间。要使用这个函数必须满足一些条件,那就是必须有一个用于时间统计的定时器或计数器,这个定时器或计数器的精度要至少大于10倍的系统节拍周期。这个定时器或计数器的配置以及获取定时时间是由两个宏定义实现的,这两个宏一般在文件FreeRTOSConfig.h中定义。配置定时器或计数器的宏为portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(),获取定时时间的宏为portGET_RUN_TIME_COUNTER_VALUE。实现了这两个宏定义后,还必须在文件FreeRTOSConfig.h中将宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS设置为1,此API函数才有效。

&&&这个API函数调用usTaskGetSystemState()函数获取每个任务的状态信息,并把其中的运行时间格式化为程序员易读的字符形式,并将这些信息保存到参数pcWriteBuffer指向的区域。

&&&注意,调用这个函数会挂起所有任务,这一过程可能持续较长时间,因此本函数仅在调试时使用。

11.2参数描述

pcWriteBuffer:任务的运行时间信息会写入这个缓冲区,为ASCII表单形式。这个缓冲区要足够大,以容纳生成的报告,每个任务大约需要40个字节。

11.3用法举例

&&&以lpc17xx系列为控制为例,我们使用定时器0来作为统计基准时钟。

11.3.1使能函数宏

&&&在文件FreeRTOSConfig.h中,设置宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS为1,

11.3.2定时初始化定时器代码

void vConfigureTimerForRunTimeStats( void )
{
    /* 使能定时器0的外设电源,配置外设时钟 */
    PCONP |= 0x02UL;
    PCLKSEL0 = (PCLKSEL0& (~(0x3<<2))) | (0x01 << 2);
    /* 复位定时器 0 */
    T0TCR = 0x02;
    /* 作为计数器 */
    T0CTCR = 0x00;
    /* 预分频,设置合适的分辨率即可 */
    T0PR =  ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
    /* 启动计数器 */
    T0TCR = 0x01;
}

11.3.3定义配置定时器和获取定时时间宏

&&&在文件FreeRTOSConfig.h中,定义下列代码:

extern void vConfigureTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#defineportGET_RUN_TIME_COUNTER_VALUE() T0TC

12.设置任务标签值

12.1函数描述

       voidvTaskSetApplicationTaskTag( TaskHandle_t xTask,
                        TaskHookFunction_tpxTagValue );

&&&可以给每个任务分配一个标签值。这个值一般用于应用程序,RTOS内核不会使用。在文件FreeRTOSConfig.h中,宏configUSE_APPLICATION_TASK_TAG必须设置为1,此函数才有效。

12.2参数描述

xTask:任务句柄。NULL表示当前任务。pxTagValue:要分配给任务的标签值。这是一个TaskHookFunction_t类型的函数指针,但也可以给任务标签分配任意的值。

注:TaskHookFunction_t原型定义:typedef BaseType_t (*TaskHookFunction_t)(void * )

12.3用法举例

/* 在这个例子中,给任务设置一个整形标签值。例子中使用了RTOS跟踪钩子宏。*/
void vATask( void *pvParameters )
{
  /* 为自己的标签分配一个整形值 */
 vTaskSetApplicationTaskTag( NULL, ( void * ) 1 );
  for( ;; )
  {
    /* 任务主体代码 */
  }
}
/*****************************************************************************/
/*在这个任务中,给任务设置一个函数标签值。首先定义一个回调函数,这个函数必须声明为TaskHookFunction_t类型。 */
static BaseType_t prvExampleTaskHook( void * pvParameter )
{
  /* 这里为用户定义代码 –可能是记录数据、更新任务状态值等。*/
  return 0;
}
/* 将回调函数设置为任务的标签值。 */
void vAnotherTask( void *pvParameters )
{
  /* 注册回调函数*/
 vTaskSetApplicationTaskTag( NULL, prvExampleTaskHook );
  for( ;; )
  {
     /* 任务主体代码 */
  }
}
/* 每当任务切换时,会调用xTaskCallApplicationTaskHook 函数(见14.)。 */
#define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook(pxCurrentTCB,0 )

13.获取任务标签值

13.1函数描述

TaskHookFunction_txTaskGetApplicationTaskTag( TaskHandle_t xTask );

返回分配给任务的标签值。程序员定义标签值,RTOS内核通常不会访问标签值。

函数仅对高级用户使用。在文件FreeRTOSConfig.h中,宏configUSE_APPLICATION_TASK_TAG必须设置为1,此函数才有效。

13.2参数描述

xTask:任务句柄。NULL表示当前任务。

13.3返回值

返回指定任务的标签值。

14.执行任务的应用钩子函数

14.1函数描述

         BaseType_txTaskCallApplicationTaskHook(
                                   TaskHandle_txTask,
                                   void*pvParameter );

可以为每个任务分配一个标签值,当这个值是一个TaskHookFunction_t类型函数指针时,相当于应用程序向任务注册了一个回调函数,而API函数xTaskCallApplicationTaskHook用来调用这个回调函数。

一般这个函数配合RTOS跟踪钩子宏使用,见12.设置任务标签值一节的用法举例。

14.2参数描述

xTask:任务句柄。NULL表示当前任务。pvParameter:作为参数传递给应用钩子函数

15.设置线程本地存储指针

15.1函数描述

       void vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet,
                                       BaseType_t xIndex,
                                        void*pvValue )

此函数仅用于高级用户。

线程本地存储允许应用程序在任务的控制块中存储一些值,每个任务都有自己独立的储存空间。

比如,许多库函数都包含一个叫做errno的全局变量。某些库函数使用errno返回库函数错误信息,应用程序检查这个全局变量来确定发生了那些错误。在单线程程序中,将errno定义成全局变量是可以的,但是在多线程应用中,每个线程(任务)必须具有自己独有的errno值,否则,一个任务可能会读取到另一个任务的errno值。

FreeRTOS提供了一个灵活的机制,使得应用程序可以使用线程本地存储指针来读写线程本地存储。在文件FreeRTOSConfig.h中,宏configNUM_THREAD_LOCAL_STORAGE_POINTERS指定每个任务线程本地存储指针数组的大小。API函数vTaskSetThreadLocalStoragePointer()用于向指针数组中写入值,API函数pvTaskGetThreadLocalStoragePointer()用于从指针数组中读取值。

15.2参数描述

xTaskToSet:任务句柄。NULL表示当前任务。

xIndex:写入到线程本地存储数组的索引号,线程本笃存储数组的大小由宏configNUM_THREAD_LOCAL_STORAGE_POINTERS设定,该宏在文件FreeRTOSConfig.h中。

pvValue:写入到指定索引地址的数据值

15.3用法举例

&&参见16.获取线程本地存储指针一节。

16.读取线程本地存储指针

16.1函数描述

         void*pvTaskGetThreadLocalStoragePointer(
                                 TaskHandle_txTaskToQuery,
                                 BaseType_txIndex );

此函数仅用于高级用户。从线程本地存储指针数组中读取值。更详细描述见15.设置线程本地存储指针一节。

16.2参数描写

xTaskToQuery:任务句柄。NULL表示当前任务。

xIndex:写入到线程本地存储数组的索引号,线程本笃存储数组的大小由宏configNUM_THREAD_LOCAL_STORAGE_POINTERS设定,该宏在文件FreeRTOSConfig.h中。

16.3返回值

返回一个指针,这个指针存储在线程本地存储指针数组中,数组索引由参数xIndex指定。

16.4用法举例

16.4.1存储一个整形数

uint32_tulVariable;
/* 向当前任务的线程本地存储数组下标为1的位置写入一个指向32位常量值的指针。*/
vTaskSetThreadLocalStoragePointer(NULL, 1, ( void * ) 0x12345678 );
/*向当前任务的线程本地存储数组下标为0的位置写入一个指向32整形值的指针*/
ulVariable= ERROR_CODE;
vTaskSetThreadLocalStoragePointer(NULL, 0, ( void * ) ulVariable );
/*从当前任务的线程本地存储数组下标为5的位置读取出一个指针并赋值给32位整形变量。*/
ulVariable= ( uint32_t ) pvTaskGetThreadLocalStoragePointer( NULL, 5 );

16.4.2存储结构提

typedefstruct
{
    uint32_t ulValue1;
    uint32_t ulValue2;
}xExampleStruct;
xExampleStruct*pxStruct;
/*为结构体分配内存*/
pxStruct= pvPortMalloc( sizeof( xExampleStruct ) );
/*为结构体成员赋值*/
pxStruct->ulValue1= 0;
pxStruct->ulValue2= 1;
/*向当前任务的线程本地存储数组下标为0的位置写入一个指向结构体变量的指针*/
vTaskSetThreadLocalStoragePointer(NULL, 0, ( void * ) pxStruct );
/*从当前任务的线程本地存储数组下标为0的位置读取出一个结构体指针*/
pxStruct= ( xExampleStruct * ) pvTaskGetThreadLocalStoragePointer( NULL, 0 );

17.设置超时状态

17.1函数描述

void vTaskSetTimeOutState( TimeOut_t *const pxTimeOut );

此函数仅用于高级用户,通常与API函数xTaskCheckForTimeOut()共同使用。

任务因为等待某事件而进入阻塞状态,通常情况下任务会设置一个等待超时周期。如果在等待事件超时,任务会退出阻塞状态。想象一个这样的应用,某任务等待一个事件而进入阻塞状态,但是事件迟迟不发生,超时后任务退出阻塞状态继续执行任务。假如任务等待的事件仍然没有发生,则任务又会阻塞在该事件下。只要任务等待的事件一直不发生,这个任务进入阻塞然后超时退出阻塞,再进入阻塞的循环就会一直存在。是不是可以设定一个总超时时间,只要总阻塞时间大于这个总超时时间,则可以结束这个任务或进行相应记录?freeRTOS提供了两个API函数来完成这个功能,这就是vTaskSetTimeOutState()和xTaskCheckForTimeOut()。

vTaskSetTimeOutState()函数用于设置初始条件,之后调用xTaskCheckForTimeOut()函数检查任务总阻塞时间是否超过总超时时间,如果没有超过,则调整剩余的超时时间计数器。

17.2参数描述

pxTimeOut:指向一个结构体的指针,该结构体用来保存确定超时是否发生的必要信息。vTaskSetTimeOutState()函数会设置结构体的成员。

17.3用法举例

参见18.超时检测。

18.超时检测

18.1函数描述

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

此函数仅用于高级用户,通常与API函数vTaskSetTimeOutState共同使用。

详细描述见17.设置超时状态。

18.2参数描述

pxTimeOut:指向一个结构体的指针。该结构体保存确定超时是否发生的必要信息。使用API函数vTaskSetTimeOutState初始化该结构体。

pxTicksToWait:TickType_t指针,指向的变量保存总超时时间。

18.3返回值

pdTRUE:总超时发生pdFALSE:总超时未发生

18.4用法举例

/* 函数用于从RX缓冲区中接收uxWantedBytes字节数据,RX缓冲区由UART中断填充。如果RX缓冲区没有足够的数据,则任务进入阻塞状态,直到RX缓冲区有足够数据或者发生超时。如果超时后仍然没有足够的数据,则任务会再次进入阻塞状态,xTaskCheckForTimeOut()函数用于重新计算总超时时间以确保总阻塞状态时间不超过MAX_TIME_TO_WAIT。如果总阻塞状态时间大于了总超时时间,则不管RX缓冲区是否有充足数据,都将这些数据读出来。
 */
size_txUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes )
{
    size_t uxReceived = 0;
    TickType_t xTicksToWait = MAX_TIME_TO_WAIT;
    TimeOut_t xTimeOut;
    /* 初始化结构体变量xTimeOut。*/
   vTaskSetTimeOutState( &xTimeOut );
   /* 无限循环,直到缓冲区包含足够的数据或者阻塞超时发生。*/
   while( UART_bytes_in_rx_buffer(pxUARTInstance ) < uxWantedBytes )
   {
      /* RX缓冲区没有足够多的数据,表示任务已经进入过一次阻塞状态。调用API函数xTaskCheckForTimeOut检查总阻塞时间是否超过总超时时间,如果没有,则调整剩余的总超时时间。*/
      if( xTaskCheckForTimeOut( &xTimeOut,&xTicksToWait ) != pdFALSE )
      {
         /* 如果总阻塞时间大于总超时时间,则退出这个循环 */
         break;
      }
       /* 在等待了xTicksToWait个系统节拍周期后,向接收中断发出通知,需要更多数据。
*/
      ulTaskNotifyTake( pdTRUE, xTicksToWait );
   }
     /*从RX缓冲区读取uxWantedBytes个字节并放到pucBuffer缓冲区。*/
    uxReceived = UART_read_from_receive_buffer(pxUARTInstance,  pucBuffer,  uxWantedBytes );
     return uxReceived;
}

以上就是FreeRTOS实时操作系统的任务应用函数详解的详细内容,更多关于FreeRTOS任务应用函数的资料请关注我们其它相关文章!

(0)

相关推荐

  • FreeRTOS实时操作系统空闲任务的阻塞延时实现

    目录 什么是阻塞延时.为什么需要空闲任务 空闲任务的实现 阻塞延时的实现 xTicksToDelay 递减 SysTick初始化 仿真 什么是阻塞延时.为什么需要空闲任务 RTOS中的延时叫阻塞延时,即任务需要延时时,任务会放弃cpu使用权,cpu转而去做其他的事,当任务延时时间到后,任务重新请求获得cpu使用权.但当所有的任务都处于阻塞后,为了不让cpu空闲没事干就需要一个空闲任务让cpu干活. 空闲任务的实现 空闲任务实现和创建普通任务没区别,空闲任务在调用vTaskStartSchedul

  • FreeRTOS任务控制API函数的功能分析

    目录 1.相对延时 1.1函数描述 1.2参数描述 1.3用法举例 2.绝对延时 2.1函数描述 2.2参数描述 2.3用法举例 3.获取任务优先级 3.1函数描述 3.2参数描述 3.3返回值 3.4用法举例 4.设置任务优先级 4.1函数描述 4.2参数描述 4.3用法举例 5.任务挂起 5.1函数描述 5.2参数描述 5.3用法举例 6.恢复挂起的任务 6.1函数描述 6.2参数描述 7.恢复挂起的任务(在中断服务函数中使用) 7.1函数描述 7.2参数描述 7.3返回值 7.4用法举例

  • FreeRTOS实时操作系统的任务概要讲解

    目录 1. 任务和协程(Co-routines) 1.1任务的特性 1.2任务概要 2. 任务状态 3.任务优先级 4.实现一个任务 5.空闲任务和空闲任务钩子(idle task和Idle Task hook) 5.1空闲任务 5.2空闲任务钩子 1. 任务和协程(Co-routines) 应用程序可以使用任务也可以使用协程,或者两者混合使用,但是任务和协程使用不同的API函数,因此在任务和协程之间不能使用同一个队列或信号量传递数据. 通常情况下,协程仅用在资源非常少的微处理器中,特别是RAM

  • FreeRTOS实时操作系统多任务管理基础知识

    目录 什么是多任务系统? FreeRTOS  任务与协程 1.任务(Task) 的特性 2.协程(Co-routine)的特性 任务状态 运行态 就绪态 阻塞态 挂起态 任务优先级 任务实现 任务控制块 任务堆栈 RTOS 系统的核心就是任务管理,FreeRTOS 也不例外,而且大多数学习 RTOS 系统的工程师或者学生主要就是为了使用 RTOS 的多任务处理功能,初步上手 RTOS 系统首先必须掌握的也是任务的创建.删除.挂起和恢复等操作,由此可见任务管理的重要性. 什么是多任务系统? 回想一

  • FreeRTOS实时操作系统的任务创建和删除

    目录 前言 1.任务创建 1.1函数描述 1.2参数描述 1.3返回值 1.4用法举例 2.任务删除 2.1任务描述 2.2参数描述 前言 在FreeRTOS移植到Cortex-M3硬件平台的文章中,我们已经见过任务创建API,但那篇文章的重点在于如何移植FreeRTOS,本文将重点放在任务的创建和删除API函数上面. 任务创建和删除API函数位于文件task.c中,需要包含task.h头文件. 1.任务创建 1.1函数描述 BaseType_t xTaskCreate( TaskFunctio

  • freertos实时操作系统空闲任务阻塞延时示例解析

    阻塞态:如果一个任务当前正在等待某个外部事件,则称它处于阻塞态. rtos中的延时叫阻塞延时,即任务需要延时的时候,会放弃CPU的使用权,进入阻塞状态.在任务阻塞的这段时间,CPU可以去执行其它的任务(如果其它的任务也在延时状态,那么 CPU 就将运行空闲任务),当任务延时时间到,重新获取 CPU 使用权,任务继续运行. 空闲任务:处理器空闲的时候,运行的任务.当系统中没有其他就绪任务时,空闲任务开始运行,空闲任务的优先级是最低的. 空闲任务 定义空闲任务: #define portSTACK_

  • FreeRTOS实时操作系统的任务创建与任务切换

    目录 任务控制块数据结构 任务创建函数 定义就绪表 就绪表初始化 启动调度器 任务切换 任务控制块数据结构 任务控制块数据结构在task.c声明 typedef struct tskTaskControlBlock { volatile StackType_t * pxTopOfStack; //栈顶指针 ListItem_t xStateListItem; //任务节点 StackType_t * pxStack; //任务栈起始地址 char pcTaskName[configMAX_TAS

  • FreeRTOS实时操作系统的任务应用函数详解

    目录 1.获取任务系统状态 1.1函数描述 1.2参数描述 1.3返回值 1.4用法举例 2.获取当前任务句柄 2.1函数描述 2.2返回值 3.获取空闲任务句柄 3.1函数描述 3.2返回值 4.获取任务堆栈最大使用深度 4.1函数描述 4.2参数描述 4.3返回值 4.4用法举例 5.获取任务状态 5.1函数描述 5.2参数描述 5.3返回值 6.获取任务描述内容 6.1函数描述 6.2参数描述 6.3返回值 7.获取系统节拍次数 7.1函数描述 7.2返回值 8.获取调度器状态 8.1函数

  • FreeRTOS实时操作系统支持时间片示例详解

    目录 什么是时间片 时间片实现关键 taskSELECT_HIGHEST_PRIORITY_TASK() taskRESET_READY_PRIORITY() 什么是时间片 时间片就是同一个优先级下可以有多个任务,每个任务轮流地享有相同的 CPU 时间, 享有 CPU 的时间我们叫时间片.在 RTOS 中,最小的时间单位为一个 tick,即 SysTick 的中断周期,与其说 FreeRTOS 支持时间片,倒不如说它的时间片就是正常的任务调度. 时间片实现关键 时间片实现关键在这两个宏. tas

  • Vue渲染函数详解

    前面的话 Vue 推荐在绝大多数情况下使用 template 来创建HTML.然而在一些场景中,真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接近编译器.本文将详细介绍Vue渲染函数 引入 下面是一个例子,如果要实现类似下面的效果.其中,H标签可替换 <h1> <a name="hello-world" href="#hello-world" rel="external nofol

  • PHP输出缓冲控制Output Control系列函数详解

    概述 以前研究过PHP的输入输出缓冲,不过博客搬家以后,原来文章找不到了,今天看到一篇好文,顺便转载过来. 简介 说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会向磁盘写入的,而是写到buffer中,当buffer写满或者执行了保存操作,才会将数据写入磁盘.对于PHP来说,每一次像 echo 这样的输出操作,同样是先写入到了 php buffer 里,在脚本执行完毕或者执行了强制输出缓存操作,数据才会

  • OraclePL/SQL单行函数和组函数详解

    正在看的ORACLE教程是:OraclePL/SQL单行函数和组函数详解. 1 函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类:  2  3 单行函数  4  5 组函数   6  7 本文将讨论如何利用单行函数以及使用规则.  8  9 SQL中的单行函数 10 11 SQL和PL/SQL中自带很多类型的函数,有字符.数字.日期.转换.和混合型等多种函数用于处理单行数据,因此这些都可被统称

  • C语言中随机数rand()函数详解

      在生活中很多场景下都需要产生随机数,比如抽奖,打牌,游戏等场景下就需要使用随机数.在C语言标准库函数里面有专门用来产生随机数的函数rand,它的函数原型如下: int __cdecl rand(void);   rand函数没有参数,它的返回值就是随机数.下面通过一个简单的例子来测试一下rand函数. #include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { int i; i = rand(

  • FreeRTOS实时操作系统的内存管理分析

    目录 1.heap_1.c 功能简介: 2.heap_2.c 功能简介: 3.heap_3.c 功能简介: 4.heap_4.c 功能简介: 5.heap_5.c(V8.1.0新增) 前言 本文介绍内存管理的基础知识,详细源码分析见< FreeRTOS内存管理示例分析> FreeRTOS提供了几个内存堆管理方案,有复杂的也有简单的.其中最简单的管理策略也能满足很多应用的要求,比如对安全要求高的应用,这些应用根本不允许动态内存分配的. FreeRTOS也允许你自己实现内存堆管理,甚至允许你同时使

随机推荐