Measurement Hardware Driver Development Kit (MHDDK) Architecture


This document outlines the register level programming (RLP) architecture and tools which are part of the National Instruments Measurement Hardware Driver Development Kit (MHDDK). This information is subject to change, revision, and clarification.


NI-DAQmx or Register Level Programming (RLP)

If at all possible, it is advisable to use the NI-released driver with your NI hardware (e.g. NI-DAQmx). Rather than developing your own driver from scratch, using the existing drivers will provide you the most benefit from your hardware, including continued forward compatibility with new operating systems, re-use of existing code with new and improved hardware and award-winning technical support. NI spends many man-years of development time on these drivers so that you don’t have to.

In situations where you cannot use the existing drivers, NI does provide information and assistance for developing applications and drivers using register level programming (RLP). RLP consists of programming the hardware directly by writing to and reading from the registers on the hardware rather than calling functions in the driver. To be able to use RLP with a particular device, you must be familiar with the registers and their functionality on the device, as well as programming using direct register accesses and other associated programming techniques (memory management, memory mapping, windowed register access, interrupts, DMA, etc.) on your hardware platform and operating system.


RLP Architecture Overview

NI’s RLP software examples and documentation are developed around an RLP architecture used for a variety of NI hardware products. The RLP architecture is a modular, reusable architecture designed to maximize reuse of code components across different hardware products and across different platforms and operating systems.

The RLP architecture consists of three main layers: the RLP examples, the Chip Objects and the osiBus. Using these three layers, NI provides a consistent set of RLP examples that can be applied to a wide range of different hardware products and that can be quickly adapted to additional operating systems and hardware platforms. The RLP examples and underlying architecture are used by developers to implement their own RLP-based applications and drivers. Using the provided examples, developers can quickly adapt the examples to their application or create new applications and drivers based on the Chip Object and osiBus architecture.



RLP Examples

The RLP examples implement application-specific operations on a specific device or device family. Each example illustrates how to program a specific operation using the general functionality provided by the Chip Objects. These examples can be easily adapted for other operations, and illustrate the general use of the Chip Objects.


Chip Objects

A Chip Object provides an abstraction layer of the particular hardware supported by the Chip Object. The abstraction consists of encapsulating the multitude of registers and bitfields on a particular device in logical objects and methods in C++ classes. In some cases, there may be more than one Chip Object for one device, with each Chip Object addressing a different subsystem on the device. Using the Chip Objects, you can configure and program the device by invoking logical methods to set, unset, and configure specific attributes of the device. The RLP examples illustrate this process for different operations. The RLP examples and Chip Objects are both platform and OS independent, and can thus be used on a wide range of OSes and platforms. The Chip Objects interface to the hardware on a specific OS and platform using the osiBus layer, which is implemented for each specific OS/platform combination. For more information about using Chip Objects, refer to How to Use a Chip Object.

If available for your hardware, Chip Objects are the simplest and easiest method to access your hardware through RLP. The Chip Objects provide objects and methods using logical names for the registers and bit fields on the hardware. While not as simple to use as the NI-DAQmx driver, this greatly simplifies RLP and eliminates many common errors. In addition, the Chip Objects eliminate some additional difficulties such as windowed register access. Since the Chip Objects are based on the osiBus layer, they also eliminate the need for memory mapping. In cases where your platform OS is not supported by the current osiBus implementations, you will need to port osiBus to the new platform.



The operating system interface bus (osiBus) layer is a generic register I/O interface used by the Chip Objects to interface to the hardware. In code, the osiBus is implemented as a C++ class called iBus. The interface provided by iBus to the Chip Objects is consistent for all OSes and platforms. Internal to the iBus, there are OS- and platform-specific implementations that enable the iBus to interface to the hardware on the chosen platform. The MHDKK supports several operating systems, including Windows and Linux. For more information about the available iBus implementations, refer to “What operating systems are supported?” in  Measurement Hardware Driver Development Kit (MHDDK) Frequently Asked Questions.



The shipping RLP examples include an iBus implementation based on NI-VISA to access PCI/PXI and PCIe/PXIe hardware on Windows platforms. The same implementation will also work on other platforms which NI-VISA supports. This implementation does not work for PCMCIA/PCCard on Windows.

