๐ Overview #
Embedded platforms such as industrial controllers and communication gateways often outgrow the limited UARTs provided by on-chip peripherals. A 2011 paper documents a practical VxWorks device driver for the XR16L788 dual serial port chip. By integrating two XR16L788 devices with a Samsung S3C2410 ARM processor, the system expands to 16 reliable serial ports.
Although the work targets legacy ARM9 hardware, its driver architecture and implementation strategy remain directly applicable to modern VxWorks serial driver development.
๐งฑ VxWorks Serial Driver Model #
VxWorks classifies serial ports as character devices managed through the I/O system. Applications interact with UARTs via standard APIs, while hardware details are encapsulated inside the driver.
The driver exposes a standard SIO (Serial I/O) interface, enabling:
- Hardware-independent access
- Dynamic driver loading
- Clean separation between application and hardware logic
This modular model allows serial drivers to evolve without kernel recompilation.
๐งฉ Hardware Configuration #
The reference design consists of:
- CPU: Samsung S3C2410 (ARM9)
- UART expansion: Two Exar XR16L788 chips
- Total UARTs: 16 serial channels
Each XR16L788 provides eight high-speed UARTs with 64-byte TX/RX FIFOs and supports shared interrupts. The chips connect to the CPU via memory-mapped registers, minimizing additional glue logic.
๐ ๏ธ Driver Data Structures #
The driver adopts a two-level structure: one for the device and one for each UART channel.
#define MAX_XR16788_DEVS 2 // Number of XR16L788 devices
#define MAX_XR16788_CHANS 8 // Channels per device
typedef struct XR16L788_DEV {
int devNum; // Device index (0,1...)
int devRegBase; // Base register address
int oscFreq; // Input clock frequency
int intNum; // CPU interrupt number
int intMask; // Interrupt mask
char *devNamePrefix; // Device name prefix
void *pChanArray; // Array of channels
} XR16L788_DEV;
typedef struct XR16L788_CHAN {
SIO_CHAN sio; // System SIO struct
STATUS (*getTxChar)(); // TX callback
STATUS (*putRcvChar)(); // RX callback
void *getTxArg;
void *putRcvArg;
int chNum; // Channel index
int chRegBase; // Channel register base
int baudRate; // Baud rate
int options; // Feature flags
int mode; // Interrupt or poll mode
XR_CH_REG *pXrChReg; // Channel registers
struct XR16L788_DEV *pXrDev; // Parent device
} XR16L788_CHAN;
This layout cleanly separates shared device resources from per-channel state, simplifying scaling and maintenance.
โ๏ธ Hardware Initialization #
Initialization is split into two phases. The first configures chip-level signals and timing, while the second initializes individual channels.
void sysSerialHwInit_16788(void) {
xr16788Init(); // Init chip signals and timing
for (devNum = 0; devNum < MAX_XR16788_DEVS; devNum++) {
pDev = &xr16788Dev[devNum];
pDev->pChanArray = &xr16788Chan[devNum];
if (ERROR == xrInitDev(pDev)) continue;
for (chanNum = 0; chanNum < MAX_XR16788_CHANS; chanNum++) {
pChan = &xr16788Chan[devNum][chanNum];
xrInitChan(pChan); // Channel-specific init
}
}
}
A second-stage routine connects interrupts and registers the channels with the VxWorks I/O system.
โก Interrupt Handling #
All UART channels on a device share a single interrupt. The ISR reads the interrupt identification register and dispatches processing accordingly.
void xr16788Int(XR16L788_DEV *pDev) {
UINT8 iir = XR_READ(pDev, IIR);
if (iir & XR_IIR_NO_INT) return;
switch (iir & XR_IIR_ID_MASK) {
case XR_IIR_RX_RDY:
xrRxInt(pDev->pChanArray[i]);
break;
case XR_IIR_TX_RDY:
xrTxInt(pDev->pChanArray[i]);
break;
}
}
This centralized interrupt strategy reduces overhead while maintaining deterministic response times.
๐ SIO Operations and Baud Configuration #
The driver implements standard SIO callbacks, including open, close, read, write, and ioctl operations. Baud rate configuration follows the classic UART divisor model.
STATUS xr16788Ioctl(XR16L788_CHAN *pChan, int request, void *arg) {
switch (request) {
case SIO_BAUD_SET:
baud = *(int *)arg;
divisor = pChan->pXrDev->oscFreq / (16 * baud);
// Program DLL/DLM via DLAB
break;
}
return OK;
}
Strict compliance with the SIO interface ensures compatibility with existing VxWorks applications.
๐งช Validation Results #
Testing confirmed stable full-duplex communication across all 16 ports at multiple baud rates, including long-duration stress tests. No data loss or interrupt anomalies were observed, validating the design for real-time use.
๐ Relevance in 2025 #
While the XR16L788 and S3C2410 are now considered legacy components, the driver structure, interrupt model, and SIO integration remain directly applicable to newer UART expansion chips and VxWorks 7-based systems. For engineers extending serial I/O on ARM, FPGA, or PCIe platforms, this design remains a solid reference implementation.