Skip to main content

VxWorks UART Programming: Serial Port Configuration and I/O

·631 words·3 mins
VxWorks UART Serial Port Embedded Systems RTOS Driver Development
Table of Contents

VxWorks UART Programming: Serial Port Configuration and I/O

UART (Universal Asynchronous Receiver/Transmitter) remains a fundamental interface for debugging, control, and device communication in embedded systems. While the programming model is broadly consistent across operating systems, VxWorks exposes UART functionality through its I/O system and ioctl interface.

This guide provides a practical walkthrough of configuring serial ports, performing read/write operations, and implementing a complete UART task in VxWorks.

🛠️ Serial Port Configuration
#

Opening the Serial Device
#

Serial ports in VxWorks are exposed as device files:

fd = open("/tyCo/0", O_RDWR, 0);
  • /tyCo/0: First serial device
  • O_RDWR: Enables both read and write access

Device naming may vary depending on BSP and hardware configuration.

Configuring Mode and Buffers
#

Basic configuration is performed using ioctl():

ioctl(fd, FIOSETOPTIONS, OPT_RAW);
ioctl(fd, FIOFLUSH, 0);
  • OPT_RAW: Disables line processing (raw data mode)
  • FIOFLUSH: Clears input/output buffers

Common ioctl Commands
#

Command Purpose
FIOBAUDRATE Set baud rate
FIOGETOPTIONS Retrieve current options
FIOSETOPTIONS Apply device options
FIOREAD Query unread bytes
FIOWRITE Query pending output
FIOFLUSH Clear buffers
FIOCANCEL Cancel I/O operations

Setting Line Parameters
#

Hardware-level configuration is applied using:

ioctl(fd, SIO_HW_OPTS_SET, CS8 | PARENB | CLOCAL | CREAD);

Key flags:

  • CS8: 8 data bits
  • PARENB: Enable parity
  • PARODD: Odd parity (optional)
  • CLOCAL: Ignore modem control
  • CREAD: Enable receiver

🔄 UART Read and Write Operations
#

Once configured, UART communication uses standard POSIX-style APIs:

int read(int fd, char *buffer, size_t maxbytes);
int write(int fd, char *buffer, size_t nbytes);

Parameters
#

  • fd: File descriptor from open()
  • buffer: Data buffer
  • maxbytes / nbytes: Transfer size

These APIs integrate seamlessly with the VxWorks I/O system.

💻 Complete UART Example
#

The following example demonstrates a UART task that periodically sends data while coordinating access via shared memory and semaphores.

#include "vxWorks.h"
#include "stdio.h"
#include "ioLib.h"
#include "taskLib.h"
#include "sioLib.h"
#include "sdLib.h"
#include "semLib.h"
#include "msgQLib.h"

#define DEV_NAME "/tyCo/2"
#define MAX_BUF_SIZE 20
#define SHARE_DATA_LENGTH 20

typedef struct unix_clock_struct 
{
    UINT32 sec;    
    UINT32 msec;   
    UINT8 quality; 
} UNIX_CLOCK_STRUCT;

char *comdata;
SEM_ID mutexComdata;

int set_serial(int fd);

void taskUart(void)
{
    int ret;
    int fd = open(DEV_NAME, O_RDWR, 0);
    UNIX_CLOCK_STRUCT w_buff;

    if (fd < 0)
        printf("open failed.\n");

    if (set_serial(fd) < 0)
        printf("serial config failed.\n");

    while (1)
    {
        semTake(mutexComdata, WAIT_FOREVER);

        ioctl(fd, FIOFLUSH, 0);
        bzero(&w_buff, sizeof(w_buff));
        memcpy(&w_buff, comdata, sizeof(w_buff));

        if (write(fd, &w_buff.sec, sizeof(w_buff.sec)) < 0)
            printf("write failed.\n");
        else
            printf("write success: %d\n", w_buff.sec);

        semGive(mutexComdata);
        taskDelay(sysClkRateGet() * 2);
    }
}

int set_serial(int fd)
{
    if (fd < 0)
        return -1;

    if (ioctl(fd, FIOBAUDRATE, 9600) < 0)
        return -1;

    if (ioctl(fd, SIO_HW_OPTS_SET, CREAD | CS8 | CLOCAL) < 0)
        return -1;

    return 0;
}

🔍 Key Implementation Insights
#

Synchronization
#

  • Use semaphores (semTake, semGive) to protect shared data
  • Prevent concurrent access to UART resources

Buffer Management
#

  • Clear buffers before transmission (FIOFLUSH)
  • Avoid stale or partial data reads

Task-Based Design
#

  • Run UART logic in a dedicated task
  • Control execution rate using taskDelay()

⚠️ Common Pitfalls
#

Incorrect Device Name
#

  • /tyCo/x mapping depends on BSP configuration
  • Verify using system device listing

Misconfigured Line Settings
#

  • Incorrect parity or data bits can corrupt communication
  • Ensure both ends match configuration

Blocking Behavior
#

  • read() may block if no data is available
  • Consider non-blocking modes or timeouts

✅ Best Practices
#

  • Always validate file descriptors and return values
  • Use raw mode for binary communication
  • Encapsulate configuration into reusable functions
  • Separate UART logic from application logic
  • Log errors for easier debugging in production systems

📌 Conclusion
#

UART programming in VxWorks builds on a familiar POSIX-style model while leveraging powerful configuration via ioctl. By combining proper device setup, robust synchronization, and task-based design, developers can implement reliable serial communication for debugging, control, and data exchange.

This foundation can be extended to support interrupt-driven drivers, DMA-based transfers, or higher-level communication protocols in more advanced embedded systems.

Reference: VxWorks UART Programming: Serial Port Configuration and I/O

Related

PCI-RapidIO Bridge Driver Design on VxWorks
·731 words·4 mins
VxWorks RapidIO PCI Device Driver Embedded Systems
Meet the VxWorks RTOS
·14 words·1 min
VxWorks VxWorks 7
The Capital Transaction History of Wind River
·680 words·4 mins
Wind River VxWorks Linux Acquisition Aptiv TPG