We use critical sections to protect parts of code that access shared resources. This stops other tasks or interrupts from changing data at the same time, avoiding errors.
Critical section with taskENTER_CRITICAL in FreeRTOS
Introduction
Syntax
FreeRTOS
taskENTER_CRITICAL(); // critical code here taskEXIT_CRITICAL();
taskENTER_CRITICAL disables interrupts to protect the code inside.
Always pair taskENTER_CRITICAL with taskEXIT_CRITICAL to re-enable interrupts.
Examples
FreeRTOS
taskENTER_CRITICAL(); sharedCounter++; taskEXIT_CRITICAL();
FreeRTOS
taskENTER_CRITICAL(); // Access hardware safely writeRegister(value); taskEXIT_CRITICAL();
Sample Program
This program shows how to safely increase a shared counter using taskENTER_CRITICAL and taskEXIT_CRITICAL to prevent interruptions.
FreeRTOS
#include "FreeRTOS.h" #include "task.h" #include <stdio.h> volatile int sharedCounter = 0; void incrementCounter() { taskENTER_CRITICAL(); sharedCounter++; taskEXIT_CRITICAL(); } int main() { printf("Counter before: %d\n", sharedCounter); incrementCounter(); printf("Counter after: %d\n", sharedCounter); return 0; }
Important Notes
Do not keep critical sections longer than necessary to avoid blocking interrupts too long.
taskENTER_CRITICAL disables interrupts globally, so use carefully in real-time systems.
Summary
Critical sections protect shared data by disabling interrupts.
Use taskENTER_CRITICAL and taskEXIT_CRITICAL together.
Keep critical sections short to keep system responsive.
Practice
1. What is the main purpose of using
taskENTER_CRITICAL() in FreeRTOS?easy
Solution
Step 1: Understand what
This function disables interrupts to prevent context switches and protect shared resources.taskENTER_CRITICAL()doesStep 2: Identify the purpose in multitasking
Disabling interrupts ensures that the critical section code runs without interruption, avoiding data corruption.Final Answer:
To disable interrupts and protect shared data during a critical section -> Option BQuick Check:
Critical section protection = disable interrupts [OK]
Hint: Remember: critical section means no interrupts [OK]
Common Mistakes:
- Confusing task creation with critical section
- Thinking it allocates memory
- Assuming it sends messages
2. Which of the following is the correct syntax to start a critical section in FreeRTOS?
easy
Solution
Step 1: Recall the exact function name and syntax
The correct FreeRTOS API function to enter a critical section istaskENTER_CRITICAL()with parentheses.Step 2: Check the options for correct spelling and syntax
Only taskENTER_CRITICAL(); uses the exact function name with parentheses, which is required to call the function.Final Answer:
taskENTER_CRITICAL(); -> Option CQuick Check:
Function call syntax = parentheses needed [OK]
Hint: Function calls always need parentheses () [OK]
Common Mistakes:
- Omitting parentheses when calling functions
- Using incorrect function names
- Confusing with similar sounding functions
3. Consider the following FreeRTOS code snippet:
int sharedCounter = 0;
void incrementCounter() {
taskENTER_CRITICAL();
sharedCounter++;
taskEXIT_CRITICAL();
}
incrementCounter();
printf("%d", sharedCounter);
What will be the output after running this code once?medium
Solution
Step 1: Analyze the increment inside the critical section
The function incrementssharedCounterby 1 while interrupts are disabled, ensuring safe update.Step 2: Check the output after one call
After callingincrementCounter()once,sharedCounterbecomes 1, so printing it outputs 1.Final Answer:
1 -> Option AQuick Check:
Increment once = 1 [OK]
Hint: Increment inside critical section updates safely [OK]
Common Mistakes:
- Assuming no increment due to critical section
- Thinking code won't compile
- Confusing output with initial value
4. Identify the error in this FreeRTOS critical section code:
void updateData() {
taskENTER_CRITICAL();
sharedData = 42;
// Missing taskEXIT_CRITICAL();
}medium
Solution
Step 1: Check for matching critical section calls
The code callstaskENTER_CRITICAL()but does not calltaskEXIT_CRITICAL(), so interrupts remain disabled.Step 2: Understand consequences of missing exit
Interrupts staying disabled can freeze the system or cause missed interrupts, which is a serious error.Final Answer:
MissingtaskEXIT_CRITICAL()causes interrupts to stay disabled -> Option AQuick Check:
Always pair enter and exit critical [OK]
Hint: Always match enter and exit critical calls [OK]
Common Mistakes:
- Forgetting to call taskEXIT_CRITICAL()
- Thinking enter critical is invalid in functions
- Assuming volatile fixes missing exit
5. You have two tasks incrementing a shared variable
counter. To avoid race conditions, you use a critical section:
void increment() {
taskENTER_CRITICAL();
counter++;
taskEXIT_CRITICAL();
}
However, the system becomes unresponsive when interrupts are disabled for too long. What is the best way to improve this?hard
Solution
Step 1: Understand impact of long critical sections
Disabling interrupts for too long blocks other important system activities, causing unresponsiveness.Step 2: Optimize critical section length
Keeping the critical section short, only around the shared variable update, minimizes interrupt blocking and improves responsiveness.Final Answer:
Keep the critical section as short as possible, only around the increment -> Option DQuick Check:
Short critical section = better responsiveness [OK]
Hint: Shorten critical sections to keep system responsive [OK]
Common Mistakes:
- Removing critical section causing race conditions
- Disabling interrupts too long
- Using busy-wait inside critical section
Recommended
Ready to prove it?
Pass the test and this pattern moves unknown
10 questions ~5 mineasy hard
