第二章 FreeRTOS任务控制

目录

vTaskDelay

vTaskDelayUntil

uxTaskPriorityGet

vTaskPrioritySet

vTaskSuspend

vTaskResume

xTaskResumeFromISR

xTaskAbortDelay


 

vTaskDelay

void vTaskDelay( const TickType_t xTicksToDelay );

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

将任务延迟给定的滴答数。任务保持阻塞的实际时间取决于滴答率。常量portTICK_PERIOD_MS可用于根据滴答率(分辨率为一个滴答周期)计算实时时间。

vTaskDelay()指定相对于调用vTaskDelay()的时间,任务希望解除阻塞的时间。例如,将阻止时间段指定为100个滴答声将导致任务在调用vTaskDelay()之后取消阻止100个滴答声。因此,vTaskDelay()不能提供一种控制周期性任务频率的好方法,因为通过代码的路径以及其他任务和中断活动将影响vTaskDelay()的调用频率,因此会影响时间接下来执行任务的位置。请参阅vTaskDelayUntil(),了解旨在简化固定频率执行的替代API函数。它通过指定调用任务应解除阻止的绝对时间(而不是相对时间)来实现。

参数:

xTicksToDelay  调用任务应阻塞的时间(以滴答周期为单位)。

用法示例:

void vTaskFunction( void * pvParameters )
 {
 /* Block for 500ms. */
 const TickType_t xDelay = 500 / portTICK_PERIOD_MS;

     for( ;; )
     {
         /* Simply toggle the LED every 500ms, blocking between each toggle. */
         vToggleLED();
         vTaskDelay( xDelay );
     }
}

vTaskDelayUntil

task. h

void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );

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

将任务延迟到指定时间。定期任务可以使用此功能以确保执行频率恒定。

此函数在一个重要方面与vTaskDelay()不同:vTaskDelay()指定任务希望解锁的时间(对于调用vTaskDelay()的时间),而vTaskDelayUntil()指定任务希望的绝对时间解除封锁。

从调用vTaskDelay()开始,vTaskDelay()将导致任务在指定的滴答数内阻塞。因此,很难单独使用vTaskDelay()来生成固定的执行频率,因为在调用vTaskDelay()之后任务解除阻塞与下一次调用vTaskDelay()的任务之间的时间可能不固定[该任务可能采用其他方法两次调用之间的代码路径,或者每次执行时都可能被中断或抢占不同的次数]。

vTaskDelay()指定相对于调用函数的时间的唤醒时间,而vTaskDelayUntil()指定希望解除阻止的绝对(精确)时间。

应当注意,如果vTaskDelayUntil()用于指定过去的唤醒时间,它将立即返回(无阻塞)。因此,如果使用vTaskDelayUntil()定期执行的任务由于某种原因(例如,该任务暂时置于Suspended状态)而导致中止执行,则该任务将不得不重新计算其所需的唤醒时间,从而导致该任务丢失一个或更多定期处决。可以通过将引用作为pxPreviousWakeTime参数传递的变量与当前滴答计数进行比较来检测。但是,在大多数使用情况下,这不是必需的。

常量portTICK_PERIOD_MS可用于根据滴答率(分辨率为一个滴答周期)计算实时时间。

在通过调用vTaskSuspendAll()挂起RTOS调度程序后,不得调用此函数。

参数:

pxPreviousWakeTime  指向变量的指针,该变量保存上一次取消阻止任务的时间。变量必须在首次使用之前用当前时间进行初始化(请参见下面的示例)。此后,变量将在vTaskDelayUntil()中自动更新。
xTimeIncrement  周期时间段。该任务将在时间(* pxPreviousWakeTime + xTimeIncrement)解除阻止。使用相同的xTimeIncrement参数值调用vTaskDelayUntil将使任务以固定的间隔时间执行。

用法示例:

// Perform an action every 10 ticks.
 void vTaskFunction( void * pvParameters )
 {
 TickType_t xLastWakeTime;
 const TickType_t xFrequency = 10;

     // Initialise the xLastWakeTime variable with the current time.
     xLastWakeTime = xTaskGetTickCount();

     for( ;; )
     {
         // Wait for the next cycle.
         vTaskDelayUntil( &xLastWakeTime, xFrequency );

         // Perform action here.
     }
 }

uxTaskPriorityGet

task. h

UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );
 

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

获得任何任务的优先级。

参数:

任务  处理要查询的任务。传递NULL句柄会导致返回调用任务的优先级。

返回值:

xTask的优先级。

用法示例:

void vAFunction( void )
 {
 TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to obtain the priority of the created task.
     // It was created with tskIDLE_PRIORITY, but may have changed
     // it itself.
     if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
     {
         // The task has changed its priority.
     }

     // ...

     // Is our priority higher than the created task?
     if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
     {
         // Our priority (obtained using NULL handle) is higher.
     }
 }

