Task Control
vTaskDelay
void vTaskDelay( const TickType_t xTicksToDelay );
INCLUDE_vTaskDelay must be defined as 1 for this function to be available.
Delay a task for a given number of ticks. The actual time that the task remains blocked depends on the tick rate. The constant portTICK_PERIOD_MS can be used to calculate real time from the tick rate - with the resolution of one tick period.
vTaskDelay() specifies a time at which the task wishes to unblock relative to the time at which vTaskDelay() is called. For example, specifying a block period of 100 ticks will cause the task to remain blocked for 100 ticks after vTaskDelay() is called. The task will be unblocked on the 100th tick after vTaskDelay() is called.
vTaskDelay() does not therefore provide a good method of controlling the frequency of a periodic task as the path taken through the code, as well as other task and interrupt activity, will effect the frequency at which vTaskDelay() gets called and therefore the time at which the task next executes. See vTaskDelayUntil() for an alternative API function designed to facilitate fixed frequency execution. It does this by specifying an absolute time (rather than a relative time) at which the calling task should unblock.
Passing 0 to vTaskDelay() shall yield to next ready task of equal priority.
-
Parameters
- xTicksToDelay: The amount of time, in tick periods, that the calling task should block.
-
Example
void vTaskFunction( void * pvParameters )
{
const TickType_t xDelay = 500 / portTICK_PERIOD_MS;
for( ;; )
{
vToggleLED();
vTaskDelay( xDelay );
}
}
vTaskDelayUntil
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime,
const TickType_t xTimeIncrement );
Prefer INCLUDE_xTaskDelayUntil for new projects. It must be defined as 1 for this function to be available
Delay a task until a specified time. This function can be used by periodic tasks to ensure a constant execution frequency.
This function differs from vTaskDelay() in one important aspect: vTaskDelay() specifies a time at which the task wishes to unblock relative to the time at which vTaskDelay() is called, whereas vTaskDelayUntil() specifies an absolute time at which the task wishes to unblock.
The constant portTICK_PERIOD_MS can be used to calculate real time from the tick rate - with the resolution of one tick period.
-
Parameters:
-
pxPreviousWakeTime: Pointer to a variable that holds the time at which the task was last unblocked. The variable must be initialised with the current time prior to its first use (see the example below). Following this the variable is automatically updated within vTaskDelayUntil().
-
xTimeIncrement: The cycle time period. The task will be unblocked at time (*pxPreviousWakeTime + xTimeIncrement). Calling vTaskDelayUntil with the same xTimeIncrement parameter value will cause the task to execute with a fixed interval period.
-
Example:
void vTaskFunction( void * pvParameters )
{
TickType_t xLastWakeTime;
const TickType_t xFrequency = 10;
xLastWakeTime = xTaskGetTickCount();
for( ;; )
{
vTaskDelayUntil( &xLastWakeTime, xFrequency );
}
}
xTaskDelayUntil
BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime,
const TickType_t xTimeIncrement );
INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available.
-
Parameters:
-
pxPreviousWakeTime: Pointer to a variable that holds the time at which the task was last unblocked. The variable must be initialised with the current time prior to its first use (see the example below). Following this the variable is automatically updated within vTaskDelayUntil().
-
xTimeIncrement: The cycle time period. The task will be unblocked at time (*pxPreviousWakeTime + xTimeIncrement). Calling vTaskDelayUntil with the same xTimeIncrement parameter value will cause the task to execute with a fixed interval period.
-
Returns:
- A value which can be used to check whether the task was actually delayed:
pdTRUE if the task was delayed and pdFALSE otherwise. A task will not be delayed if the next expected wake time is in the past.
Note: A return value of pdTRUE does not guarantee that pxPreviousWakeTime to be greater than the current tick count. If the calling task becomes unblocked but is not able to execute due to a higher priority task executing, drift may occur.
void vTaskFunction( void * pvParameters )
{
TickType_t xLastWakeTime;
const TickType_t xFrequency = 10;
BaseType_t xWasDelayed;
xLastWakeTime = xTaskGetTickCount ();
for( ;; )
{
xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency );
}
}
uxTaskPriorityGet
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );
INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available.
-
Parameters:
- xTask: Handle of the task to be queried. Passing a NULL handle results in the priority of the calling task being returned.
-
Returns:
void vATaskFunction( void * pvParams )
{
TaskHandle_t xHandle;
( void ) pvParams;
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
{
}
if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
{
}
}
vTaskPrioritySet
void vTaskPrioritySet( TaskHandle_t xTask,
UBaseType_t uxNewPriority );
INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.
- Parameters:
-
xTask: Handle of the task whose priority is being set. A NULL handle sets the priority of the calling task.
-
uxNewPriority: The priority to which the task will be set. Priorities are asserted to be less than configMAX_PRIORITIES. If configASSERT is undefined, priorities are silently capped at (configMAX_PRIORITIES - 1).
void vAFunction( void )
{
TaskHandle_t xHandle;
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 )
vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
}
vTaskSuspend
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
Suspend any task. When suspended a task will never get any microcontroller processing time, no matter what its priority.
Calls to vTaskSuspend are not accumulative - i.e. calling vTaskSuspend() twice on the same task still only requires one call to vTaskResume() to ready the suspended task.
-
Parameters:
xTaskToSuspend: Handle to the task being suspended. Passing a NULL handle will cause the calling task to be suspended.
-
Example:
void vAFunction( void )
{
TaskHandle_t xHandle;
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
vTaskSuspend( xHandle );
vTaskSuspend( NULL );
}
vTaskResume
void vTaskResume( TaskHandle_t xTaskToResume );
INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
A task that has been suspended by one or more calls to vTaskSuspend() will be made available for running again by a single call to vTaskResume().
-
Parameters:
- xTaskToResume: Handle to the task being readie
-
Example:
void vAFunction( void )
{
TaskHandle_t xHandle;
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
vTaskSuspend( xHandle );
vTaskResume( xHandle );
}
xTaskResumeFromISR
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume );
INCLUDE_vTaskSuspend and INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be available.
A function to resume a suspended task that can be called from within an ISR.
A task that has been suspended by one of more calls to vTaskSuspend() will be made available for running again by a single call to xTaskResumeFromISR().
xTaskResumeFromISR() is generally considered a dangerous function because its actions are not latched. For this reason it should definitely not be used to synchronise a task with an interrupt if there is a chance that the interrupt could arrive prior to the task being suspended, and therefore the interrupt being lost. Use of a semaphore, or preferable a direct to task notification, would avoid this eventuality.
-
Parameters:
- xTaskToResume: Handle to the task being readied.
-
Returns:
- pdTRUE if resuming the task should result in a context switch,
- pdFALSE otherwise. This is used by the ISR to determine if a context switch may be required following the ISR.
-
Example:
TaskHandle_t xHandle;
void vAFunction( void )
{
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
}
void vTaskCode( void *pvParameters )
{
for( ;; )
{
vTaskSuspend( NULL );
}
}
void vAnExampleISR( void )
{
BaseType_t xYieldRequired;
xYieldRequired = xTaskResumeFromISR( xHandle );
portYIELD_FROM_ISR( xYieldRequired );
}
xTaskAbortDelay
BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
Forces a task to leave the Blocked state, and enter the Ready state, even if the event the task was in the Blocked state to wait for has not occurred, and any specified timeout has not expired.
INCLUDE_xTaskAbortDelay must be defined as 1 for this function to be available.
-
Parameters:
-
xTask: The handle of the task that will be forced out of the Blocked state.
To obtain a task’s handle create the task using xTaskCreate() and make use of the pxCreatedTask parameter, or create the task using xTaskCreateStatic() and store the returned value, or use the task’s name in a call to xTaskGetHandle().
-
Returns:
- If the task referenced by xTask was not in the Blocked state then pdFAIL is returned. Otherwise pdPASS is returned.
uxTaskPriorityGetFromISR
UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask );
INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available.
Obtain the priority of any task. This function is safe to use from within an interrupt service routine (ISR).
-
Parameters:
- xTask: Handle of the task to be queried. Passing a NULL handle results in the priority of the calling task being returned.
-
Returns:
uxTaskBasePriorityGet
UBaseType_t uxTaskBasePriorityGet( const TaskHandle_t xTask );
INCLUDE_uxTaskPriorityGet and configUSE_MUTEXES must be defined as 1 for this function to be available.
Obtain the base priority of any task. The base priority of a task is 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.
-
Parameters:
- xTask: Handle of the task to be queried. Passing a NULL handle results in the priority of the calling task being returned.
-
Returns:
uxTaskBasePriorityGetFromISR
UBaseType_t uxTaskBasePriorityGetFromISR( const TaskHandle_t xTask );
INCLUDE_uxTaskPriorityGet and configUSE_MUTEXES must be defined as 1 for this function to be available.
Obtain the base priority of any task. The base priority of a task is 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. This function is safe to use from within an interrupt service routine (ISR).
-
Parameters:
- xTask: Handle of the task to be queried. Passing a NULL handle results in the priority of the calling task being returned.
-
Returns:
Real Example
extern "C" {
#include "./flash_led.hpp"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <stdio.h>
namespace LED {
int count_slow = 0;
int count_fast = 0;
int max_count = 10;
void flash_led_task(void *pvParameters) {
LED_Parameters *params = (LED_Parameters *)pvParameters;
gpio_config_t conf;
conf.mode = GPIO_MODE_OUTPUT;
conf.pin_bit_mask = 1ULL << params->gpio;
conf.pull_up_en = GPIO_PULLUP_ENABLE;
conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
esp_err_t err = gpio_config(&conf);
printf("errcode %d\r\n", err);
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
gpio_set_level(params->gpio, 1);
printf("led on\r\n");
vTaskDelay(pdMS_TO_TICKS(1000));
gpio_set_level(params->gpio, 0);
printf("led off\r\n");
printf("count: %d\n", count_slow);
if (count_slow < max_count) {
count_slow++;
} else {
count_slow = 0;
vTaskResume(params->fast_handle);
printf("resume fast func\n");
vTaskSuspend(NULL);
}
}
}
void fast_flash_led_task(void *pvParameters) {
LED_Parameters *params = (LED_Parameters *)pvParameters;
printf("suspend fast func\n");
vTaskSuspend(NULL);
while (true) {
vTaskDelay(pdMS_TO_TICKS(300));
gpio_set_level(params->gpio, 1);
printf("led on\r\n");
vTaskDelay(pdMS_TO_TICKS(300));
gpio_set_level(params->gpio, 0);
printf("led off\r\n");
if (count_fast < max_count) {
count_fast++;
} else {
count_fast = 0;
vTaskResume(params->led_handle);
printf("suspend fast func\n");
vTaskSuspend(NULL);
}
}
}
}
}
#include "./led/flash_led.hpp"
#include "driver/gpio.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"
#include <inttypes.h>
#include <stdio.h>
#define STACK_SIZE 2048
extern "C" void app_main(void) {
TaskHandle_t xHandle;
TaskHandle_t xFastHandle;
static gpio_num_t led_gpio = GPIO_NUM_0;
static LED::LED_Parameters led_param;
led_param.gpio = led_gpio;
xTaskCreate(LED::flash_led_task, "flash_led", STACK_SIZE, &led_param,
tskIDLE_PRIORITY, &xHandle);
xTaskCreate(LED::fast_flash_led_task, "fast_flash_led", STACK_SIZE,
&led_param, tskIDLE_PRIORITY, &xFastHandle);
led_param.led_handle = xHandle;
led_param.fast_handle = xFastHandle;
}
Reference
Task Control