Skip to main content

Practical PCIe Device Driver Development on VxWorks 7

·515 words·3 mins
PCIe VxWorks 7
Table of Contents
BSP - This article is part of a series.
Part 14: This Article

Introduction
#

In fields like industrial control, data acquisition, and communications, PCIe controllers from PLX (now part of Broadcom) are widely used. VxWorks 7, the latest real-time operating system from Wind River, introduces a modernized and modular driver framework called VxBus 2.0. This article walks through the process of developing a PCIe device driver for VxWorks 7 using a PLX controller such as the PLX8725, including practical code examples.

Overview of the VxBus 2.0 Driver Model
#

VxBus is the official driver framework in VxWorks. VxBus 2.0, introduced in VxWorks 7, brings several improvements:

  • Object-oriented and layered architecture
  • Dynamic device plug-and-play support
  • Better SMP (multi-core) support
  • Compatibility with Flattened Device Tree (FDT)

A typical driver in VxBus 2.0 includes:

  • A probe function to match supported devices
  • An attach function to map hardware resources and register interrupts
  • A detach function (optional) to release resources
  • Public API functions for application interaction

About the PLX PCIe Controller (e.g., PLX8725)
#

PLX PCIe switches and bridges, such as the PLX8725 or PLX8749, offer:

  • Multiple BARs (Base Address Registers) for register mapping
  • MSI/MSI-X interrupt support
  • A built-in DMA engine
  • Hot-plug capabilities and event signaling

These devices are typically detected and initialized via PCI configuration space in VxWorks.

Optional Device Tree Configuration
#

When using Device Tree (FDT), a PCIe node can be described like this:

pcie@0x80000000 {
    compatible = "plx,pcie8725";
    reg = <0x80000000 0x1000>; // BAR region
    interrupts = <32>;         // IRQ number
};

In the driver, APIs such as vxbFdtDevGet() and vxbResourceAlloc() are used to retrieve these resources.

VxBus Driver Code Framework
#

Header File: plxPcieDrv.h

#define PLX_VENDOR_ID   0x10B5
#define PLX_DEVICE_ID   0x8725

typedef struct {
    VXB_DEV_ID dev;
    void * barBase;
    int irq;
    VXB_RESOURCE * pResBar;
    VXB_RESOURCE * pResIrq;
} PLX_PCIE_DRV_CTRL;

Driver Implementation: plxPcieDrv.c

LOCAL STATUS plxPcieProbe(VXB_DEV_ID dev) {
    UINT16 vendorId, deviceId;
    vxbPciConfigRead16(dev, PCI_CFG_VENDOR_ID, &vendorId);
    vxbPciConfigRead16(dev, PCI_CFG_DEVICE_ID, &deviceId);
    return (vendorId == PLX_VENDOR_ID && deviceId == PLX_DEVICE_ID) ? OK : ERROR;
}

LOCAL STATUS plxPcieAttach(VXB_DEV_ID dev) {
    PLX_PCIE_DRV_CTRL *pCtrl = vxbMemAlloc(sizeof(*pCtrl));
    if (!pCtrl) return ERROR;

    pCtrl->dev = dev;
    pCtrl->pResBar = vxbResourceAlloc(dev, VXB_RES_MEMORY, 0);
    pCtrl->barBase = (void *)vxbResourceVirtAdrsGet(pCtrl->pResBar);
    pCtrl->pResIrq = vxbResourceAlloc(dev, VXB_RES_IRQ, 0);
    pCtrl->irq = (int)(long)vxbResourceAdrsGet(dev, VXB_RES_IRQ, 0);

    vxbDevSoftcSet(dev, pCtrl);
    vxbIntConnect(dev, pCtrl->pResIrq, plxPcieIsr, pCtrl);
    vxbIntEnable(dev, pCtrl->pResIrq);
    return OK;
}

LOCAL void plxPcieIsr(void *param) {
    PLX_PCIE_DRV_CTRL *pCtrl = (PLX_PCIE_DRV_CTRL *)param;
    UINT32 status = *(volatile UINT32 *)(pCtrl->barBase + 0x04);
    *(volatile UINT32 *)(pCtrl->barBase + 0x04) = status;
    // Custom interrupt handling here
}

Driver registration section:

LOCAL VXB_DRV plxPcieDrv = {
    {NULL},
    "plxPcie", "PLX PCIe Driver",
    VXB_BUSID_PCI, 0, 0,
    plxPcieProbe, plxPcieAttach, NULL
};

VXB_DRV_DEF(plxPcieDrv)
VXB_DRV_MOD_INSTALL(plxPcieDrv)

Debugging Tips
#

  • View PCI configuration:
-> vxbPciShow()
  • List registered devices:
-> vxbDevShow()
  • Print BAR and IRQ:
printf("BAR0 base: 0x%x, IRQ: %d\n", pCtrl->barBase, pCtrl->irq);
  • Use WindView to trace interrupt latency

Recommended Extensions #

  • Enable DMA transfer using vxbDma* interfaces
  • Add user-space interface via ioctl or shared memory
  • Support for hot-plug events and multiple BARs

Conclusion
#

Combining VxWorks 7 with PLX PCIe controllers enables high-performance, real-time communication. With the modular VxBus 2.0 framework and Device Tree support, driver development becomes clean and scalable. This guide and starter code should serve as a strong foundation for your own PCIe driver development.

BSP - This article is part of a series.
Part 14: This Article

Related

Configuring a VxWorks 7 System With Secure User Authentication
·605 words·3 mins
VxWorks 7 User Authentication
VxWorks 7 BSP Development Guide
·1720 words·9 mins
VxWorks 7 Workbench
TCP Socket Programming on VxWorks 7
·1051 words·5 mins
VxWorks 7 Socket TCP