A counting semaphore helps manage a limited number of resources shared by many tasks. It keeps track of how many resources are free or used.
Counting semaphore for resource pools in FreeRTOS
SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( maxCount, initialCount );
// To take (acquire) a resource:
if( xSemaphoreTake( xSemaphore, portMAX_DELAY ) == pdTRUE ) {
// Use resource
}
// To give (release) a resource:
xSemaphoreGive( xSemaphore );maxCount is the total number of resources available.
initialCount is how many resources are free at the start.
SemaphoreHandle_t xSemaphore = xSemaphoreCreateCounting( 3, 3 );
if( xSemaphoreTake( xSemaphore, portMAX_DELAY ) == pdTRUE ) {
// Use resource
xSemaphoreGive( xSemaphore );
}This program creates a counting semaphore with 2 resources. Three tasks try to get a resource. Only two can have it at once; the third waits until one releases.
#include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include <stdio.h> SemaphoreHandle_t xCountingSemaphore; void vTaskFunction( void *pvParameters ) { const char *taskName = (const char *) pvParameters; if( xSemaphoreTake( xCountingSemaphore, portMAX_DELAY ) == pdTRUE ) { printf("%s acquired a resource\n", taskName); vTaskDelay( 1000 / portTICK_PERIOD_MS ); // Simulate using resource printf("%s releasing a resource\n", taskName); xSemaphoreGive( xCountingSemaphore ); } vTaskDelete(NULL); } int main( void ) { xCountingSemaphore = xSemaphoreCreateCounting( 2, 2 ); // 2 resources if( xCountingSemaphore == NULL ) { // Semaphore was not created successfully return 1; } xTaskCreate( vTaskFunction, "Task1", 1000, "Task1", 1, NULL ); xTaskCreate( vTaskFunction, "Task2", 1000, "Task2", 1, NULL ); xTaskCreate( vTaskFunction, "Task3", 1000, "Task3", 1, NULL ); vTaskStartScheduler(); for( ;; ); return 0; }
Always check if the semaphore was created successfully before using it.
Use portMAX_DELAY to wait indefinitely for a resource, or a timeout value to avoid waiting forever.
Remember to give back the semaphore after using the resource to avoid deadlocks.
Counting semaphores track how many identical resources are free or used.
Use xSemaphoreCreateCounting to create one with max and initial counts.
Tasks take and give the semaphore to safely share resources.
Practice
Solution
Step 1: Understand counting semaphore role
A counting semaphore keeps track of how many identical resources are free or in use.Step 2: Compare with other options
Creating tasks, storing data, or handling interrupts are not roles of counting semaphores.Final Answer:
To track the number of available identical resources -> Option AQuick Check:
Counting semaphore = resource count tracker [OK]
- Confusing counting semaphore with binary semaphore
- Thinking it creates or manages tasks
- Assuming it stores data
Solution
Step 1: Recall function parameters
The functionxSemaphoreCreateCountingtakes max count first, then initial count.Step 2: Match parameters to options
xSemaphoreCreateCounting(5, 3); uses (5, 3) which means max count 5 and initial count 3, correct order.Final Answer:
xSemaphoreCreateCounting(5, 3); -> Option BQuick Check:
Max count first, initial count second [OK]
- Swapping max and initial count parameters
- Using only one parameter
- Confusing with binary semaphore creation
SemaphoreHandle_t sem = xSemaphoreCreateCounting(3, 3); xSemaphoreTake(sem, 0); xSemaphoreTake(sem, 0);
Solution
Step 1: Understand initial semaphore count
The semaphore starts with count 3 (max and initial both 3).Step 2: Subtract count for each take
EachxSemaphoreTakereduces count by 1 if successful. Two takes reduce count by 2.Final Answer:
1 -> Option DQuick Check:
3 - 2 takes = 1 [OK]
- Assuming count stays the same after take
- Confusing take with give operation
- Thinking count can go below zero
SemaphoreHandle_t sem = xSemaphoreCreateCounting(2, 2); xSemaphoreGive(sem);
Solution
Step 1: Check initial semaphore count
The semaphore is created with max count 2 and initial count 2, so it's full.Step 2: Analyze xSemaphoreGive call
Giving semaphore when count is already max causes overflow error or undefined behavior.Final Answer:
Calling xSemaphoreGive when semaphore count is at max causes overflow -> Option CQuick Check:
Giving at max count causes overflow [OK]
- Ignoring semaphore max count limits
- Swapping max and initial counts
- Calling give before creating semaphore
Solution
Step 1: Identify max and initial counts
Max count is total devices (4), initial count is free devices (2).Step 2: Match parameters to function call
Correct call isxSemaphoreCreateCounting(4, 2)with max 4 and initial 2.Final Answer:
SemaphoreHandle_t sem = xSemaphoreCreateCounting(4, 2); -> Option AQuick Check:
Max = total devices, initial = free devices [OK]
- Swapping max and initial counts
- Setting initial count higher than max
- Using max count less than total resources
Ready to prove it?
Pass the test and this pattern moves unknown
