Bird
Raised Fist0
FreeRTOSprogramming~20 mins

vTaskDelayUntil() for precise timing in FreeRTOS - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
vTaskDelayUntil Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this FreeRTOS task timing code?

Consider a FreeRTOS task using vTaskDelayUntil() to run every 100 ticks. What will be the output timestamps printed by the task?

FreeRTOS
TickType_t xLastWakeTime;

void vTaskFunction(void *pvParameters) {
    xLastWakeTime = xTaskGetTickCount();
    for (int i = 0; i < 3; i++) {
        vTaskDelayUntil(&xLastWakeTime, 100);
        printf("Tick: %lu\n", xTaskGetTickCount());
    }
}
ATick: 101\nTick: 201\nTick: 301
BTick: 100\nTick: 200\nTick: 300
CTick: 100\nTick: 201\nTick: 302
DTick: 0\nTick: 100\nTick: 200
Attempts:
2 left
💡 Hint

Remember that vTaskDelayUntil() delays the task until the next fixed tick count based on xLastWakeTime.

🧠 Conceptual
intermediate
1:30remaining
Why use vTaskDelayUntil() instead of vTaskDelay() for periodic tasks?

Which reason best explains why vTaskDelayUntil() is preferred over vTaskDelay() for tasks that must run at precise intervals?

AvTaskDelayUntil() maintains a fixed periodic rate by accounting for task execution time, while vTaskDelay() delays relative to the current time causing drift.
BvTaskDelayUntil() uses less CPU than vTaskDelay() because it disables interrupts during delay.
CvTaskDelayUntil() allows tasks to run faster than the specified delay, while vTaskDelay() enforces a strict minimum delay.
DvTaskDelayUntil() automatically adjusts task priority during delay, vTaskDelay() does not.
Attempts:
2 left
💡 Hint

Think about how each function calculates the delay period relative to time.

🔧 Debug
advanced
2:30remaining
Identify the bug causing timing drift in this FreeRTOS task

This task is intended to run every 50 ticks using vTaskDelayUntil(). However, the timing drifts and the task runs slower than expected. What is the bug?

FreeRTOS
TickType_t xLastWakeTime;

void vTaskFunction(void *pvParameters) {
    for (;;) {
        xLastWakeTime = xTaskGetTickCount();
        vTaskDelayUntil(&xLastWakeTime, 50);
        printf("Tick: %lu\n", xTaskGetTickCount());
    }
}
AxLastWakeTime is reset inside the loop each iteration, so the delay is always relative to the current tick count causing drift.
BxLastWakeTime is not declared as volatile, so the compiler optimizes it incorrectly.
CThe task does not call vTaskDelay() before vTaskDelayUntil(), causing starvation.
DvTaskDelayUntil() is called with the wrong delay value; it should be 100 instead of 50.
Attempts:
2 left
💡 Hint

Check where xLastWakeTime is initialized and updated.

📝 Syntax
advanced
2:00remaining
Which option correctly uses vTaskDelayUntil() for a 200 tick periodic task?

Choose the code snippet that correctly implements a FreeRTOS task running every 200 ticks using vTaskDelayUntil().

A
TickType_t xLastWakeTime = 0;
for (;;) {
    vTaskDelayUntil(&amp;xLastWakeTime, 200);
    // Task code
}
B
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
for (;;) {
    vTaskDelayUntil(xLastWakeTime, 200);
    // Task code
}
C
TickType_t xLastWakeTime = xTaskGetTickCount();
for (;;) {
    vTaskDelayUntil(&amp;xLastWakeTime, 200);
    // Task code
}
D
TickType_t xLastWakeTime;
for (;;) {
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil(&amp;xLastWakeTime, 200);
    // Task code
}
Attempts:
2 left
💡 Hint

Remember the correct way to initialize and update xLastWakeTime for vTaskDelayUntil().

🚀 Application
expert
1:30remaining
Calculate the number of task executions in 1000 ticks using vTaskDelayUntil()

A FreeRTOS task uses vTaskDelayUntil() with a delay of 120 ticks to run periodically. How many times will the task execute within 1000 ticks?

A7
B8
C10
D9
Attempts:
2 left
💡 Hint

Divide the total ticks by the delay period and consider the first execution timing.

Practice

(1/5)
1. What is the main purpose of vTaskDelayUntil() in FreeRTOS?
easy
A. To delay a task until a fixed periodic time, keeping timing precise
B. To delay a task for a random amount of time
C. To suspend a task indefinitely
D. To immediately resume a suspended task

Solution

  1. Step 1: Understand the function's purpose

    vTaskDelayUntil() is designed to delay a task until a specific time, maintaining a fixed periodic interval.
  2. 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.
  3. Final Answer:

    To delay a task until a fixed periodic time, keeping timing precise -> Option A
  4. Quick Check:

    Precise periodic delay = A [OK]
