| Products & Services | Solutions | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → xPC Target |
| Contents | Index |
| Learn more about xPC Target |
| On this page… |
|---|
When writing xPC Target drivers for PCI devices, consider the memory access method. A PCI device can be either I/O port mapped or memory mapped.
I/O port mapped — The BIOS assigns a port range.
Memory mapped — The BIOS assigns a memory region, if your device is memory mapped.
The PC BIOS automatically assigns a conflict-free set of resources to any PCI device found in the system at boot-up. You typically do not know where the board resides (base address) before driver initialization. However, you can obtain this information by querying the PCI configuration space at run time. The xPC Target software provides functions to accomplish this (see the PCI Configuration Information functions).
To locate a PCI device, you need the following:
Vendor and device ID
Optionally, subsystem vendor and subsystem device ID
Slot number or bus and slot number
You can have the drivers locate PCI devices in one of the following ways:
If the system has one board of any one type, you can use the driver slot option to search for the first board that matches a vendor and device ID. To initiate this search, set this option to -1.
If the system contains multiple boards of the same type, setting the slot option to -1 does not find the additional boards. In that case, specify the bus and slot numbers with the vendor and device IDs.
Before you can access a PCI device, you need to access the configuration space to locate the board in the target PC memory. This section describes the procedure to do this.
For PCI devices, the driver will need to access the PCI configuration space for the board. This space contains relevant board information such as the base address and access type (I/O port or memory mapped). The xPC Target software provides functions that allow the driver to access this space.
Vendor and device ID — The driver searches all boards for the specified vendor (manufacturer) and device ID. The PCI Steering Committee, an independent standards body, assigns a unique vendor ID (uint16) to each PCI board vendor. Each vendor then assigns a unique ID to each PCI board type it supports.
Note Vendor and device IDs do not always uniquely identify a board. For example, all boards that use the PLX-9080 bus interface chip have a vendor ID of 10B5 (the vendor ID assigned to PLX Technology, Inc.). The device ID for the chip is 9080. In cases like this, to select a particular board that contains this chip, you must use a subvendor and subdevice ID in addition to the vendor and device IDs. |
Slot number or bus and slot number — The driver looks only for the board that matches the specified vendor and device ID and slot number.
Use the xpcGetPCIDeviceInfo function to get information for a PCI device in your system. The syntax for this function is:
int xpcGetPCIDeviceInfo (uint16_T vendorId, uint16_T deviceId, uint16_T subVendorId, uint16_T subDeviceId, uint16_T bus, uint16_T slot, xpcPCIDevice *pciInfo);
This function returns the xpcPCIDevice structure filled according to the following:
| If You Supply... | This Function.... |
|---|---|
| All the parameters | Looks for a device that matches all the parameters and returns the xpcPCIDevice structure for that device. Use this form if you know that your system has multiple boards from the same vendor with the same ID and you want your user to specify the exact device. |
| XPC_NO_SUB for the subVendorId or subDeviceId parameter | Does not consider the subvendor or subdevice ID when looking for a match for the specified device. It returns the xpcPCIDevice structure for a device that matches the other parameters. You can use this form if you do not plan to use the subVendorId or subDeviceId values. |
| XPC_NO_BUS_SLOT for the slot for the device | Returns the first PCI device it finds that matches the remaining parameters. You can use this form if you know that your system has only one board with a particular ID set. |
xPC Target drivers use the following convention to fill in slot parameters and retrieve slot information. Choose the convention that will work best for you.
| Set... | To... |
|---|---|
Set slot = -1 | Assume bus = 0 and call the xpcGetPCIDeviceInfo function to find the first instance of the board. |
Set slot = S | Assume bus = 0 and call the xpcGetPCIDeviceInfo function to find the specified board. If the board matches the IDs, return the PCI information to the driver. Otherwise, return an error. |
Set slot = [B, S] | Check bus B and slot S for the specified board. If the board matches the IDs, return the PCI information to the driver. Otherwise, return an error. Setting slot = [0, S] is identical to slot = S. |
The following example illustrates how to use the xpcGetPCIDeviceInfo function to program the driver to accept slot number input or slot and bus number input from the driver block.
Pass the slot number or slot and bus number into the xpcGetPCIDeviceInfo function using code like the following:
uint16_T vendorId, deviceId;
int32_T bus, slot, subvendor, subdevice;
xpcPCIDevice pciInfo;
/* S_PCI_SLOT_ARG is passed in from the mask */
/* Typically the slot arg is a scalar containing -1 if there is only one board of
this type in the target */
/* If there are multiple boards of this type the slot arg is a vector containing bus
and slot info */
/* This code snipped parses the slot arg into bus and slot */
if ( (int_T)(mxGetN(ssGetSFcnParam(S, S_PCI_SLOT_ARG))) == 1 ) {
bus = 0;
slot = (int32_T)(mxGetPr(ssGetSFcnParam(S, S_PCI_SLOT_ARG))[0]);
} else {
bus = (int32_T)(mxGetPr(ssGetSFcnParam(S, S_PCI_SLOT_ARG))[0]);
slot = (int32_T)(mxGetPr(ssGetSFcnParam(S, S_PCI_SLOT_ARG))[1]);
}
vendorId = (uint16_T)0x1234;
deviceId = (uint16_T)0x9876;
subvendor = (uint16_T)0x5678;
subdevice = (uint16_T)0x8765;
/* Set subvendor and subdevice to XPC_NO_SUB, XPC_NO_SUB if they are not necessary */
/* xpcGetPCIDeviceInfo() populates the pciInfo struct */
if ( xpcGetPCIDeviceInfo(vendorId, deviceId,
subvendor, subdevice,
bus, slot,
&pciInfo) ) {
sprintf(msg, "Board 0x%x not found at bus %d slot %d", deviceId, bus, slot);
ssSetErrorStatus(S, msg);
return;
}For detailed information on the xpcPCIDevice structure, see xpcPCIDevice.
A memory-mapped PCI board uses up to six memory regions to access board regions and memory. Each region might also have a different length. You must call the xpcReserveMemoryRegion function for each PCI memory region you want to access; use the returned virtual address to access the region. Failure to do this will result in a segmentation fault.
To access a memory mapped location, do the following:
Declare a pointer of the appropriate size to the memory. For example:
volatile uint32 *csr; /* Control and status register */
Note that you will want to use the volatile keyword here; otherwise, the compiler might optimize away accesses to this location.
Set its value (address) to the physical address at which the register resides.
To access I/O ports, use the following functions:
xpcInpB, xpcInpW, xpcInpDW — I/O port input functions for byte, word, and double word accesses
xpcOutpB, xpcOutpW, xpcOutpDW — I/O port output functions for byte, word, and double word accesses
![]() | PCI Drivers | Sample PCI Device Driver | ![]() |

Learn more about Simulink through this collection of videos, articles, technical literature and the Getting Started with Simulink Guide.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |