NI does not actively maintain this document.
This content provides support for older products and technology, so you may notice outdated links or obsolete information about operating systems or other relevant products.
This tutorial explains how to use the Measurement Hardware Driver Development Kit (MHDDK) on an operating system that does not have an operating system interface bus (iBus) implementation.
In order to use the Chip Objects in the Measurement Hardware Driver Development Kit (MHDDK) on an operating system, you must have an iBus for that operating system. This document covers the basics of an iBus and the considerations for creating one for your target operating system.
An iBus is an OS abstraction layer. It provides a simple interface to the PCI/PXI bus for the example programs in the MHDDK. It provides simple functions for register I/O and, if supported, DMA buffer operations.
These are the two functions you will need to define to make the iBus work on your target OS. Almost all of the system dependent code for the RLP examples is in osiUserCode.cpp. To port an iBus to a new OS:
iBus* acquireBoard(tChar* brdLocation);
This function creates the iBus and maps the Base Address Ranges (BARs) for the selected PCI device into memory. It can store system-specific data by using void *osSpecific in the iBus. This is a convenient way to share data with releaseBoard(…), such as OS specific structures, pointers, or file numbers.
On most systems, acquireBoard(…) will:
void releaseBoard(iBus* &bus);
This function deletes the iBus created by acquireBoard(…).
On most systems, releaseBoard(…) will:
These are the two functions you will need to define to make the iBus support DMA on your target OS:
tDMAMemory* iBus::allocDMA (u32 size);
This function requests a block of DMA memory and maps it into memory. Typically, the tDMAMemory class is subclassed to hold OS-specific information so that data can be shared with freeDMA(…).
On most systems, allocDMA(…) will:
void iBus::freeDMA (tDMAMemory *mem);
This function deletes the tDMAMemory object created by allocDMA(…).
On most systems, freeDMA(…) will:
These are the iBus functions used by Chip Objects and the RLP examples. They are already defined and should not need to be modified to port iBus to a new OS. This section is only an overview—the functions are located in osiBus.h and osiBus.cpp.
u32 iBus::get(u32 attribute, u32 occurrence);
get(…) allows a program to get attributes of the PCI device. In the RLP examples, the only attribute needed is the physical addresses of the BARs, which is used for initializing the MITE on some devices.
tAddressSpace iBus::createAddressSpace(tBusWindowType windowType);
createAddressSpace(…) returns an address space which can read and write to the PCI device. createAddressSpace(…) can return an address space for any of the BARs which were initialized by acquireBoard(…).
void iBus::destroyAddressSpace(tAddressSpace &addressSpace);
destroyAddressSpace(…) releases the system resources retained by createAddressSpace(…), if any.
Use the tAddressSpace functions read8/16/32 and write8/16/32 to access PCI registers through an iBus.
write8( ), write16( ), write32( );
Write 8, 16, or 32 bits. This function is inlined and is usually compiled away to a pointer dereference.
read8( ), read16( ), read32( );
Read 8, 16, or 32 bits. This function is inlined and is usually compiled away to a pointer dereference.
This example is from the MITE initialization in the RLP examples:
iBus* bus = NULL;
tAddressSpace miteSpace;
u32 physicalBar1 = 0;
u32 address = 0xC0;
u32 value = 0;
bus = acquireBoard("PXI::4::2::INSTR");
miteSpace = bus->createAddressSpace(kPCI_BAR0);
physicalBar1 = bus->get(kBusAddressPhysical, kPCI_BAR1);
value = (physicalBar1 & 0xFFFFFF00L) | 0x80;
miteSpace.write32(address, value);
bus->destroyAddressSpace(miteSpace);
releaseBoard(bus);