CVMEInterface

Name

CVMEInterface -- Interface independent access to the VME bus for C++

Synopsis


#include <config.h>
#include <CVMEInterface.h>
#include <string>
            

static void Open(CVMEInterface::AddressMode mode, unsigned short crate=0);

static void Close(void* pCrateHandle);

static void* Map(void* pCrateHandle, unsigned long nBase, unsigned long nBytes);

static void Unmap(void* pCrateHandle, void* pBase, unsigned long nBytes);

static int Read(void* pCrateHandle, unsigned long offset, void* pBuffer, unsigned long nBytes);

static int Write(void* pCrateHandle, unsigned long nOffset, void* pBuffer, unsigned long nBytes);

static void Lock();

static void Unlock();

Description

CVMEInterface provides generic low level access to VME busses. Programming against either CVMEinterface or CVMEModule (see the reference pages for the device supprot software), ensures that your code is portable across all VME interfaces supported by the NSCL DAQ system. This portability comes at the potential price of performance.

This reference section also describes classes for each supported VME interface. If you require access to some special features of an interface, you can sacrifice portability by programming against them as well.

To compile software that uses this class you will need to ensure that the compiler can locate the CVMEInterface.h header as follows:


-I$DAQROOT/include
                

To link software that uses this class you will need to link in both the VmeAPI library and the Exception library, as well as potentially other device support libraries that depend on your interface. For the SBS PCI/VME interface board, the addtional information required on the link line is shown below:


-L$DAQROOT/lib -lVmeApi -lException -lbtp -lpthread
                

Public member functions

static void Open(CVMEInterface::AddressMode mode, unsigned short crate=0);

Opens a handle to access a VME crate. This handle should be used as the pCrateHandle in other functions in this class. mode represents the address modifier to be used by default when accessing the crate through this handle. See "Types and Public Data" below for more information about the address modifier. crate is the number of the VME crate to be opened. if omitted, the crate parameter defaults to 0 which is suitable for software running in single crate systems. If, however you are producing software that is supposed to provide general support for a device, you should not default this parameter.

The handle is returned to the caller as an opaque pointer (void*). If the open is unsuccessful, the function throws a string exception with a value that reports why the open failed.

static void Close(void* pCrateHandle);

Closes a handle that was previously opened via CVMEInterface::Open. pCrateHandle is the opaque handle to the crate returned by the CVMEInterface::Open call.

Note that it is possible, but not gauranteed that a call to Close will not unmap any address space mappings. Therefore, to be totally portable, you should Unmap all address blocks created on this crate first, and only then Close the crate,

Failure is reported by throwing a string exception that describes

static void* Map(void* pCrateHandle, unsigned long nBase, unsigned long nBytes);

Creates a mapped segment into the VME address space. A mapped segment may not be supported by all vme interface boards. If the vme interface you are using supports VME mapping, the header <config.h will define HAVE_VME_MAPPING. A mapped segment uses the mmap(2) system call to map a chunk of VME address space into your process virtual address space.

As usual pCrateHandle is the handle gotten from the CVMEInterface::Open call. The VME address space in the map is specified by nBase the starting VME addresss of the map and nBytes the size of the address block in bytes. On success, a pointer to the process virtual address space corresponding to that block of VME space is returned. On failure, a string exception is thrown.

static void Unmap(void* pCrateHandle, void* pBase, unsigned long nBytes);

Destroys a mapping created by CVMEInterface::Map. Once this is called, dereferencing the block of address pointed to by the pointer returned from CVMEInterface::Map will almost certainly result in a segmentation fault.

pCrateHandle is the handle to the VME crate from CVMEInterface::Open. pBase is the pointer gotten back from CVMEInterface::Map. Finally, nBytes is the size of the address block requested in the original call to CVMEInterface::Map.

static int Read(void* pCrateHandle, unsigned long offset, void* pBuffer, unsigned long nBytes);

Peforms a read from from the VME crate. The size of the transfer depends on the byte count nBytes. A value of 1 or 2 transfers a single byte or short. 3 will transfer a short and a byte but with an undefined order and therefore should be avoided. Values that are multiples of 4 will transfer longwords.

The base address of the transfer is given by offset, and data are transferred to the memory pointed to by pBuffer. pCrateHandle as usual is the handle to the crate gotten from the CVMEInterface::Open call.

The function resturns the number of bytes actually transferred. Note that the SBS DMA engine has sufficient pipelining that it will overestimate the number of bytes transferred if the transfer is interrupted by a bus error. The function signals errors by throwing a string exception.

static int Write(void* pCrateHandle, unsigned long nOffset, void* pBuffer, unsigned long nBytes);

Same as CVMEInterface::Read however data are transferred from the pBuffer to the VME bus.

static void Lock();

static void Unlock();

These function manage access to the VME crate. Calling Lock should be called prior to accessing the VME crate and Unlock when done for a while. The behavior of these functions ensures that only one process in a computer system can have a successful Lock. Subsequent attempts to Lock the bus will cause the caller to block until the owner calls Unlock.

Note that at least one interface (VM-USB) opens and closes the device during Lock/Unlock calls. This means that portable programming requires that you hold the lock for the VME bus prior to performaing any operations on it.

Types and Public data

The address modifier is used by the VME bus to qualify addresses presented to it into address spaces. The VME bus supports several, potentially distinct, address spaces (distinct means that address x in one address space may not reference the same thing as address x in another address space). The following is the supported part of the definition of CVMEInterface::AddressMode, which is used to specify address modifiers.


  typedef enum {                        // Addressing modes:
    A16,
    A24,
    A32,
    GEO,
    MCST,
    CBLT
  } AddressMode;

                

For various An address modifiers, n refers to the number of significant address bits for each space. GEO is the address modifier used by e.g. the CAEN V785 and compatible modules to specify geographical addressing. MCST multicast addressing and CBLT chained block transfer.

It is up to the implementation of the class to ensure that where appropriate, block (MBLT) transfesr are performed.

The public member data const char* m_szDriverName is a null terminated array of characters that gives the name of the device.

Exceptions

All these member functions throw exceptions of type std::string. The contents of the string thrown are a descriptive error message.

Examples

The example below opens the A32 address space in vme crate 0. Creates a memory map of longwords starting at location 0x100000 extending for 0x100 bytes does some stuff and then undoes all that.


...
try {
    void  *pCrate = CVMEInterface::Open(CVMEInterface::A32, 0);
    void* *Vme    = CVMEInterface::Map(pCrate, 0x100000, 0x100);
    uint32_t* pModule = static_cast<uint32_t>(Vme);
   
    // Do stuff dereferencing pModule.
    CVMEInterface::Lock();    //Surround each burst of VME activity
    ...
    CVMEInterface::Unlock();  // with Lock/Unlock calls.
    ...
    // Clean up our mess.
    
    CVMEInterface::Unmap(pCrate, Vme, 0x100);
    CVMEInterface::Close(pCrate);
}
catch (std::string errorMessage) {
    std::cerr << " Caught a string exception: "
              << errorMessage << std::endl;
}
   
...