DriverX Toolkit library for direct port I/O, interrupt, ISR, memory mapped I/O, programing direct io, direkter hardware zugriff I/O, interrupts.

DriverX 4
for Windows 95/98/ME and Windows NT/2000/XP

Version 4

Hardware Control for 32-bit Windows Applications

Need support for USB ? more info

DriverX DEMO and Trial

Using DriverX, Windows developers can quickly and easily write Windows applications to control a wide range of hardware devices. DriverX is currently being used in applications to control hardware ranging from parallel devices with custom protocols, to board level hardware such as digital I/O cards and servo-controllers.

DriverX, first shipped in 1994, is currently in use in thousands of applications worldwide ranging from motion controllers and A/D converters to custom parallel port devices and dongles.

The DriverX provides basic high-level routines for...

I/O port access

Physical memory mapping

Interrupt handlers

DriverX can be used with common development environments including Visual C++, Borland C++, Visual Basic and Delphi. Executables developed using DriverX can be run on both Windows NT and Windows 95 and can be redistributed royalty free. Since no kernel-mode or DDK development is required, DriverX is very easy to use.

Port Operation Queuing

DriverX provides great performance for many applications through the DriverX port operation queuing routines. Batches of port operations can be queued and passed to the DriverX kernel-mode device driver for execution. Data read and write loops can be executed entirely in kernel-mode using DriverX routines such as QueueLoopBack, QueueBufInp/Outp, and QueueWhileInpAnd.

 

What's Included?

DriverX includes the following:

Generic driver(s) - These kernel-mode Windows 95 and Windows NT drivers provide the basic system services required by the library to implement hardware operations. The library determines the Windows platform and loads the appropriate driver at runtime

Routines for port access, physical memory access, and interrupt service routines

Port I/O (including high-performance auto-increment and handshaking read/write support)

LPT Port I/O (including port locking)

Fast memory I/O

High Speed Interrupt handling (worst case interrupt latencies around 15 micro seconds using DriverX on 166Mhz Pentium, 64M RAM running Windows NT4 and Windows 98).

Routines for registry configuration of user devices and the DriverX device drivers

A utility application to aid the developer in creating registry device configurations

Full online and printed help

Examples illustrating every major product feature

Hardware Viewer utility application

C routines and C++ classes with source code

Static library builds

DLL builds and Visual Basic interface module

ActiveX(OLE Control) - This control will appear on the control container's toolbar as a hardware card icon. It can be dragged onto an application form and its methods can be used to control the target hardware.

PCI device support including busmaster DMA

Windows 95/98 Plug and Play support

Binary compatibility between Windows NT/2000/XP and Windows 95/98/ME

Supports Delphi, VB, Visual C++, Borland C++/C++ Builder, and other C/C++ Win32 compilers

Note that Visual Basic users can control port and physical memory ranges using either the C/C++ DLL libraries or the ActiveX (OLE Control). However, only the ActiveX control provides interrupt handling via the ActiveX event firing mechanism.


DriverX Advantages

Port-op queuing - Developers can easily incorporate queuing of port operations for higher throughput. No macro preprocessor is required to use this feature.

Hardware Viewer Utility - With the Hardware Viewer utility, developers can begin interracting with their hardware minutes after installation of the DriverX library package-and without writing a line of code.

C, C++, Delphi, and Visual Basic support in one package with similar APIs.

No undocumented calls. Unlike some other similar development tools and freeware tools on the market, DriverX does not use undocumented NT kernel calls. Using these tools could leave you with an application that won't run on future NT versions.


DriverX C Example

This example illustrates how a 16-bit application controlling an A/D converter card can be quickly and easily ported to 32-bit Windows using the DriverX C library.

 