NI-VISA provides a set of easy-to-use register I/O functions. On Windows platforms, register I/O can be very difficult since it requires kernel mode access. By using the VISA driver, the same operations can be done from user mode. You can use the VISA driver to perform any kind of register I/O on the supported platforms, including writing drivers for third party hardware or accessing NI hardware without using the Chip Objects. For more information, refer to the following Tutorial: Using the NI-VISA Driver Wizard and NI-VISA to Develop a PXI(e)/PCI(e) Driver in Windows.



In addition to the NI-VISA-based implementation, the RLP examples also include two Linux implementations of iBus. Both implementations are based directly on Linux provided APIs, and enable the RLP examples to be run under Linux. The first uses /dev/mem and provides support for Linux 2.4 kernels but does not provide DMA support. The second uses a native kernel module for Linux 2.6 kernels and provides DMA support.


Other Implementations

To port the RLP examples to other platforms, portions of the iBus implementation in osiUserCode.cpp must be written for your specific platform. For basic register I/O, only two functions need to be updated: acquireBoard(…) and releaseBoard(…). In the case of DMA operations, an additional two functions need changes: iBus::allocDMA(…) and iBus::freeDMA(…). Updating these functions will require familiarity with register I/O and memory management on your specific platform. This process is described in more detail in How to Make an iBus.



Most devices support some form or interrupt generation to signal specific events such as data being acquired to a FIFO buffer, the digital lines matching a predefined state, etc. The devices are configured to generate these interrupts as part of the general programming and configuration for a particular operation. Once the device starts to generate interrupts, an interrupt handler, also called interrupt service routine (ISR), installed with the operating system must receive and process these interrupts. While the RLP examples and documentation describe how to configure the hardware to generate interrupts, they do not illustrate how to register interrupt service routines with particular operating systems. The example may illustrate the code that would be called inside of an ISR, but the actual development and registration of the ISR is left to the developer on each particular operating system. You should be familiar with this type of programming if you need to use interrupts in your application or driver. Information about handling interrupts in NI-VISA can be found in the following Tutorial: Using the NI-VISA Driver Wizard and NI-VISA to Develop a PXI(e)/PCI(e) Driver in Windows.



While DMA has not been integrated into all RLP examples, there are some specific examples with DMA operations available. These DMA examples combined with the general RLP examples for a particular device should be sufficient to add DMA functionality for those devices. Additional information is available in the RLP documentation for the hardware. One component of the iBus is used only for DMA operations. If you do not use DMA, this portion of iBus is not required. In turn, if you do use DMA, this portion of iBus must be ported to your platform and operating system in addition to the main portion of iBus. Check the osiUserCode.cpp file for this code.


RLP Options

If possible, it is advisable to use the NI-DAQmx driver to program supported NI hardware. NI-DAQmx provides the most flexible, reliable, and easy-to-use interface for programming DAQ hardware. It also includes extensive documentation and examples for a wide range of applications. In cases where it is not possible to use NI-DAQmx, there are a number of different options to program the hardware using register level programming (RLP). Situations that might warrant RLP of DAQ hardware include:

  • NI-DAQmx is not supported on the required platform and operating system.
  • Specific DAQ hardware is not supported in NI-DAQmx on a given platform and operating system.
  • NI-DAQmx does not support a specific operation on a device that the hardware does support.
  • The performance of NI-DAQmx for a specific operation on a device is not adequate for a particular application and there is information that the device may be able to meet the performance requirement if programmed through RLP.


Low Level Register I/O

At the lowest level, all devices are programmed by setting the proper registers (containing individual bit fields) with the proper values. The registers and bit fields are documented in the appropriate RLP documentation. If you are familiar with register I/O programming on your platform and OS, you may choose to access the device registers directly. You will need to include operations such as memory mapping and windowed register accesses.


NI-VISA Register I/O

If NI-VISA supports register I/O for your platform and your OS, you may choose to use NI-VISA to perform your register level programming. You will still need to be familiar with the registers and bit fields on the hardware you are programming, but some operations like memory mapping will be handled by the VISA driver.


Hardware Support

RLP examples and documentation are available for most NI DAQ device families. For more details, refer to “What NI Hardware is supported?” in Measurement Hardware Driver Development Kit (MHDDK) Frequently Asked Questions.



NI has register level programming documentation available for a variety of NI DAQ device families. For more details, see “Where can I find more documentation about RLP with the MHDDK?” in Measurement Hardware Driver Development Kit (MHDDK) Frequently Asked Questions.


Maintenance and Support

RLP is not supported through the standard Applications Engineering support channel. For information about the support policy for MHDDK refer to Measurement Hardware Driver Development Kit (MHDDK) Technical Support.