Bird
Raised Fist0
FreeRTOSprogramming~10 mins

vTaskDelay() for periodic tasks in FreeRTOS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - vTaskDelay() for periodic tasks
Task starts
↓
Execute task code
↓
Call vTaskDelay(delay)
↓
Task blocked for delay ticks
↓
Delay ends, task ready
↓
Scheduler runs task again
↩Back to Execute task code
The task runs its code, then calls vTaskDelay to pause for a fixed time, making the task periodic by repeating this cycle.
Execution Sample
FreeRTOS
void Task(void *pvParameters) {
  for(;;) {
    // Do work
    vTaskDelay(100 / portTICK_PERIOD_MS);
  }
}
This task runs forever, doing work then delaying for 100 milliseconds each cycle.
Execution Table
StepActionTask StateDelay Time Left (ticks)Scheduler Behavior
1Task starts and runs codeRunning0Task runs
2Calls vTaskDelay(100)Blocked100Task blocked, scheduler runs other tasks
3Tick interrupt decrements delayBlocked99Task still blocked
4Tick interrupt decrements delayBlocked50Task still blocked
5Tick interrupt decrements delayBlocked1Task still blocked
6Tick interrupt decrements delay to 0Ready0Task ready to run
7Scheduler runs task againRunning0Task runs again
8Task repeats loopRunning0Task runs
9Calls vTaskDelay(100)Blocked100Task blocked again
10Execution continues similarly...Blocked/ReadyVariesCycle repeats
💡 Task never exits; it loops forever with periodic delays.
Variable Tracker
VariableStartAfter Step 2After Step 6After Step 9Final
Task StateRunningBlockedReadyBlockedRepeats
Delay Time Left (ticks)01000100Cycles
Key Moments - 3 Insights
Why does the task become blocked after calling vTaskDelay?
Because vTaskDelay tells the scheduler to pause the task for the specified ticks, so it moves from Running to Blocked state as shown in step 2 of the execution_table.
How does the task become ready again after delay?
Each tick interrupt reduces the delay count. When it reaches zero (step 6), the task state changes from Blocked to Ready, so the scheduler can run it again.
Does vTaskDelay guarantee exact periodic timing?
vTaskDelay delays for at least the specified ticks, but actual timing depends on scheduler and other tasks. The task runs periodically but may have small timing variations.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the Task State immediately after calling vTaskDelay?
ARunning
BReady
CBlocked
DSuspended
💡 Hint
Check Step 2 in the execution_table where vTaskDelay is called.
At which step does the delay time left reach zero, making the task ready again?
AStep 3
BStep 6
CStep 5
DStep 7
💡 Hint
Look at the Delay Time Left column in the execution_table.
If the delay passed to vTaskDelay is doubled, how does the Delay Time Left change at Step 2?
AIt doubles
BIt stays the same
CIt halves
DIt becomes zero
💡 Hint
Refer to the Delay Time Left value at Step 2 in the execution_table.
Concept Snapshot
vTaskDelay(delayTicks) pauses a task for delayTicks ticks.
Task state changes from Running to Blocked during delay.
Delay counts down each tick until zero.
When zero, task becomes Ready and runs again.
Used to create periodic tasks with fixed wait times.
Full Transcript
This visual trace shows how vTaskDelay creates periodic tasks in FreeRTOS. The task runs its code, then calls vTaskDelay with a delay in ticks. This moves the task to Blocked state, pausing it. Each tick interrupt reduces the delay count. When the delay reaches zero, the task becomes Ready and the scheduler runs it again. This cycle repeats forever, making the task periodic. The execution table tracks task state and delay time step-by-step. Key moments explain why the task blocks and how it becomes ready again. The quiz tests understanding of task states and delay timing. This helps beginners see how vTaskDelay controls task timing visually.

Practice

(1/5)
1. What is the primary purpose of vTaskDelay() in FreeRTOS?
easy
A. To pause a task for a specific number of ticks
B. To create a new task
C. To delete a task
D. To send data between tasks

Solution

  1. Step 1: Understand the function role

    vTaskDelay() is designed to pause or block a task for a set number of tick counts, allowing other tasks to run.
  2. Step 2: Compare with other options

    Creating or deleting tasks and sending data are done by other FreeRTOS functions, not vTaskDelay().
  3. Final Answer:

    To pause a task for a specific number of ticks -> Option A
  4. Quick Check:

    vTaskDelay() pauses task = A [OK]
Hint: vTaskDelay() always pauses task execution for ticks [OK]
Common Mistakes:
  • Confusing vTaskDelay() with task creation functions
  • Thinking vTaskDelay() sends data
  • Assuming vTaskDelay() deletes tasks
