vTaskDelayUntil() helps tasks run at exact time intervals. It keeps timing steady even if the task takes different amounts of time to run.
vTaskDelayUntil() for precise timing in FreeRTOS
void vTaskDelayUntil(TickType_t *pxPreviousWakeTime, TickType_t xTimeIncrement);
pxPreviousWakeTime is a pointer to a variable holding the last wake time.
xTimeIncrement is how many ticks to wait between runs.
TickType_t xLastWakeTime; xLastWakeTime = xTaskGetTickCount(); for(;;) { // Task code here vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(100)); }
TickType_t xLastWakeTime = xTaskGetTickCount();
vTaskDelayUntil(&xLastWakeTime, 50);This program creates a task that prints the current tick count every 500 milliseconds exactly, using vTaskDelayUntil() for precise timing.
#include "FreeRTOS.h" #include "task.h" #include <stdio.h> void vTaskFunction(void *pvParameters) { TickType_t xLastWakeTime; const TickType_t xFrequency = pdMS_TO_TICKS(500); // 500 ms xLastWakeTime = xTaskGetTickCount(); for(;;) { printf("Task running at tick: %lu\n", xTaskGetTickCount()); vTaskDelayUntil(&xLastWakeTime, xFrequency); } } int main(void) { xTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, NULL); vTaskStartScheduler(); for(;;); return 0; }
Always initialize pxPreviousWakeTime with xTaskGetTickCount() before the first call.
vTaskDelayUntil() helps avoid drift that happens with simple delay functions.
If the task runs longer than the delay period, the next wake time will be in the past, so the task runs immediately to catch up.
vTaskDelayUntil() keeps task timing steady and precise.
Use it when you want tasks to run at fixed intervals without drift.
Initialize the last wake time before the loop and pass it by pointer each time.
Practice
vTaskDelayUntil() in FreeRTOS?Solution
Step 1: Understand the function's purpose
vTaskDelayUntil()is designed to delay a task until a specific time, maintaining a fixed periodic interval.Step 2: Compare options with function behavior
Only To delay a task until a fixed periodic time, keeping timing precise describes this precise periodic delay. Other options describe unrelated behaviors.Final Answer:
To delay a task until a fixed periodic time, keeping timing precise -> Option AQuick Check:
Precise periodic delay = A [OK]
- Confusing vTaskDelayUntil with vTaskDelay
- Thinking it suspends tasks indefinitely
- Assuming it resumes tasks immediately
vTaskDelayUntil() to track the last wake time?Solution
Step 1: Identify the correct type for last wake time
The FreeRTOS API specifiesTickType_tas the type for tick counts and time tracking.Step 2: Initialization rules for vTaskDelayUntil
The variable must be declared but not necessarily initialized to zero; it is initialized by callingxLastWakeTime = xTaskGetTickCount();before the loop.Final Answer:
TickType_t xLastWakeTime; -> Option CQuick Check:
Use TickType_t without initial zero for last wake time [OK]
- Using int instead of TickType_t
- Initializing to zero instead of using xTaskGetTickCount()
- Using void pointer type
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
for (;;) {
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(1000));
printf("Task running\n");
}Solution
Step 1: Understand vTaskDelayUntil behavior
It delays the task until the next fixed interval based on the last wake time, keeping timing steady.Step 2: Analyze the delay duration
The delay is set to 1000 ms converted to ticks, so the task runs approximately every 1000 ms without accumulating drift.Final Answer:
Approximately 1000 milliseconds, steady without drift -> Option AQuick Check:
vTaskDelayUntil = steady periodic delay [OK]
- Assuming exact millisecond precision
- Confusing with vTaskDelay which causes drift
- Thinking delay varies randomly
vTaskDelayUntil():
void vTaskFunction(void *pvParameters) {
TickType_t xLastWakeTime = 0;
for (;;) {
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(500));
// Task code here
}
}Solution
Step 1: Check initialization of xLastWakeTime
It must be initialized to the current tick count usingxTaskGetTickCount()before the loop to set the reference time.Step 2: Verify usage of vTaskDelayUntil
The function is correctly used inside the loop, and pdMS_TO_TICKS is valid for converting milliseconds to ticks.Final Answer:
xLastWakeTime should be initialized with xTaskGetTickCount() before the loop -> Option DQuick Check:
Initialize xLastWakeTime with xTaskGetTickCount() [OK]
- Not initializing xLastWakeTime before loop
- Misusing vTaskDelayUntil outside loops
- Incorrect delay parameter types
vTaskDelayUntil() to achieve this?Solution
Step 1: Understand timing requirements
The task must run every 200 ms total, including 50 ms execution time, so delay should be 200 ms fixed interval.Step 2: Correct usage of vTaskDelayUntil
InitializexLastWakeTimewithxTaskGetTickCount()before the loop, then callvTaskDelayUntil()with 200 ms delay after task code to maintain steady timing without drift.Final Answer:
Initialize xLastWakeTime with xTaskGetTickCount() before the loop, then call vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(200)) inside the loop after task code -> Option BQuick Check:
Init last wake time + vTaskDelayUntil with full period = D [OK]
- Using vTaskDelay instead of vTaskDelayUntil causing drift
- Not accounting for task execution time in delay
- Initializing xLastWakeTime incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