Hint: vTaskDelayUntil keeps timing steady, not random delays [OK]
Common Mistakes:
  • Confusing vTaskDelayUntil with vTaskDelay
  • Thinking it suspends tasks indefinitely
  • Assuming it resumes tasks immediately
2. Which of the following is the correct way to declare the variable used with vTaskDelayUntil() to track the last wake time?
easy
A. TickType_t xLastWakeTime = 0;
B. int xLastWakeTime = 0;
C. TickType_t xLastWakeTime;
D. void *xLastWakeTime = NULL;

Solution

  1. Step 1: Identify the correct type for last wake time

    The FreeRTOS API specifies TickType_t as the type for tick counts and time tracking.
  2. Step 2: Initialization rules for vTaskDelayUntil

    The variable must be declared but not necessarily initialized to zero; it is initialized by calling xLastWakeTime = xTaskGetTickCount(); before the loop.
  3. Final Answer:

    TickType_t xLastWakeTime; -> Option C
  4. Quick Check:

    Use TickType_t without initial zero for last wake time [OK]
Hint: Declare with TickType_t, initialize with xTaskGetTickCount() [OK]
Common Mistakes:
  • Using int instead of TickType_t
  • Initializing to zero instead of using xTaskGetTickCount()
  • Using void pointer type
3. Given the code snippet below, what will be the approximate delay between each "Task running" print?
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();

for (;;) {
    vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(1000));
    printf("Task running\n");
}
medium
A. Approximately 1000 milliseconds, steady without drift
B. Exactly 1000 milliseconds between prints
C. Variable delay, sometimes less than 1000 milliseconds
D. No delay, prints continuously

Solution

  1. Step 1: Understand vTaskDelayUntil behavior

    It delays the task until the next fixed interval based on the last wake time, keeping timing steady.
  2. 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.
  3. Final Answer:

    Approximately 1000 milliseconds, steady without drift -> Option A
  4. Quick Check:

    vTaskDelayUntil = steady periodic delay [OK]
Hint: vTaskDelayUntil keeps intervals steady, not exact but no drift [OK]
Common Mistakes:
  • Assuming exact millisecond precision
  • Confusing with vTaskDelay which causes drift
  • Thinking delay varies randomly
4. Identify the error in the following FreeRTOS task code using vTaskDelayUntil():
void vTaskFunction(void *pvParameters) {
    TickType_t xLastWakeTime = 0;
    for (;;) {
        vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(500));
        // Task code here
    }
}
medium
A. vTaskDelayUntil() should not be used inside a loop
B. TickType_t cannot be initialized to zero
C. pdMS_TO_TICKS() cannot be used as a delay parameter
D. xLastWakeTime should be initialized with xTaskGetTickCount() before the loop

Solution

  1. Step 1: Check initialization of xLastWakeTime

    It must be initialized to the current tick count using xTaskGetTickCount() before the loop to set the reference time.
  2. 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.
  3. Final Answer:

    xLastWakeTime should be initialized with xTaskGetTickCount() before the loop -> Option D
  4. Quick Check:

    Initialize xLastWakeTime with xTaskGetTickCount() [OK]
Hint: Always init last wake time with xTaskGetTickCount() before loop [OK]
Common Mistakes:
  • Not initializing xLastWakeTime before loop
  • Misusing vTaskDelayUntil outside loops
  • Incorrect delay parameter types
5. You want a FreeRTOS task to run exactly every 200 ms without drift, but your task sometimes takes 50 ms to execute. How should you use vTaskDelayUntil() to achieve this?
hard
A. Use vTaskDelayUntil() with 50 ms delay to match task execution time
B. Initialize xLastWakeTime with xTaskGetTickCount() before the loop, then call vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(200)) inside the loop after task code
C. Initialize xLastWakeTime to zero and call vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(250)) before task code
D. Call vTaskDelay(pdMS_TO_TICKS(200)) after task code to delay fixed 200 ms

Solution

  1. 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.
  2. Step 2: Correct usage of vTaskDelayUntil

    Initialize xLastWakeTime with xTaskGetTickCount() before the loop, then call vTaskDelayUntil() with 200 ms delay after task code to maintain steady timing without drift.
  3. Final Answer:

    Initialize xLastWakeTime with xTaskGetTickCount() before the loop, then call vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(200)) inside the loop after task code -> Option B
  4. Quick Check:

    Init last wake time + vTaskDelayUntil with full period = D [OK]
Hint: Init last wake time, delay full period after task code [OK]
Common Mistakes:
  • Using vTaskDelay instead of vTaskDelayUntil causing drift
  • Not accounting for task execution time in delay
  • Initializing xLastWakeTime incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard