Bird
Raised Fist0
FreeRTOSprogramming~20 mins

Task pooling for dynamic workloads in FreeRTOS - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Task Pooling Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of task creation with dynamic pooling
Consider a FreeRTOS system where tasks are created dynamically from a pool. What will be the output of the following code snippet when three tasks are created and run?
FreeRTOS
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>

void vTaskFunction(void *pvParameters) {
    int id = *((int *)pvParameters);
    printf("Task %d running\n", id);
    vTaskDelete(NULL);
}

int main() {
    TaskHandle_t xTaskHandles[3];
    int task_id;

    for (int i = 0; i < 3; i++) {
        task_id = i + 1;
        xTaskCreate(vTaskFunction, "Task", 1000, &task_id, 1, &xTaskHandles[i]);
    }

    vTaskStartScheduler();
    return 0;
}
ATask 1 running\nTask 2 running\nTask 3 running\n
BTask 1 running\nTask 1 running\nTask 1 running\n
CTask 3 running\nTask 3 running\nTask 3 running\n
DNo output, system hangs
Attempts:
2 left
💡 Hint
Consider what happens when the same memory address is passed to multiple tasks.
🧠 Conceptual
intermediate
1:30remaining
Best practice for task parameter passing in dynamic pools
In FreeRTOS, when creating multiple tasks dynamically from a pool, what is the best practice to ensure each task receives a unique parameter?
APass the address of a loop variable directly to each task.
BAllocate or use distinct memory for each task's parameter before creation.
CUse a global variable shared by all tasks.
DDo not pass any parameter; use global constants instead.
Attempts:
2 left
💡 Hint
Think about how memory addresses and values behave when tasks start asynchronously.
🔧 Debug
advanced
2:00remaining
Identify the cause of task starvation in a dynamic pool
Given a FreeRTOS system with a task pool managing dynamic workloads, tasks sometimes never run. What is the most likely cause?
FreeRTOS
void vTaskFunction(void *pvParameters) {
    while(1) {
        // Process workload
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

int main() {
    for (int i = 0; i < 5; i++) {
        xTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, NULL);
    }
    vTaskStartScheduler();
    return 0;
}
ATasks have equal priority but the scheduler is not started.
BTasks block indefinitely, causing starvation.
CThe idle task priority is higher than created tasks, starving them.
DAll tasks have the same priority, causing round-robin scheduling and no starvation.
Attempts:
2 left
💡 Hint
Consider how FreeRTOS schedules tasks with the same priority.
📝 Syntax
advanced
1:30remaining
Identify the syntax error in task creation code
Which option contains a syntax error in FreeRTOS task creation?
FreeRTOS
void vTaskFunction(void *pvParameters) {
    // Task code
}

int main() {
    TaskHandle_t xHandle;
    xTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, &xHandle);
    vTaskStartScheduler();
    return 0;
}
AxTaskCreate(vTaskFunction, Task, 1000, NULL, 1, &xHandle);
BxTaskCreate(vTaskFunction, "Task", 1000, NULL, 1);
CxTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, &xHandle);
DxTaskCreate(vTaskFunction, "Task", 1000, NULL, 1, xHandle);
Attempts:
2 left
💡 Hint
Check the type of the second argument in xTaskCreate.
🚀 Application
expert
2:30remaining
Calculate maximum concurrent tasks in a dynamic pool
A FreeRTOS system has 64KB of heap memory. Each task requires 2KB stack and 512 bytes for task control block (TCB). If the system reserves 8KB for other uses, what is the maximum number of tasks that can be created dynamically in a task pool?
A22
B20
C24
D26
Attempts:
2 left
💡 Hint
Calculate available memory and divide by total memory per task (stack + TCB).

Practice

(1/5)
1. What is the main advantage of using a task pool in FreeRTOS for dynamic workloads?
easy
A. It reuses a fixed number of tasks to handle many jobs efficiently.
B. It creates a new task for every job to maximize parallelism.
C. It eliminates the need for queues in task communication.
D. It requires more memory but improves task priority handling.

Solution

  1. Step 1: Understand task pooling concept

    Task pooling means reusing a limited number of tasks instead of creating new ones for each job.
  2. Step 2: Identify benefits of task pooling

    This reuse saves memory and improves efficiency by avoiding overhead of task creation and deletion.
  3. Final Answer:

    It reuses a fixed number of tasks to handle many jobs efficiently. -> Option A
  4. Quick Check:

    Task pooling = reuse fixed tasks [OK]
