📖 Scenario: You are working on a small embedded system using FreeRTOS. You want to understand how design patterns help make multi-tasking reliable and safe. This project will guide you through creating tasks, using synchronization, and showing how design patterns prevent problems like data corruption.
🎯 Goal: Build a simple FreeRTOS program with two tasks sharing a variable safely using a mutex. This shows how design patterns like mutual exclusion ensure reliable multi-tasking.
📋 What You'll Learn
Create two FreeRTOS tasks named Task1 and Task2
Create a shared integer variable called sharedCounter initialized to 0
Create a mutex called xMutex to protect access to sharedCounter
In each task, safely increment sharedCounter 5 times using the mutex
Print the value of sharedCounter after each increment
Use FreeRTOS API functions like xTaskCreate, xSemaphoreCreateMutex, xSemaphoreTake, and xSemaphoreGive
💡 Why This Matters
🌍 Real World
Embedded systems often run multiple tasks that share resources. Using design patterns like mutexes prevents bugs and crashes.
💼 Career
Understanding synchronization and design patterns is essential for embedded software engineers working with real-time operating systems like FreeRTOS.
Progress0 / 4 steps
1
Create shared variable and include FreeRTOS headers
Write code to include FreeRTOS.h and task.h. Then create a global integer variable called sharedCounter and set it to 0.
FreeRTOS
Hint
Remember to include the FreeRTOS headers first. Then declare sharedCounter as a global variable initialized to zero.
2
Create a mutex to protect sharedCounter
Create a mutex handle variable called xMutex of type SemaphoreHandle_t. Then create the mutex using xSemaphoreCreateMutex() and assign it to xMutex.
FreeRTOS
Hint
Use SemaphoreHandle_t to declare the mutex variable. Then call xSemaphoreCreateMutex() to create it.
3
Create two tasks that safely increment sharedCounter
Write two task functions named Task1 and Task2. Each task should loop 5 times. Inside the loop, use xSemaphoreTake(xMutex, portMAX_DELAY) to lock the mutex, increment sharedCounter by 1, print the value using printf, then release the mutex with xSemaphoreGive(xMutex). Add a small delay of 100ms between increments using vTaskDelay(pdMS_TO_TICKS(100)).
FreeRTOS
Hint
Each task must lock the mutex before changing sharedCounter and unlock it after. Use printf to show the current value.
4
Create tasks and start the scheduler
In main(), call setupMutex(). Then create Task1 and Task2 using xTaskCreate with stack size 1000 and priority 1. Finally, start the FreeRTOS scheduler with vTaskStartScheduler(). Print "Scheduler started" before starting the scheduler.
FreeRTOS
Hint
Call setupMutex() first. Then create both tasks with xTaskCreate. Finally, start the scheduler with vTaskStartScheduler().
Practice
(1/5)
1. Why do design patterns help ensure reliable multi-tasking in FreeRTOS?
easy
A. They make tasks run faster by skipping synchronization.
B. They organize tasks to safely share resources and avoid conflicts.
C. They allow tasks to ignore priority rules.
D. They remove the need for task communication.
Solution
Step 1: Understand task coordination
Design patterns help tasks work together by managing how they share resources.
Step 2: Recognize safety and reliability
By organizing resource access, patterns prevent conflicts and crashes in multi-tasking.
Final Answer:
They organize tasks to safely share resources and avoid conflicts. -> Option B
A. Using zero block time may cause task to skip critical section without waiting.
B. Mutex is given before taking it.
C. vTaskDelete should be called before giving mutex.
D. Critical section code is missing.
Solution
Step 1: Analyze semaphore take with zero block time
Using zero block time means the task tries to take the mutex but does not wait if it's unavailable, possibly skipping the critical section.
Step 2: Understand impact on reliability
This can cause unreliable behavior because the task may not execute the critical section safely every time.
Final Answer:
Using zero block time may cause task to skip critical section without waiting. -> Option A
Quick Check:
Zero wait risks skipping mutex [OK]
Hint: Zero wait means no blocking; task may skip critical section [OK]
Common Mistakes:
Thinking mutex is given before taken
Believing vTaskDelete order matters here
Assuming critical section must be shown
5. You want to design a FreeRTOS system where multiple tasks send data safely to a single processing task without data loss or corruption. Which design pattern best ensures reliable multi-tasking?
hard
A. Use a shared global variable without synchronization.
B. Use multiple mutexes for each task to lock the processor.
C. Use task notifications to broadcast data to all tasks.
D. Use a queue to send data from tasks to the processing task.
Solution
Step 1: Identify safe data transfer method
Queues in FreeRTOS safely store data from multiple tasks and deliver it to one consumer task without corruption.
Step 2: Compare other options
Shared variables without sync risk corruption; multiple mutexes locking processor is inefficient; task notifications are for signaling, not data transfer.
Final Answer:
Use a queue to send data from tasks to the processing task. -> Option D
Quick Check:
Queue = Safe multi-task data transfer [OK]
Hint: Queues safely pass data between tasks [OK]
Common Mistakes:
Using shared variables without locks
Misusing mutexes to lock processor
Confusing notifications with data queues
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.