I’m coding in a embedded environment with FreeRTOS and an STM32. As a POC I made the following code :
void producerTask1(void *pvParameters) {
int dataToSend = 1;
while(1) {
// Take the counting semaphore before sending data to the queue
xSemaphoreTake(countSemaphore, portMAX_DELAY);
// Send data to the queue
if (xQueueSend(myQueue, &dataToSend, portMAX_DELAY) == pdTRUE) {
// Successfully sent data to the queue
}
xSemaphoreGive(countSemaphore);
// Simulate production delay
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void producerTask2(void *pvParameters) {
int dataToSend = 2;
while(1) {
// Take the counting semaphore before sending data to the queue
xSemaphoreTake(countSemaphore, portMAX_DELAY);
// Send data to the queue
if (xQueueSend(myQueue, &dataToSend, portMAX_DELAY) == pdTRUE) {
// Successfully sent data to the queue
}
xSemaphoreGive(countSemaphore);
// Simulate production delay
vTaskDelay(pdMS_TO_TICKS(1500));
}
}
int isThereDataWaitingInMyQueue() {
return uxQueueMessagesWaiting(myQueue) > 0;
}
int areAllSemaphoreFree() {
// Check if the counting semaphore is at its maximum value
return uxSemaphoreGetCount(countSemaphore) == 10;
}
int actionToDo() {
// Implement the logic to determine if an action needs to be done
return 1; // Placeholder for demonstration
}
void consumerTask(void *pvParameters) {
int receivedData;
while(1) {
do {
if (xQueueReceive(myQueue, &receivedData, portMAX_DELAY) == pdTRUE) {
// Process received data
printf("Received data: %dn", receivedData);
}
} while(isThereDataWaitingInMyQueue());
// Wait until all semaphores are free
while(!areAllSemaphoreFree()) {
vTaskDelay(1);
}
// Perform actions when the queue is empty
while(!isThereDataWaitingInMyQueue() && actionToDo()) {
// Perform actions
}
}
}
void main(void) {
// Create the queue and the counting semaphore
myQueue = xQueueCreate(10, sizeof(int));
countSemaphore = xSemaphoreCreateCounting(10, 10);
// Create producer tasks
xTaskCreate(producerTask1, "Producer1", 1000, NULL, 1, NULL);
xTaskCreate(producerTask2, "Producer2", 1000, NULL, 1, NULL);
// Create the consumer task
xTaskCreate(consumerTask, "Consumer", 1000, NULL, 1, NULL);
// Start the scheduler
vTaskStartScheduler();
// Infinite loop (the code should never reach this point)
while(1);
}
Is it ok to use a counting semaphore this way ?
From the examples I’ve seen before and the code database that I have I’ve never seen counting semaphore used this way, so I thought I might be doing something wrong.
I asked ChatGPT his opinion but it’s like talking to a wall :/