Using Low-Level Memory Functions with PXI

This section contains information specific to the Windows product.

Low-level memory functions allow direct access to memory, as do high-level memory functions. However, with low-level memory function calls, you must map a range of addresses and directly access the registers with low-level memory functions, such as viPeek32 and viPoke32.

There is more programming effort required when using low-level memory functions. However, the program execution speed can improve. To increase program execution speed, the low-level memory functions do not return error codes.

Programming the Registers

When using the low-level memory functions for direct register access, you must first map a range of addresses using the viMapAddress function. Next, you can send a series of peeks and pokes using the viPeek and viPoke low-level memory functions. Then, you must free the address window using the viUnmapAddress function.

Low-Level Memory Functions

You can program the registers using low-level functions for 8-, 16-, 32-, or 64-bit transfers. The table below summarizes the low-level memory functions.

Function

Description

viMapAddress(vi, mapSpace, mapBase, mapSize, access, suggested, address);

Maps the specified memory space.

viPeek8(vi, addr, val8);

Reads 8 bits of data from address specified.

viPeek16(vi, addr, val16);

Reads 16 bits of data from address specified.

viPeek32(vi, addr, val32);

Reads 32 bits of data from address specified.

viPeek64(vi, addr, val64);

Reads 64 bits of data from address specified.

viPoke8(vi, addr, val8);

Writes 8 bits of data to address specified.

viPoke16(vi, addr, val16);

Writes 16 bits of data to address specified.

viPoke32(vi, addr, val32);

Writes 32 bits of data to address specified.

viPoke64(vi, addr, val64);

Writes 64 bits of data to address specified.

viUnmapAddress(vi);

Unmaps memory space previously mapped.

Mapping Memory Space

When using VISA to access the device's registers, you must map memory space into your process space. For a given session, you can have only one map at a time. To map space into your process, use the VISA viMapAddress function:

viMapAddress(vi, mapSpace, mapBase, mapSize, access, suggested, address);

This function maps space for the device specified by the vi session. mapBase, mapSize, and suggested are used to indicate the offset of the memory to be mapped, amount of memory to map, and a suggested starting location, respectively. mapSpace specifies the memory location to map; the following are valid mapSpace choices:

VI_PXI_CFG_SPACE   -  Address the PCI configuration space.

VI_PXI_BAR0_SPACE - VI_PXI_BAR5_SPACE    -  Address the specified Base Address Register PCI memory or I/O space.

VI_PXI_ALLOC_SPACE   -  Access physical locally allocated memory.

A pointer to the address space where the memory was mapped is returned in the address parameter. If the device specified does not have memory in the specified address space, an error is returned. A sample viMapAddress function call follows.

/* Maps to VI_PXI_BAR0_SPACE address space */
viMapAddress(vi, VI_PXI_BAR0_SPACE 0x000, 0x100, VI_FALSE, VI_NULL,&address);

  • When calling the viMapAddress function on a PXI session, the maximum value for the mapSize parameter is limited to the actual size of the resource addressed by the mapSpace parameter (VI_PXI_BAR0_SPACE – VI_PXI_BAR5_SPACE).
  • Determining Window Mapping

    The VI_ATTR_WIN_ACCESS read-only attribute specifies how a window can be accessed. You can access a mapped window with the VISA low-level memory functions, or with a pointer if the address is dereferenced. To determine how to access the window, read the VI_ATTR_WIN_ACCESS attribute.

    VI_ATTR_WIN_ACCESS Settings

    The VI_ATTR_WIN_ACCESS read-only attribute can be set to one of the following:

    Setting

    Value

    Description

    VI_NMAPPED

    1

    Specifies that the window is not mapped.

    VI_USE_OPERS

    2

    Specifies that the window is mapped and you can only use the low-level memory functions to access the data.

    VI_DEREF_ADDR

    3

    Specifies that the window is mapped and has a de-referenced address. In this case you can use the low-level memory functions to access the data, or you can use a C pointer. Using a de-referenced C pointer will allow faster access to data.

    Reading and Writing to Device Registers

    When you have mapped the memory space, use the VISA low-level memory functions to access the device's registers. First, determine which device register you need to access. Then, you need to know the register's offset. See the instrument’s user manual for a description of the registers and register locations. You can then use this information and the VISA low-level functions to access the device registers.

    Low-Level Memory Access Example

    The VisaLowLevelMemoryAccess function in the PXIVisaSample program shows some direct memory dereferencing examples, and some viPeek examples.

    Unmapping Memory Space

    Make sure you use the viUnmapAddress function to unmap the memory space when it is no longer needed. Unmapping memory space makes the window available for the system to reallocate.