Skip to main content

Using Semaphores for Task Synchronization in VxWorks

·434 words·3 mins
VxWorks RTOS Semaphores Task Synchronization Embedded Systems Programming Tutorial
Table of Contents

๐Ÿš€ Introduction
#

In the previous blog Understanding Tasks and Scheduling in VxWorks, we explored tasks and scheduling in VxWorks.

Now, letโ€™s solve a common challenge:
โžก๏ธ How do tasks coordinate with each other without causing race conditions?

The answer lies in semaphores.

In this tutorial, youโ€™ll learn:

  • What semaphores are in VxWorks.
  • The difference between binary and counting semaphores.
  • How to use a binary semaphore to synchronize two tasks.


๐Ÿงฉ What is a Semaphore?
#

A semaphore is a synchronization object used to control access to shared resources.

Types in VxWorks:

  1. Binary Semaphore

    • Values: 0 or 1.
    • Used for signaling (e.g., one task notifies another).
  2. Counting Semaphore

    • Values: 0 to N.
    • Used for managing access to a pool of identical resources.

๐Ÿ’ป Example: Binary Semaphore Between Two Tasks
#

Weโ€™ll create two tasks:

  • Producer Task โ†’ signals the semaphore.
  • Consumer Task โ†’ waits for the semaphore before running.

Code Example
#

#include <vxWorks.h>
#include <taskLib.h>
#include <semLib.h>
#include <stdio.h>
#include <unistd.h>

SEM_ID syncSem;  // Semaphore ID

// Producer task: gives semaphore
void producerTask()
{
    while (1)
    {
        printf("Producer: signaling the semaphore...\n");
        semGive(syncSem); // Release the semaphore
        sleep(2);         // Wait 2 seconds
    }
}

// Consumer task: waits for semaphore
void consumerTask()
{
    while (1)
    {
        semTake(syncSem, WAIT_FOREVER); // Block until semaphore is given
        printf("Consumer: received signal, running task!\n");
    }
}

void usrAppInit(void)
{
    // Create a binary semaphore, initially empty (0)
    syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);

    // Spawn producer task (priority 100)
    taskSpawn("tProducer", 100, 0, 2000, (FUNCPTR)producerTask,
              0,0,0,0,0,0,0,0,0,0);

    // Spawn consumer task (priority 150)
    taskSpawn("tConsumer", 150, 0, 2000, (FUNCPTR)consumerTask,
              0,0,0,0,0,0,0,0,0,0);
}

๐Ÿ“ Explanation of the Code
#

  1. semBCreate()

    • Creates a binary semaphore.
    • SEM_Q_PRIORITY โ†’ wake tasks in priority order.
    • SEM_EMPTY โ†’ starts with value 0.
  2. Producer Task

    • Calls semGive() every 2 seconds to release the semaphore.
  3. Consumer Task

    • Calls semTake() and blocks until the producer signals.

โšก What Youโ€™ll See
#

The output should look like:

Producer: signaling the semaphore...
Consumer: received signal, running task!
Producer: signaling the semaphore...
Consumer: received signal, running task!
...

The consumer only runs when the producer gives the semaphore.


๐Ÿ” Key Takeaways
#

  • Semaphores are essential for synchronizing tasks in VxWorks.
  • Binary semaphores are perfect for signaling between tasks.
  • Without semaphores, tasks could run into race conditions or inconsistent states.

โœ… Wrap-Up
#

In this tutorial, you learned:

  • The basics of semaphores in VxWorks.
  • How to use a binary semaphore to synchronize tasks.
  • How semGive() and semTake() coordinate producer-consumer tasks.

In the next blog, weโ€™ll extend this by using message queues for inter-task communication.


๐Ÿ‘‰ Stay tuned for Blog 4: โ€œMessage Queues in VxWorks: Passing Data Between Tasks.โ€

Related

Understanding Tasks and Scheduling in VxWorks
·423 words·2 mins
VxWorks RTOS Tasks Scheduling Embedded Systems Programming Tutorial
Getting Started with VxWorks Programming: Hello World for Beginners
·510 words·3 mins
VxWorks RTOS Embedded Systems Programming Tutorial Beginner Guide
The Ultimate VxWorks Programming Guide
·650 words·4 mins
VxWorks RTOS Embedded Systems RTP Device Drivers