Bird
Raised Fist0
FreeRTOSprogramming~10 mins

Multiple tasks running concurrently in FreeRTOS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Multiple tasks running concurrently
Start Scheduler
↓
Task 1 Ready
↓
Task 1 Running
↓
Task 1 Blocked
↓
Task 2 Ready
↓
Task 2 Running
↓
Task 2 Blocked
↩Back to Scheduler
The scheduler starts and switches between tasks that are ready to run, running one task at a time and switching when tasks block or yield.
Execution Sample
FreeRTOS
void Task1(void *pvParameters) {
  for(;;) {
    // Do work
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

void Task2(void *pvParameters) {
  for(;;) {
    // Do work
    vTaskDelay(500 / portTICK_PERIOD_MS);
  }
}
Two tasks run concurrently, each delaying for different times to simulate work and allow switching.
Execution Table
StepRunning TaskTask1 StateTask2 StateScheduler ActionOutput
1Task1RunningReadyStart Task1Task1 runs first
2Task1Blocked (delay)ReadySwitch to Task2Task1 delays 1000ms
3Task2Blocked (delay)RunningRun Task2Task2 runs
4Task2Blocked (delay)Blocked (delay)Both tasks delayedTask2 delays 500ms
5IdleReadyReadyTasks ready, switch to Task1Task1 delay over
6Task1RunningReadyRun Task1Task1 runs again
7Task1Blocked (delay)ReadySwitch to Task2Task1 delays again
8Task2Blocked (delay)RunningRun Task2Task2 runs again
9Task2Blocked (delay)Blocked (delay)Both delayedTask2 delays again
10IdleReadyReadyTasks ready, switch to Task1Cycle repeats
Exit----Scheduler runs indefinitely, tasks keep switching
💡 Scheduler runs forever, switching tasks as they block and become ready again
Variable Tracker
VariableStartAfter Step 1After Step 3After Step 5After Step 7After Step 9Final
Task1 StateReadyRunningBlocked (delay)ReadyBlocked (delay)ReadyBlocked (delay)
Task2 StateReadyReadyRunningBlocked (delay)ReadyRunningBlocked (delay)
Key Moments - 3 Insights
Why does Task1 become blocked after running?
Because Task1 calls vTaskDelay, it tells the scheduler to pause it for 1000ms, so it moves to Blocked state (see execution_table step 2).
How does the scheduler decide which task to run next?
The scheduler runs the highest priority task that is Ready. When Task1 blocks, Task2 is Ready and runs next (see steps 2 and 3).
What happens when both tasks are delayed at the same time?
Both tasks are Blocked, so the scheduler runs the Idle task until one task's delay expires (see step 4 and 10).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is Task2's state at Step 3?
AReady
BBlocked (delay)
CRunning
DSuspended
💡 Hint
Check the 'Task2 State' column at Step 3 in the execution_table.
At which step does Task1 become Ready again after its delay?
AStep 5
BStep 7
CStep 2
DStep 9
💡 Hint
Look for when Task1 state changes from Blocked to Ready in the execution_table.
If Task2's delay was increased to 2000ms, how would the scheduler behavior change?
ATask2 would run more often
BTask2 would block longer, Task1 runs more
CBoth tasks would block at the same time more often
DScheduler would stop switching tasks
💡 Hint
Consider how longer delay affects Task2's Blocked state duration in variable_tracker.
Concept Snapshot
FreeRTOS runs multiple tasks by switching between them.
Each task runs until it blocks or yields.
vTaskDelay pauses a task, letting others run.
Scheduler picks the highest priority Ready task.
When all tasks block, Idle task runs.
This creates the illusion of tasks running at the same time.
Full Transcript
In FreeRTOS, multiple tasks run concurrently by the scheduler switching between them. When the scheduler starts, it runs the first ready task. If a task calls vTaskDelay, it becomes blocked for that time, and the scheduler switches to another ready task. Tasks alternate running and blocking, allowing multitasking. When all tasks are blocked, the Idle task runs until a task becomes ready again. This process repeats indefinitely, creating concurrent task execution. The execution table shows step-by-step how Task1 and Task2 states change and how the scheduler switches between them. The variable tracker highlights the state changes of each task after each step. Key moments clarify why tasks block and how the scheduler chooses which task to run next. The visual quiz tests understanding of task states and scheduler behavior. The concept snapshot summarizes the multitasking mechanism in FreeRTOS.

Practice

(1/5)
1. What is the main purpose of running multiple tasks concurrently in FreeRTOS?
easy
A. To allow the program to perform several operations at the same time
B. To make the program run slower
C. To use more memory without benefit
D. To avoid using any delays in the code

Solution

  1. Step 1: Understand task concurrency

    Multiple tasks let the program handle different jobs at once, improving efficiency.
  2. Step 2: Identify the purpose in FreeRTOS

    FreeRTOS switches between tasks automatically, enabling multitasking.
  3. Final Answer:

    To allow the program to perform several operations at the same time -> Option A
  4. Quick Check:

    Multiple tasks = multitasking = To allow the program to perform several operations at the same time [OK]
Hint: Multiple tasks mean doing many things at once [OK]
Common Mistakes:
  • Thinking tasks slow down the program
  • Believing tasks waste memory
  • Ignoring the role of delays
2. Which of the following is the correct way to create a task in FreeRTOS?
easy
A. TaskCreate(TaskFunction, "TaskName", stackSize, NULL, priority, NULL);
B. createTask(TaskFunction, "TaskName", stackSize, NULL, priority, NULL);
C. xTaskCreate(TaskFunction, "TaskName", stackSize, NULL, priority, NULL);
D. xCreateTask(TaskFunction, "TaskName", stackSize, NULL, priority, NULL);

Solution

  1. Step 1: Recall FreeRTOS task creation function

    The correct function to create a task is xTaskCreate.
  2. Step 2: Match the exact syntax

    xTaskCreate(TaskFunction, "TaskName", stackSize, NULL, priority, NULL); matches the correct function name and parameters.
  3. Final Answer:

    xTaskCreate(TaskFunction, "TaskName", stackSize, NULL, priority, NULL); -> Option C
  4. Quick Check:

    Task creation function = xTaskCreate = xTaskCreate(TaskFunction, "TaskName", stackSize, NULL, priority, NULL); [OK]
Hint: Remember the function starts with 'xTaskCreate' [OK]
Common Mistakes:
  • Using incorrect function names like createTask
  • Mixing up parameter order
  • Missing the 'x' prefix in function name
3. Consider this FreeRTOS code snippet:
void Task1(void *pvParameters) {
  for (;;) {
    printf("Task1 running\n");
    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}

void Task2(void *pvParameters) {
  for (;;) {
    printf("Task2 running\n");
    vTaskDelay(pdMS_TO_TICKS(500));
  }
}
What will be the output pattern when both tasks run concurrently?
medium
A. Task1 prints every 1 second; Task2 prints every 0.5 seconds
B. Task1 and Task2 print at the same time every 1 second
C. Task1 prints every 0.5 seconds; Task2 prints every 1 second
D. Only Task1 prints because Task2 is blocked

Solution

  1. Step 1: Analyze vTaskDelay timing for Task1

    Task1 delays 1000 ms (1 second) between prints.
  2. Step 2: Analyze vTaskDelay timing for Task2

    Task2 delays 500 ms (0.5 seconds) between prints.
  3. Step 3: Understand concurrent execution

    Both tasks run independently, so Task2 prints twice as often as Task1.
  4. Final Answer:

    Task1 prints every 1 second; Task2 prints every 0.5 seconds -> Option A
  5. Quick Check:

    Delays control print rate = Task1 prints every 1 second; Task2 prints every 0.5 seconds [OK]
Hint: Check each task's delay time to predict print frequency [OK]
Common Mistakes:
  • Assuming tasks print simultaneously
  • Mixing up delay times
  • Thinking one task blocks the other
4. Given this code snippet, what is the error?
void TaskA(void *pvParameters) {
  while(1) {
    // Do something
    vTaskDelay(1000);
  }
}

xTaskCreate(TaskA, "TaskA", 1000, NULL, 1, NULL);
medium
A. Task function must return int, not void
B. vTaskDelay requires delay in ticks, not milliseconds
C. Stack size 1000 is too small
D. Task name must be longer than 5 characters

Solution

  1. Step 1: Check vTaskDelay parameter

    vTaskDelay expects delay in ticks, not milliseconds.
  2. Step 2: Identify correct delay usage

    Use pdMS_TO_TICKS(1000) to convert 1000 ms to ticks.
  3. Final Answer:

    vTaskDelay requires delay in ticks, not milliseconds -> Option B
  4. Quick Check:

    Delay unit must be ticks = vTaskDelay requires delay in ticks, not milliseconds [OK]
Hint: Use pdMS_TO_TICKS() to convert ms to ticks for vTaskDelay [OK]
Common Mistakes:
  • Passing milliseconds directly to vTaskDelay
  • Wrong return type for task function
  • Incorrect stack size assumptions
5. You want two tasks to print messages alternately every 500 ms without overlapping prints. Which approach ensures this behavior in FreeRTOS?
hard
A. Use global variables without any synchronization
B. Use vTaskDelay with different delay times for each task
C. Run both tasks at the same priority without synchronization
D. Use a binary semaphore to synchronize tasks before printing

Solution

  1. Step 1: Understand the need for synchronization

    To avoid overlapping prints, tasks must coordinate access to the printing resource.
  2. Step 2: Identify synchronization method

    A binary semaphore allows one task to print while the other waits, alternating access.
  3. Step 3: Evaluate other options

    Different delays or same priority without sync can cause overlapping prints; global variables alone don't prevent conflicts.
  4. Final Answer:

    Use a binary semaphore to synchronize tasks before printing -> Option D
  5. Quick Check:

    Synchronization via semaphore = Use a binary semaphore to synchronize tasks before printing [OK]
Hint: Use semaphores to control shared resource access [OK]
Common Mistakes:
  • Relying only on delays for synchronization
  • Ignoring task priority effects
  • Not using any synchronization mechanism
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