Using Device-Specific Parameters for Flexible Driver Configuration in VxWorks 7
Device-specific parameters offer a robust mechanism to fine-tune driver behavior for particular hardware configurations—without relying on hard-coded values. This guide illustrates how to implement this flexibility using a real-world example from a PCIe controller driver developed for the Renesas R-Car H3 SIP evaluation board.
Background #
We developed a VxWorks 7 BSP for the Renesas R-Car H3, including drivers for key peripherals: serial, Ethernet, MMC, I2C, GPIO, and PCI Express. To validate the PCI Express driver, we inserted an Intel i210 PCIe card into the board’s slot, loaded the VxWorks 7 Intel gigabit Ethernet driver, and verified successful detection and integration into the network stack.
This BSP was shared across our development teams globally. Eventually, a problem surfaced: a PCIe-based CAN controller wasn’t initializing on boot. Investigation showed that the PCIe link between root complex and endpoint wasn’t forming in time.
Identifying the Issue #
The issue stemmed from a hardcoded 1 ms timeout for link establishment in the PCIe driver. However, the CAN controller card needed up to 5 ms. Simply increasing the timeout would negatively affect boot time in cases where no PCIe peripherals were present.
Solution: Device-Specific Parameters #
Instead of a global timeout change, we made the timeout configurable per device through the device tree.
Step 1: Define the Driver Parameter Table #
We created a parameter table with a default value:
/* R-Car H3 PCIe controller driver parameter table */
LOCAL VXB_PARAMS rcarH3PcieParams[] =
{
{ DLLACT_TIMEOUT_PARAM, VXB_PARAM_INT32, { (void *)DLLACT_TIMEOUT_US } },
{ NULL, VXB_PARAM_END_OF_LIST, { NULL } }
};
Step 2: Declare the Parameter Table in the Driver Definition #
Use the VXB_DRVFLAG_PARAM
flag to declare the parameter table:
/* R-Car H3 PCIe controller VxBus driver definition */
VXB_DRV vxbFdtRcarH3PcieDrv =
{
{ NULL }, // list node
RCAR_H3_PCIE_DRV_NAME, // Name
"Renesas R-Car H3 PCIe driver", // Description
VXB_BUSID_FDT, // Class
VXB_DRVFLAG_PARAM, // Flags
0, // Reference count
rcarH3PcieMethodList, // Method table
rcarH3PcieParams // Parameter defaults
};
Step 3: Update Driver Initialization to Use the Parameter #
Retrieve the parameter during initialization:
/* Get the DLL activation timeout from the driver parameter table */
if (vxbParamGet (pDev, DLLACT_TIMEOUT_PARAM, VXB_PARAM_INT32, ¶m) == OK)
{
dllActTimeoutUs = (unsigned)param.int32Val;
}
else
{
PCIEC_DBG (PCIEC_DBG_ERR,
"%s: pDev %p: Failed to get DLL timeout parameter - using default\n",
__FUNCTION__, pDev);
}
The driver uses the default value unless overridden in the device tree.
Step 4: Override with Device Tree Parameters #
We added a devparam
node to the chosen
section of the device tree. This allows specific parameters to be set per device.
Example Format (from VxWorks 7 documentation): #
chosen {
...
devparam {
<devName>@<devUnit> {
<parameter name> = <parameter value>;
...
};
};
};
Example Override for R-Car H3 #
To set a 5000 μs timeout:
chosen {
bootargs = "etherAvb(0,0) host:vxWorks h=192.168.0.2 e=192.168.0.20 u=target pw=vxTarget";
devparam {
renesas,rcar-h3-pcie@0 {
dllActTimeoutUs = <5000>;
};
};
};
Debug Output When No Card Is Present #
rcarH3PcieHwInit: pDev 0xffff80000011f980: PCIe DLL not ready after 5000us
rcarH3PcieAttach: pDev 0xffff80000011f980: error exit
This confirmed the timeout override was active and functional.
Conclusion #
Using device-specific parameters allowed teams using the PCIe CAN controller to fine-tune their configuration through the device tree, improving reliability without negatively impacting other systems.
This approach provides flexibility and avoids embedding assumptions directly into driver code. For more details, refer to the VxBus Driver Tunables section in the VxWorks 7 BSP and Driver Guide.