Original 16-bit code



   ///////////////////////////////////////////////////////////////////////
   // ackdata.c
   //
   // Acquires A/D converter values for one roll scan.

   #include <stdio.h>
   #include <dos.h>
   #include <conio.h>

   unsigned short g_buffer[1024];
   int g_nCount=0;

   /////////////////// CardIsr()
   //
   // Interrupt service routine for RADEXM-20. Called when analog-to
   // digital conversion is complete. Stores value in global buffer.

   void CardIsr()
   {
       // Read data
       g_buffer[g_nCount++] =
          inp(CARD_BASE+DATA_REG)  + ((inp(CARD_BASE+DATA_REG+1))*256);

     // Acknowledge the interrupt with the card
       outp( CARD_BASE + STATUS_A, 0 );

       // Reset PIC
       outp(0xA0,0x20);
       outp(0x20,0x20);
   }

   int main()
   {
       void interrupt (*prevVect)(_CPPARGS);
       unsigned char ch;

       // Hook up interrupt
       prevVect = getvect( CARD_IRQ );
       setvect( CARD_IRQ, CardIsr );

       // Setup PIC
       ch = inp( 0xA1 );
       outp( 0xA1, ch&0xFA );

       // Setup RADEXM-20 for
       // interrupt on channel 0 acquisition
       outp( CARD_BASE + STATUS_A,0x84 );

       // Wait for acquisition done or ESC key...

32-bit code using DriverX library

Following is the previous 16-bit example ported to Windows NT and Windows 95 using the DriverX.


   ///////////////////////////////////////////////////////////////////////
   // ackdata.cpp
   //
   // Acquires A/D converter values for one roll scan.
   #include <stdio.h>
   #include <stdlib.h>
   #include <conio.h>
   #include <process.h>
   #include "whc.h"

   unsigned word g_buffer[1024];
   int g_nCount=0;

   // Define a couple macros mapping inp and outp to  DriverX calls
   HWPORT* g_pPort;
   #define inp(x) HwInp(g_pPort,(x)-CARD_BASE)
   #define outp(x,c) HwOutp(g_pPort,(x)-CARD_BASE,c)
   /////////////////// CardIsr()
   //
   // Interrupt service routine for RADEXM-20. Called when analog-to-
   // digital conversion is complete. Stores value in global buffer.

   void CardIsr()
   {
       // Read data
       g_buffer[g_nCount++] = inp(CARD_BASE+DATA_REG)+ ((inp(CARD_BASE+DATA_REG+1))*256);

       // Acknowledge the interrupt with the card
       outp( CARD_BASE + STATUS_A, 0 );

       // No need to reset PIC  (DriverX drivers manage this)
   }

   int main()
   {
       // Setup device context
       HWDEVICE* pDevice =   HwNewDevice( CardIsr );
       if (!HwConnectDevice(pDevice,"Card0")) return 1;

       // Store port context info for  port I/O calls
       g_pPort = HwDevicePorts(pDevice);

       // Create thread to run ISR in the background
       DWORD nThreadId;

       HANDLE hThread = (HANDLE)_beginthreadex (NULL, 0, HwIsrThreadProc, pDevice, CREATE_SUSPENDED, &nThreadId);

       // Enable the ISR
       HwEnableIsr(pDevice, hThread, nThreadId);

       // Setup RADEXM-20 for
       // interrupt on channel 0 acquisition
       outp( CARD_BASE + STATUS_A, 0x84 );

       // Wait for acquisition done or ESC key...

Memory Mapping

Device DPRAM ranges can be easily accessed using the DriverX MapDeviceMemory routine. This routine sets up an alias virtual address range corresponding to the physical memory range for a hardware device. The device can then be accessed using normal pointer mechanisms.

Performance is very good since the memory is accessed directly without going through the DriverX driver.

Note that on NT, the maximum amount of device memory that can be mapped is 192MB. This is a limitation of the NT operating system, not DriverX. This 192MB can be further reduced by other drivers that may also be mapping hardware memory.

PCI Support

DriverX dramatically simplifies PCI device control. On NT, a PCI device can be configured in one easy step using the DriverX Device Configuration Utility or the DriverX ConfigureDevice API routine. For Windows 95, DriverX includes a standard INF file for configuring PCI devices through the Windows 95 Add New Hardware Wizard.

Using DriverX, developers can quickly begin work on controlling a PCI device without getting bogged down in the coding of complex PCI device initialization and Plug & Play event handling routines.

DriverX supports devices with up to 16 I/O regions and up to 16 memory mapped regions. Developers using DriverX can open a handle to a PCI device using the DriverX ConnectDevice routine and can then access any I/O or memory mapped region with no other configuration or resource assignment work required.

DriverX also supports multiple PCI devices of the same type and provides routines for writing and reading to/from the PCI configuration space of a device.

A DriverX PCI device configuration can request a contiguous buffer for PCI devices that support busmaster DMA. An application can program a device for a DMA transfer using a DMA buffer physical address returned from the DriverX GetPhysicalAddress routine. The DriverX MapDmapBuffer routine can be used to access a DMA buffer from an application using normal pointer mechanisms.


DriverX - ActiveX Usage

To use a Hardware ActiveX control, the developer simply drags an ActiveX control from the container's toolbar and drops it onto his or her main application form. During initialization, the control is initialized and associated with a registry device configuration-previously entered either by the application's setup program or through methods provided by the control. 

   Private Sub Form_Load()
     ' Initialize control
       MyControl.Connect "MyConfiguration"

     ' Enable firing of interrupt events
       MyControl.EnableInterrupt
   End Sub

After initialization, the control can then be used to access the hardware device. For instance, in the following interrupt event handler for an A/D converter, the converted digital value is read and the interrupt is acknowledged.

    Private Sub MyControl_Interrupt()
     ' Store converted value into global data array

       Data(DataCount) = MyControl.inp(0)
       DataCount = DataCount+1

     ' Acknowledge the interrupt by writing to
   status register
       MyControl.outp 0, &HFF
   End Sub

 

DriverX Routines

The following routines are provided by the DriverX C library, C++ classes, Delphi unit, and ActiveX (OCX) control:

 

Port I/O Routines
Note: All port routines have byte, word, and DWORD variations.

AllocateOpQueue

Allocate an operation queue.

AllocateOpQueue

Allocate an operation queue.

AutoIncReadPort

Do a repeated read from a port into a buffer.

AutoIncWritePort

Do a repeated write from a buffer to a port.

DeleteOpQueue

Free an operation queue.

Execute

Execute an operation queue.

GetQueueBuffer

Retrieve data read from queue execution.

GetQueueResults

Get the results from a queue execution.

Inp

Do a byte, word, or DWORD port read.

MapPorts

Set up a port range on the fly.

Outp

Do a byte, word, or DWORD port write.

QueueAndTemp

Modify a queue temporary variable.

QueueBreakIfAnd

Queue command to break on a status bit.

QueueBufInp

Queue a port read into a queue buffer.

QueueBufOutp

Queue a port write from a queue buffer.

QueueDelay

Queue a command to wait x microseconds.

QueueInp

Queue a byte, word, or DWORD port read.

QueueLoopback

Set up a loop within an operation queue.

QueueOrTemp

Modify a queue temporary variable.

QueueOutp

Queue a byte, word, or DWORD port write.

QueueTempOutp

Queue command to write queue temp variable.

QueueWhileInpAnd

Queue command to loop on a status bit.

QueueWhileInpEqual

Queue command to loop on a status bit.

UnmapPorts

Clean up a mapped port range.

Memory Mapping Routines

GetMemoryPointer

Returns a virtual address for a memory range.

GetPhysicalAddress

Returns the physical address of a memory range.

MapDeviceMemory

Map a configured memory range for a device.

MapDmaBuffer

Map the DMA buffer for a device.

MapMemory

Map a specified physical memory range.

Interrupt Handling Routines

BeginIsrSynch

Synchronize with an ISR thread.

ConnectInterrupt

Hook a specified interrupt.

DisableIsr

Disable interrupt handling from a device.

DisconnectInterrupt

Unhook an interrupt.

EnableIsr

Enable interrupt handling from a device.

EndIsrSynch

End synchronization with an ISR thread.

GetIsrData

Return register value for last ring-0 ISR operation.

GetIsrIdData

Return register value for last ring-0 ISR ID operation.

Configuration Routines

ConfigureDevice

Create a device configuration.

ConfigureDriver

Configure the DriverX kernel-mode driver.

DeleteDeviceConfig

Delete a device configuration.

EnumerateDevices

Enumerate through all device configurations.

GetDeviceConfig

Retrieve a device configuration.

IsDeviceRunning

See if a device has been started.

IsDriverConfigured

See if the DriverX driver is configured.

StartDevice

Starts a device and allocates resources.

StopDevice

Stops a device and frees resources.

Miscellaneous

ConnectDevice

Open a handle to a device.

DisconnectDevice

Close a handle to a device.

GetBusDataByOffset

Read from PCI configuration space.

IsOn95

See if app is running on Windows 95/98.

IsOnNT

See if app is running on Windows NT.

SetBusDataByOffset

Write to PCI configuration space.

SetErrorHandler

Set the error handler for critical DriverX errors.

 

DriverX Technical Information

Interrupt handlers
Using DriverX, a developer can create an interrupt handler in his/her application. The DriverX library manages an independent Win32 thread which calls the developer's ISR in response to hardware interrupt events. There are no restrictions on what can be called from the ISR. The DriverX library provides a simple mechanism for avoiding concurrency problems with data shared between the ISR and other application code. DriverX is also designed to avoid any situations where the main thread could be manipulating the device while the ISR thread is handling an interrupt.

Driver-side repetitive operations
DriverX includes fast routines implemented completely on the driver side to read and write buffers with common autoincrementing or handshaking hardware.

Registry Support
DriverX provides support for registry storage of device configurations-- including port base and count and interrupt level. By using this option, the developer can take advantage of Windows resource conflict detection and standardized configuration features.

Performance Optimizations
DriverX provides a number of features to enhance data throughput to and from hardware devices. These features include fast auto-increment read/write routines and port operation queuing routines.

  // Define the acquisition loop
     HwQueueWhileInpAnd(q,
                        STATUS_REG_OFFSET,
                        1,
                        STATUS_BIT,
                        FALSE,
                        STATUS_TIMEOUT);
     HwQueueBufInp(q, DATA_REG_OFFSET);
     HwQueueLoopback(q);

  // Execute the queued instructions with one call to driver
     HwExecute(device,q);

The DriverX BreakIfAnd routine can also be used to break out of an acquisition loop on a particular register value.

The DriverX GetQueueResults routine can be used to determine how many bytes of data were transferred before a timeout or a break.


Licensing
DriverX includes a single-seat developer license. It also includes a license for unlimited redistribution of the DriverX kernel-mode drivers and libraries with applications. Redistribution is also permitted with custom controls and DLLs provided that the custom control or DLL is for a specific device and does not export the general purpose hardware control routines provided by DriverX.


Home    Back
Modified at:

ADONTEC