2. Which of the following is the correct way to delay a task for 100 milliseconds using vTaskDelay()?
easy
A. vTaskDelay(100);
B. vTaskDelayMs(100);
C. vTaskDelay(pdMS_TO_TICKS(100));
D. vTaskDelayTicks(100);

Solution

  1. Step 1: Understand tick conversion

    FreeRTOS uses ticks, not milliseconds directly. To convert milliseconds to ticks, use pdMS_TO_TICKS().
  2. Step 2: Check syntax correctness

    Only vTaskDelay(pdMS_TO_TICKS(100)); correctly converts 100 ms to ticks and delays the task.
  3. Final Answer:

    vTaskDelay(pdMS_TO_TICKS(100)); -> Option C
  4. Quick Check:

    Use pdMS_TO_TICKS() inside vTaskDelay() [OK]
Hint: Always convert ms to ticks with pdMS_TO_TICKS() [OK]
Common Mistakes:
  • Passing milliseconds directly without conversion
  • Using non-existent functions like vTaskDelayMs()
  • Confusing ticks and milliseconds
3. Given the following code snippet, what will be the approximate delay between each print statement?
void TaskFunction(void *pvParameters) {
    while(1) {
        printf("Tick\n");
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}
medium
A. Approximately 1 second
B. Approximately 500 milliseconds
C. No delay, prints continuously
D. Approximately 50 milliseconds

Solution

  1. Step 1: Analyze vTaskDelay parameter

    The delay is set to pdMS_TO_TICKS(500), which converts 500 milliseconds to ticks.
  2. Step 2: Understand loop timing

    Each loop iteration prints "Tick" then delays for about 500 ms, so prints occur roughly every 500 ms.
  3. Final Answer:

    Approximately 500 milliseconds -> Option B
  4. Quick Check:

    vTaskDelay(pdMS_TO_TICKS(500)) = 500 ms delay [OK]
Hint: vTaskDelay(pdMS_TO_TICKS(x)) delays about x milliseconds [OK]
Common Mistakes:
  • Ignoring pdMS_TO_TICKS conversion
  • Assuming no delay in loop
  • Confusing milliseconds with ticks
4. Identify the error in this code snippet intended to delay a task for 200 milliseconds:
void Task(void *params) {
    while(1) {
        doWork();
        vTaskDelay(200);
    }
}
medium
A. vTaskDelay cannot be used inside a while loop
B. doWork() must be called after vTaskDelay()
C. The task function must return a value
D. vTaskDelay should use pdMS_TO_TICKS(200) to convert milliseconds

Solution

  1. Step 1: Check vTaskDelay argument

    The argument 200 is treated as ticks, not milliseconds. To delay 200 ms, convert using pdMS_TO_TICKS(200).
  2. Step 2: Verify other code parts

    Calling doWork() before delay is valid. The task function returns void, which is correct.
  3. Final Answer:

    vTaskDelay should use pdMS_TO_TICKS(200) to convert milliseconds -> Option D
  4. Quick Check:

    Convert ms to ticks with pdMS_TO_TICKS() [OK]
Hint: Always convert ms to ticks before passing to vTaskDelay() [OK]
Common Mistakes:
  • Passing milliseconds directly to vTaskDelay()
  • Thinking vTaskDelay can't be in loops
  • Expecting task functions to return values
5. You want a task to run exactly every 1 second, but your system tick rate is 1000 Hz (1 tick = 1 ms). Which is the best way to implement this periodic delay using vTaskDelay()?
hard
A. Use vTaskDelayUntil() instead of vTaskDelay() for precise periodic timing
B. Call vTaskDelay(pdMS_TO_TICKS(1000)); inside the task loop
C. Call vTaskDelay(pdMS_TO_TICKS(1000)); and then call vTaskDelay(0);
D. Call vTaskDelay(1000); inside the task loop

Solution

  1. Step 1: Understand vTaskDelay limitations

    vTaskDelay() delays relative to current time, so small variations accumulate causing drift in periodic tasks.
  2. Step 2: Identify precise periodic method

    vTaskDelayUntil() uses an absolute wake time, preventing drift and ensuring exact periodic execution.
  3. Final Answer:

    Use vTaskDelayUntil() instead of vTaskDelay() for precise periodic timing -> Option A
  4. Quick Check:

    vTaskDelayUntil() prevents drift in periodic tasks [OK]
Hint: Use vTaskDelayUntil() for exact periodic task timing [OK]
Common Mistakes:
  • Using vTaskDelay() causes timing drift
  • Assuming tick count matches ms without conversion
  • Adding extra delays unnecessarily
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