vTaskPrioritySet

task. h

void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );

 

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

设置任何任务的优先级。

如果设置的优先级高于当前执行的任务,则在函数返回之前将进行上下文切换。

参数:

任务  处理要为其设置优先级的任务。传递NULL句柄会导致设置调用任务的优先级。
uxNewPriority  任务将被设置的优先级。

用法示例:

void vAFunction( void )
 {
 TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to raise the priority of the created task.
     vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );

     // ...

     // Use a NULL handle to raise our priority to the same value.
     vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
 }

 


vTaskSuspend

task. h

void vTaskSuspend( TaskHandle_t xTaskToSuspend );

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

暂停任何任务。暂停任务后,无论其优先级如何,都将永远不会获得任何微控制器处理时间。

对vTaskSuspend的调用不是累积性的–即,在同一任务上两次调用vTaskSuspend()仍然只需要对vTaskResume()进行一次调用即可准备挂起的任务。

参数:

xTaskToSuspend  处理被暂停的任务。传递NULL句柄将导致调用任务被挂起。

用法示例:

 void vAFunction( void )
 {
 TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to suspend the created task.
     vTaskSuspend( xHandle );

     // ...

     // The created task will not run during this period, unless
     // another task calls vTaskResume( xHandle ).

     //...

     // Suspend ourselves.
     vTaskSuspend( NULL );

     // We cannot get here unless another task calls vTaskResume
     // with our handle as the parameter.
 }

vTaskResume

task. h

void vTaskResume( TaskHandle_t xTaskToResume );

 

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

恢复暂停的任务。

通过一次调用vTaskResume(),已被一个或多个vTaskSuspend()调用暂停的任务将可以再次运行。

参数:

xTaskToResume  处理正在准备的任务。

用法示例:

void vAFunction( void )
 {
     TaskHandle_t xHandle;

     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ...

     // Use the handle to suspend the created task.
     vTaskSuspend( xHandle );

     // ...

     // The created task will not run during this period, unless
     // another task calls vTaskResume( xHandle ).

     //...

     // Resume the suspended task ourselves.
     vTaskResume( xHandle );

     // The created task will once again get microcontroller processing
     // time in accordance with its priority within the system.
 }

xTaskResumeFromISR

task. h

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume );

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

恢复可从ISR内部调用的挂起任务的功能。

通过对xTaskResumeFromISR()的一次调用,已被多个vTaskSuspend()调用之一暂停的任务将可以再次运行。

xTaskResumeFromISR()通常被认为是危险函数,因为它的动作未锁存。因此,如果中断可能在挂起任务之前到达,因此中断丢失,那么绝对不应将其用于与中断同步任务。使用信号量,或者最好直接使用任务通知,可以避免这种情况的发生。提供了一个使用直接任务通知的工作示例 。

参数:

xTaskToResume  处理正在准备的任务。

返回值:

如果恢复任务,则为pdTRUE,这将导致上下文切换,否则为pdFALSE。ISR使用它来确定在ISR之后是否可能需要上下文切换。

用法示例:

TaskHandle_t xHandle;

 void vAFunction( void )
 {
     // Create a task, storing the handle.
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

     // ... Rest of code.
 }

 void vTaskCode( void *pvParameters )
 {
     // The task being suspended and resumed.
     for( ;; )
     {
         // ... Perform some function here.

         // The task suspends itself.
         vTaskSuspend( NULL );

         // The task is now suspended, so will not reach here until the ISR resumes it.
     }
 }


 void vAnExampleISR( void )
 {
 BaseType_t xYieldRequired;

     // Resume the suspended task.
     xYieldRequired = xTaskResumeFromISR( xHandle );

     if( xYieldRequired == pdTRUE )
     {
         // We should switch context so the ISR returns to a different task.
         // NOTE:  How this is done depends on the port you are using.  Check
         // the documentation and examples for your port.
         portYIELD_FROM_ISR();
     }
 }

 


xTaskAbortDelay

task. h

BaseType_t xTaskAbortDelay( TaskHandle_t xTask );

强制任务离开“ 已阻止”状态,然后进入“就绪”状态,即使该任务处于“已阻止”状态的事件尚未发生,并且任何指定的超时都没有过期。

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

参数:

任务   将被强制退出“阻止”状态的任务的句柄。

要获取任务的句柄,请使用xTaskCreate()创建任务 并使用pxCreatedTask参数,或者使用xTaskCreateStatic()创建任务 并存储返回的值,或者在调用xTaskGetHandle()时使用任务名称。

返回值:

如果xTask引用的任务未处于“阻止”状态,则返回pdFAIL。否则返回pdPASS。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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