Skip to main content

Writing a Simple Device Driver in VxWorks

·547 words·3 mins
VxWorks RTOS Device Driver Embedded Systems Programming Tutorial
Table of Contents
VxWorks Programming Tutorial for Beginners - This article is part of a series.
Part 5: This Article

🚀 Introduction
#

So far in this series, we’ve explored:

  • Tasks and scheduling
  • Semaphores for synchronization
  • Message queues for inter-task communication

Now it’s time to dive deeper into the hardware side of VxWorks: device drivers.

In this tutorial, you’ll learn:

  • What device drivers are in VxWorks.
  • The difference between built-in drivers and custom drivers.
  • How to write a simple character device driver with a read/write interface.

🧩 What is a Device Driver?
#

A device driver is a software layer that allows the VxWorks kernel and user tasks to interact with hardware devices in a uniform way.

In VxWorks:

  • Drivers are usually integrated into the I/O system.
  • A device is represented as a file-like object (open, read, write, close).
  • Developers implement driver routines (e.g., open(), read(), write(), ioctl()).

💻 Example: A Simple Character Device Driver
#

We’ll create a dummy driver called /myDev/ that stores a small buffer in memory.
Tasks can write to it and read from it, just like a file.

Code Example
#

#include <vxWorks.h>
#include <iosLib.h>
#include <errnoLib.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 128

// Device buffer
static char deviceBuffer[BUFFER_SIZE];
static int dataLength = 0;

// Forward declarations
int myOpen(DEV_HDR *pDev, const char *name, int flags, int mode);
int myClose(DEV_HDR *pDev);
ssize_t myRead(DEV_HDR *pDev, char *buffer, size_t maxBytes);
ssize_t myWrite(DEV_HDR *pDev, const char *buffer, size_t nBytes);

// Driver table
typedef struct {
    DEV_HDR devHdr;
} MY_DEV;

MY_DEV myDevice;

// Open device
int myOpen(DEV_HDR *pDev, const char *name, int flags, int mode)
{
    printf("Device opened: %s\n", name);
    return (int)pDev;
}

// Close device
int myClose(DEV_HDR *pDev)
{
    printf("Device closed\n");
    return 0;
}

// Read device
ssize_t myRead(DEV_HDR *pDev, char *buffer, size_t maxBytes)
{
    int bytesToCopy = (dataLength < maxBytes) ? dataLength : maxBytes;
    memcpy(buffer, deviceBuffer, bytesToCopy);
    printf("Device read: %d bytes\n", bytesToCopy);
    return bytesToCopy;
}

// Write device
ssize_t myWrite(DEV_HDR *pDev, const char *buffer, size_t nBytes)
{
    int bytesToCopy = (nBytes < BUFFER_SIZE) ? nBytes : BUFFER_SIZE;
    memcpy(deviceBuffer, buffer, bytesToCopy);
    dataLength = bytesToCopy;
    printf("Device write: %d bytes\n", bytesToCopy);
    return bytesToCopy;
}

// Install device
void myDevCreate()
{
    iosDrvInstall((FUNCPTR)myOpen, (FUNCPTR)myClose,
                  (FUNCPTR)myOpen, (FUNCPTR)myClose,
                  (FUNCPTR)myRead, (FUNCPTR)myWrite, NULL);

    iosDevAdd(&myDevice.devHdr, "/myDev/", 0);
    printf("Device /myDev/ created\n");
}

📝 Explanation of the Code
#

  1. iosDrvInstall()

    • Registers driver functions (open, close, read, write).
  2. iosDevAdd()

    • Adds a device node (in this case /myDev/) into the VxWorks I/O system.
  3. Driver Functions

    • myWrite() stores data in a buffer.
    • myRead() retrieves data from the buffer.
  4. Usage

    • Once myDevCreate() is called (e.g., from usrAppInit()), tasks can use standard APIs like:
int fd = open("/myDev/", O_RDWR, 0);
write(fd, "Hello Driver", 12);
char buffer[32];
read(fd, buffer, sizeof(buffer));
close(fd);

⚡ What You’ll See
#

When running this program, the output will look like:

Device /myDev/ created
Device opened: /myDev/
Device write: 12 bytes
Device read: 12 bytes
Device closed

🔍 Key Takeaways
#

  • VxWorks device drivers integrate with the I/O system.
  • Drivers expose file-like operations (open, read, write).
  • You can simulate hardware using memory-backed drivers for testing.

✅ Wrap-Up
#

In this tutorial, you learned:

  • The basics of device drivers in VxWorks.
  • How to write and register a simple character driver.
  • How tasks can interact with a device as if it were a file.

In the next blog, we’ll extend this by exploring interrupt handling in VxWorks drivers.

👉 Stay tuned for Blog 6: “Interrupt Handling in VxWorks Device Drivers.”

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

Related

Message Queues in VxWorks: Passing Data Between Tasks
·480 words·3 mins
VxWorks RTOS Message Queues Inter-Task Communication Embedded Systems Programming Tutorial
Using Semaphores for Task Synchronization in VxWorks
·434 words·3 mins
VxWorks RTOS Semaphores Task Synchronization Embedded Systems Programming Tutorial
Understanding Tasks and Scheduling in VxWorks
·423 words·2 mins
VxWorks RTOS Tasks Scheduling Embedded Systems Programming Tutorial