The process for serial port programming is generally consistent across major operating systems; only the function interfaces may differ. This article explains how to perform serial port read and write operations in VxWorks, including configuration commands and a complete example.
🛠️ Serial Port Configuration #
Opening the Serial Port #
fd = open("/tyCo/0", O_RDWR, 0);
- "/tyCo/0": The device name for serial port 1.
- O_RDWR: Opens the serial port for both reading and writing.
Setting Raw Mode and Clearing Buffers #
In VxWorks, you can configure the serial port using the ioctl control interface.
ioctl(fd, FIOSETOPTIONS, OPT_RAW);
ioctl(fd, FIOFLUSH, 0);
Key parameters for ioctl:
| Function | Description |
|---|---|
FIOBAUDRATE |
Set baud rate (arg = baud rate value). |
FIOGETOPTIONS |
Get current device options. |
FIOSETOPTIONS |
Set device options. |
FIOGETNAME |
Get file name for descriptor. |
FIOREAD |
Get unread input bytes. |
FIOWRITE |
Get pending output bytes. |
FIOFLUSH |
Clear input/output buffers. |
FIOCANCEL |
Cancel read/write operations. |
Setting Baud Rate and Line Options #
Serial configuration such as baud rate, data bits, stop bits, and parity is also done via ioctl using the SIO_HW_OPTS_SET command:
ioctl(fd, SIO_HW_OPTS_SET, CS8 | PARENB | CLOCAL | CREAD);
| Parameter | Description |
|---|---|
CLOCAL |
Ignore modem control lines. |
CREAD |
Enable receiver. |
CSIZE |
Data bits (CS5–CS8). |
STOP8 |
Two stop bits if set; otherwise one. |
PARENB |
Enable parity checking. |
PARODD |
Use odd parity (requires PARENB). |
📖 Serial Port Read and Write #
VxWorks supports direct use of the standard read() and write() calls:
int read(int fd, char *buffer, size_t maxbytes);
int write(int fd, char *buffer, size_t nbytes);
Parameters
fd: File descriptor returned byopen().buffer: Data buffer.maxbytes/nbytes: Maximum number of bytes to read or write.
📝 Example Code #
Example implementation of serial port read/write on VxWorks:
#include "vxWorks.h"
#include "stdio.h"
#include "ioLib.h"
#include "taskLib.h"
#include "sioLib.h"
#include "sdLib.h"
#include "semLib.h"
#include "msgQLib.h"
char wbuf[] = "hello";
#define DEV_NAME "/tyCo/2"
#define MAX_BUF_SIZE 20
#define SD_COMMDATA_NAME "share_data"
#define SD_COMMDATA_MUTEX "share_sem"
#define SHARE_DATA_LENGTH 20
typedef struct unix_clock_struct
{
UINT32 sec;
UINT32 msec;
UINT8 quality;
} UNIX_CLOCK_STRUCT;
char *comdata;
int set_serial(int fd);
SEM_ID mutexComdata;
void taskUart(void);
int main(void)
{
int ret;
int sdCommId;
char r_buff[MAX_BUF_SIZE];
mutexComdata = semOpen(SD_COMMDATA_MUTEX, SEM_TYPE_MUTEX, SEM_FULL,
SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE,
OM_CREATE | OM_DELETE_ON_LAST_CLOSE, NULL);
if (mutexComdata == NULL)
{
printf("ERROR: unable to open SD_COMMDATA_MUTEX\n");
taskExit(0);
}
sdCommId = sdOpen(SD_COMMDATA_NAME, SD_LINGER, OM_CREATE, SHARE_DATA_LENGTH, 0,
SD_ATTR_RW | SD_CACHE_OFF, &comdata);
if (sdCommId == NULL)
{
printf("ERROR: unable to open SD_COMMDATA\n");
taskExit(0);
}
if ((ret = taskSpawn("taskUart", 90, 0x100, 20000, (FUNCPTR)taskUart,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) < 0)
{
printf("taskSpawn failed: ret = %d\n", ret);
}
return 0;
}
void taskUart(void)
{
int ret;
int fd = -1;
UNIX_CLOCK_STRUCT w_buff;
if ((fd = open(DEV_NAME, O_RDWR, 0)) < 0)
printf("open %s failed.\n", DEV_NAME);
if ((ret = set_serial(fd)) < 0)
printf("ret = %d\nset_serial failed.\n", ret);
while (1)
{
semRTake(mutexComdata, WAIT_FOREVER);
if ((ret = ioctl(fd, FIOFLUSH, 0)) < 0)
printf("ret = %d\nset FIOFLUSH failed.\n", ret);
if (NULL == bzero(&w_buff, sizeof(w_buff)))
printf("bzero failed.\n");
if (NULL == memcpy(&w_buff, comdata, sizeof(w_buff)))
printf("memcpy failed.\n");
if (&w_buff != NULL)
{
if ((ret = write(fd, &w_buff.sec, sizeof(ret))) < 0)
printf("ret = %d: write %s failed.\n", ret, DEV_NAME);
else
printf("write success: %d\n", w_buff.sec);
}
semGive(mutexComdata);
taskDelay(sysClkRateGet() * 2);
}
}
int set_serial(int fd)
{
int ret;
if (fd < 0)
{
printf("error: invalid fd = %d\n", fd);
return -1;
}
if ((ret = ioctl(fd, FIOBAUDRATE, 9600)) < 0)
{
printf("ret = %d\nset baudrate failed\n", ret);
return -1;
}
if ((ret = ioctl(fd, SIO_HW_OPTS_SET, CREAD | CS8 | CLOCAL)) < 0)
{
printf("ret = %d\nset SIO_HW_OPTS_SET failed.\n", ret);
return -1;
}
return 0;
}
Summary:
This article demonstrated how to configure and use serial ports in VxWorks, including baud rate setup, ioctl configuration, and data transmission via read() and write(). The provided example can serve as a foundation for developing more complex UART communication applications.