Hint: Task pooling means reuse tasks, not create new ones [OK]
Common Mistakes:
  • Thinking task pooling creates a new task per job
  • Believing task pooling removes the need for queues
  • Assuming task pooling uses more memory
2. Which FreeRTOS API is typically used to send work items to a task pool?
easy
A. vTaskDelay()
B. xQueueSend()
C. xSemaphoreTake()
D. vTaskDelete()

Solution

  1. Step 1: Identify communication method for task pools

    Task pools receive work items via queues to distribute jobs among tasks.
  2. Step 2: Match API to queue sending

    xQueueSend() is the FreeRTOS function to send data to a queue.
  3. Final Answer:

    xQueueSend() -> Option B
  4. Quick Check:

    Send work to queue = xQueueSend() [OK]
Hint: Use xQueueSend() to send work to task pool queue [OK]
Common Mistakes:
  • Confusing delay or semaphore functions with queue sending
  • Using vTaskDelete() which deletes tasks, not send work
3. Given this snippet, what will be printed?
void workerTask(void *params) {
  int workItem;
  while (xQueueReceive(workQueue, &workItem, portMAX_DELAY)) {
    printf("Processing %d\n", workItem);
  }
}

// Main code
int main() {
  int item = 42;
  xQueueSend(workQueue, &item, 0);
  vTaskStartScheduler();
  return 0;
}
medium
A. Processing 0
B. No output, queue is empty
C. Processing 42
D. Compilation error due to missing queue creation

Solution

  1. Step 1: Check queue usage in code

    The code uses workQueue but does not show it being created or initialized.
  2. Step 2: Understand FreeRTOS queue requirements

    Queues must be created with xQueueCreate before use; missing this causes compile or runtime errors.
  3. Final Answer:

    Compilation error due to missing queue creation -> Option D
  4. Quick Check:

    Queue must be created before use [OK]
Hint: Always create queues before sending or receiving [OK]
Common Mistakes:
  • Assuming queue exists without creation
  • Expecting output without scheduler running properly
  • Ignoring queue initialization
4. Identify the error in this task pool worker function:
void workerTask(void *params) {
  int workItem;
  while (xQueueReceive(workQueue, &workItem, 0)) {
    process(workItem);
  }
}
medium
A. Using zero timeout causes busy waiting and high CPU usage.
B. workItem should be a pointer, not int.
C. process() is not a valid FreeRTOS API.
D. xQueueReceive requires a NULL pointer for workItem.

Solution

  1. Step 1: Analyze xQueueReceive timeout parameter

    Timeout of 0 means non-blocking call; if queue empty, returns immediately causing loop to run continuously.
  2. Step 2: Understand impact on CPU usage

    This busy loop wastes CPU cycles, leading to high CPU usage and inefficient task pooling.
  3. Final Answer:

    Using zero timeout causes busy waiting and high CPU usage. -> Option A
  4. Quick Check:

    Zero timeout = busy wait [OK]
Hint: Use portMAX_DELAY to block and avoid busy waiting [OK]
Common Mistakes:
  • Thinking zero timeout is safe for task pools
  • Confusing pointer types for queue data
  • Assuming process() is FreeRTOS API
5. You want to implement a task pool with 3 worker tasks to handle variable workloads efficiently. Which approach is best?
hard
A. Use a single task with vTaskDelay to process all work items sequentially.
B. Create 3 tasks that poll the queue with zero timeout in a tight loop.
C. Create 3 tasks that block on xQueueReceive with portMAX_DELAY and send work via a queue.
D. Create a new task for each work item dynamically and delete it after processing.

Solution

  1. Step 1: Understand efficient task pooling

    Efficient pooling uses fixed tasks that wait (block) for work to avoid wasting CPU.
  2. Step 2: Evaluate options for workload handling

    Blocking on xQueueReceive with portMAX_DELAY lets tasks sleep until work arrives, saving CPU and memory.
  3. Final Answer:

    Create 3 tasks that block on xQueueReceive with portMAX_DELAY and send work via a queue. -> Option C
  4. Quick Check:

    Block on queue = efficient task pool [OK]
Hint: Block tasks on queue to save CPU and handle dynamic work [OK]
Common Mistakes:
  • Polling queue wastes CPU
  • Creating tasks dynamically wastes memory
  • Using single task delays reduces responsiveness
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