第二章 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。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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