↓ Skip to main content

Inter-Task Communication with Message Queues in VxWorks

VxWorks Programming Tutorial for Beginners - This article is part of a series.
Part 10: This Article

🚀 Introduction
#

In the previous blog UDP Networking in VxWorks: Sending and Receiving Packets, we explored UDP networking in VxWorks.
Now, let’s switch gears to Inter-Task Communication (IPC) inside the RTOS itself.

VxWorks offers several IPC mechanisms:

  • Semaphores (synchronization).
  • Message Queues (data transfer).
  • Shared Memory (fast, but more complex).

In this tutorial, we’ll focus on Message Queues — a reliable way to pass data between tasks.

🧩 Why Use Message Queues?
#

  • Allows safe communication between tasks.
  • FIFO order ensures predictable message handling.
  • Can prioritize messages if needed.
  • Decouples sender and receiver tasks.

💻 Example: Two Tasks Communicating with a Message Queue
#

We’ll build:

  • Producer Task → sends messages into a queue.
  • Consumer Task → receives and processes them.

Code Example
#

#include <vxWorks.h>
#include <taskLib.h>
#include <msgQLib.h>
#include <stdio.h>
#include <string.h>

#define MAX_MSGS   10
#define MAX_LEN    64

MSG_Q_ID msgQId;  // Message Queue ID

// Consumer Task
void consumerTask()
{
    char buffer[MAX_LEN];
    int len;

    while (1)
    {
        len = msgQReceive(msgQId, buffer, MAX_LEN, WAIT_FOREVER);
        if (len > 0)
        {
            buffer[len] = '\0';
            printf("Consumer: Received -> %s\n", buffer);
        }
    }
}

// Producer Task
void producerTask()
{
    char *messages[] = {
        "Message 1: Hello",
        "Message 2: VxWorks",
        "Message 3: IPC Rocks!"
    };

    for (int i = 0; i < 3; i++)
    {
        msgQSend(msgQId, messages[i], strlen(messages[i])+1, WAIT_FOREVER, MSG_PRI_NORMAL);
        printf("Producer: Sent -> %s\n", messages[i]);
        taskDelay(100); // Delay between messages
    }
}

// Init function
void usrAppInit(void)
{
    // Create a message queue
    msgQId = msgQCreate(MAX_MSGS, MAX_LEN, MSG_Q_FIFO);

    // Spawn tasks
    taskSpawn("tConsumer", 100, 0, 4000, (FUNCPTR)consumerTask,
              0,0,0,0,0,0,0,0,0,0);

    taskSpawn("tProducer", 110, 0, 4000, (FUNCPTR)producerTask,
              0,0,0,0,0,0,0,0,0,0);
}

📝 Explanation of the Code
#

  1. msgQCreate()

    • Creates a message queue that can hold 10 messages of up to 64 bytes.
  2. Producer Task

    • Sends three messages into the queue using msgQSend().
    • Uses MSG_PRI_NORMAL (default priority).
  3. Consumer Task

    • Waits on the queue using msgQReceive().
    • Processes and prints each message.
  4. Synchronization

    • WAIT_FOREVER ensures producer/consumer wait until resources are available.

⚡ What You’ll See
#

When running, the output looks like:

Producer: Sent -> Message 1: Hello
Consumer: Received -> Message 1: Hello
Producer: Sent -> Message 2: VxWorks
Consumer: Received -> Message 2: VxWorks
Producer: Sent -> Message 3: IPC Rocks!
Consumer: Received -> Message 3: IPC Rocks!

🔍 Key Takeaways
#

  • Message Queues provide reliable IPC in VxWorks.
  • They support FIFO and priority-based delivery.
  • Ideal for producer-consumer patterns in embedded systems.

✅ Wrap-Up
#

In this tutorial, you learned:

  • How to create and use a message queue in VxWorks.
  • How producer and consumer tasks communicate.
  • How message queues help decouple tasks in real-time systems.
VxWorks Programming Tutorial for Beginners - This article is part of a series.
Part 10: This Article

Related