Academic Company Events NI Developer Zone Support Solutions Products & Services Contact NI MyNI

Document Type: Tutorial
NI Supported: Yes
Publish Date: Sep 6, 2006


Feedback


Yes No

Related Categories

Related Links - Developer Zone

Related Links - Products and Services

Configuring and Using Shared Memory from a National Instruments VXI//VME Bus Controller

6 ratings | 4.50 out of 5
Print

Overview

This application note discusses configuring and using shared memory in your VXI or VME instrumentation systems. It includes code examples and troubleshooting tips.

Shared, or dual-ported memory, physically resides on the host VXI/VME controller, but can be accessed by different bus masters on the VXI or VME bus. By using shared memory located on your National Instruments VXI/VME controller, you can avoid purchasing expensive dedicated instrument memory modules to store data generated during acquisition, analysis, or waveform generation.

There are two options for sharing memory from the National Instruments series of VXI/VME controllers:

1. Installing dedicated SIMMs

2. Sharing host memory

Both of these will be discussed in separate sections of this application note.

Installing Dedicated SIMMs


Using this option, you install SIMMs onto a VXI/VME controller and transparently use this memory as if it resided on a VXI/VME device. Once you have configured the controller, the VXI resource manager automatically allocates this memory onto the VXI/VME backplane so that the other VXI/VME instruments in the system can access it. This option is available on the PCI-MXI-2, VXI-MXI-2, VME-MXI-2, VXI-1394 and VXI-1394/G. Note that this option is not available on any embedded VXI/VME controller -- the Sharing Host Memory section discusses configuring shared memory on an embedded controller.

Installing SIMMs onto your VXI/VME controller may require that you modify some jumper/DIP switch settings. For more information consult the documentation supplied with your controller. To use shared memory once you have installed the SIMMs, you must configure NI-VXI/NI-VISA, the driver level software supplied with all National Instruments VXI/VME controllers.

NI Measurement & Automation Explorer (MAX) is used to configure the PCI-MXI-2, VXI-MXI-2, VME-MXI-2, VXI-1394 and VXI-1394/G interfaces on Win 32 platforms (Windows 2000/NT/XP/Me/9x). VXIedit or VXItedit is used on other platforms and for other controllers. Several parameters must be set in order to use the SIMMs as shared memory. First, set the Address Space parameter to specify the address space and allocate the memory in A24 or A32. Up to 16 MB of memory can be addressed in A24 space, whereas up to 4 GB can be addressed in A32 space. Note that you can dual port only up to 8 MB in A24 space and up 2 GB in A32 space. Next, you must specify the amount of memory that is to be shared. Normally this would the same as the amount of RAM installed in the form of SIMMs. Figure 1 shows a PCI-MXI-2 configured to share 8 MB of memory.

Figure 1. 8 MB SIMM Configured in PCI-MXI-2

The VXI resource manager will allocate 8 MB of memory for the PCI-MXI-2 board in the A32 address space in the example shown. This memory will be allocated into two different half windows. You can select the byte order and mapping scheme for each of the half windows independently by setting the advanced options as shown in Figure 2 below. To use the SIMMs, you must set either or both half windows to Onboard memory. You typically select the same Memory Select option for both half windows.

Figure 2. Configuring the Shared Memory Windows

Note: Avoid writing to the first 4 KB of memory allocated by the resource manager because it stores EEPROM configuration settings for the MITE chip. This region is used by all MITE-based VXI/VME controllers.

Advanced Configuration Options
You can bypass this 4 KB limitation if you configure the shared RAM size to be twice the amount of memory you actually installed. Consider a VME-MXI-2 with two 32 MB SIMMs installed, for a total of 64 MB, allocated in the A32 address space starting at offset 0x24000000. Normally, the first 4 KB is reserved for the MITE chip and should be avoided. By setting the shared RAM size to 128 MB (twice the amount installed), you bypass this limitation by accessing the RAM at address = Requested Memory Size/2 + offset. As shown in Figure 3, the RAM is mapped to the VXI/VME address space at two different locations. All accesses that start at the address 0x24000000 are automatically mapped one-for-one to the installed SIMM while the lower half of the window still has the lower 4 KB reserved for the EEPROM. With this configuration, merely access the RAM at the address = Requested Mem Size/2 + offset.

[+] Enlarge Image
Figure 3. Onboard RAM on the VXI/VME-MXI-2 Mapped to the VXI/VME Bus

Sharing Host Memory


Another option for setting up shared memory is to dual port RAM installed on the host so that it is mapped onto the VXI/VME bus. With this option, you map up to 4 GB of memory (the maximum that can be addressed by a 32 bit address space) onto the VXI/VME bus. You can use this option by itself, or in conjunction with the option of installing dedicated SIMMs on controllers that offer both options.

Sharing host memory involves using memory normally used for the operating system and for running applications and allocating this memory onto the VXI/VME bus. As such, configuring the host memory so that it can be accessed by VXI/VME bus master involves two steps.

1. Configuring the VXI driver to reserve a block of memory from the operating system.

2. Programming the operating system to allocate the local buffer.

Configuring the VXI Driver to Reserve a Block of Memory from the Operating System

Measurement & Automation Explorer (MAX) is used to configure PCI-MXI-2 or embedded controller platforms on Win 32 platforms (Windows 2000/NT/XP/Me/9x). VXIedit or VXItedit is used on other operating systems (sharing host memory is not an option for NI-VXI on HP-UX systems). Several parameters must be set to dual port the system memory. First, the Address Space parameter needs to be set to specify the address space to allocate the memory in A24 or A32. Next, you must specify the Shared RAM size (also referred to as VXI Shared RAM size), which is the amount of memory dual ported onto the VXI/VME bus. Note that only some of this memory is protected from the operating system. It is possible for a VXI/VME bus master device to overwrite the contents of system memory if you are not careful to avoid regions outside those allocated in your applications.

The Reserve Physical Memory parameter, also referred to as Shared RAM Pool Size, indicates the size of physically contiguous memory that is allocated on system startup. This memory is protected from the operating system and cannot be used by any applications. The amount of memory you reserve sets an upper limit to the amount of memory that can safely be allocated on the VXI/VME bus. This is discussed in the Allocating Shared Memory section of this application note.

Figure 4 shows a PCI-MXI-2 configured to dual port 8 MB of memory. One megabyte (1 MB) which is reserved from the OS at startup, is the maximum amount of memory that can safely be allocated by your program.

Figure 4. PCI-MXI-2 Configured to Dual Port up to 8 MB of System Memory

Finally, it is important to discuss the settings found in the Advanced section. For best results, leave the configuration settings at their default values as shown in Figure 5. In particular, the Memory Select option should be set to System Memory.

Figure 5. Configuring Advanced Options for Sharing Host RAM

Allocating Shared Memory
Both the NI-VXI and NI-VISA driver-level software includes functions to allocate/deallocate the shared memory, and to fill and extract data from the shared memory. You can use these function calls in the same manner on all platforms. Because of the uniformity in use, all operating system and hardware-level details are completely transparent. Your application programs are also completely portable between the platforms and controllers, provided they have the ability to dual port, or share host memory. The maximum amount of memory that can be allocated by the functions is equal to the 1 KB less than the amount of memory reserved from the operating system. refer to the Note below. In the example shown in Figures 4 through 6, almost 1 MB is allocated.

This application note includes examples that use the NI-VXI and NI-VISA shared-memory functions. These examples are shipped with the driver-level software. It is not the intention of this application note to discuss the use of the memory allocation functions in detail since this is covered in the documentation supplied with NI-VXI and NI-VISA. Before examining the examples, let us consider an application where we are using the PCI-MXI-2 board shown in Figures 4 and 5. Eight megabytes (8 MB) of the operating system memory is dual ported onto the VXI/VME bus as shown in Figure 6. This memory is allocated from the physical memory actually installed on the host (64 MB in Figure 6). Only 1 MB of this memory is reserved from the operating system and so this is the maximum amount of memory that we can safely allocate in our application (refer to the note below). You also must ensure that you avoid writing to VXI/VME addresses higher than 0x100FFFFF in this example because these addresses are mapped to regions of system memory that may be in use by other applications and/or the operating system running on the host system. Accessing these VXI/VME addresses could lead to a system corruption.

Note: A small amount of overhead is associated with the process of allocating memory, and you must reserve at least 1 KB more than the amount of memory you wish to allocate. Thus, to allocate 1 KB of memory, specify at least 2 KB in the Reserve Physical Memory parameter. This is also referred to as Shared RAM Pool Size on some platforms. Also, the Shared RAM size parameter is typically set to All of System RAM.

[+] Enlarge Image
Figure 6. Mapping System Host Memory on the VXI/VME Bus

The upper limit for the VXI address shown in Figure 6 is a specific example and will vary depending on your system configuration settings.

Accessing Shared Memory



This section of the application note contains sample LabVIEW and C code for accessing and using shared memory. The first example illustrates how to access memory on a SIMM chip. The second set of examples illustrates how to allocate and access shared host memory.

Accessing Memory on Dedicated SIMM Chips
As discussed in the Installing Dedicated SIMMs section of this application note, many National Instruments controllers provide you with the option of installing SIMMs that are automatically mapped onto the VXI/VME backplane by the VXI resource manager. No special memory allocation functions need to be called once the system has been configured correctly. The only programming consideration is that you should avoid accessing the first 4 KB of memory because this is used to store EEPROM configuration settings. As noted earlier, you can get around the 4 KB limitation by modifying various advanced configuration settings.

The resource manager dynamically allocates the memory on the VXI/VME bus. Accessing the shared memory from the host controller is identical to accessing any other address in VXI/VME space. Other bus mastering devices can also read and write to this shared memory. However, the bus-mastering device must be provided with the address space and base address of the shared memory in order to be able to access it. There is no standard way for the bus mastering device to obtain this information and you must develop your own protocols for communicating this information.

The example in Figure 7 illustrates a C VISA program that can be used to access the dedicated shared memory. It also can be used to obtain information relating to the address space and offset of the memory. This information could then be sent to another VXI/VME bus-mastering device using whatever communication scheme you develop, so that it can access the shared memory.

/* This code listing does not include variable declarations or error checking routines due to space considerations and will not compile. It serves to show the correct sequence of VISA calls for accessing shared memory installed on a dedicated SIMM chip. The example assumes that the controller has a 1 MB SIMM chip installed and is configured
to share 1 MB. */

main()
{
status = viOpenDefaultRM (&rm);
/* Check status */
status = viOpen (rm, "VXI::0", VI_NULL, VI_NULL, &instr);
/* Check status */
status = viGetAttribute (instr, VI_ATTR_MEM_SPACE, &address_space);
/* Check status */
status = viGetAttribute (instr, VI_ATTR_MEM_BASE, &base_addr);

/* At this point any bus-mastering device can access the shared memory at absolute address = base address + 0x1000 (4 KB) in adress space = address_space. */

/* Write to the shared memory */
status = viOut8 (instr, address_space, 0x1000, 0XBEEF);
/* Check status */
/ *Read from shared memory */
status = viIn8 (instr, address_space, 0x1000, &value);
/* Check status */
/* Compare values */
if (value !=0xBEEF)
      printf("Error\n");
else
      printf("Success\n");
/* Close sessions */
viClose(instr);
viClose(rm);
}/* main */

Figure 7
. C NI-VISA Program that Accesses Shared Memory on a Dedicated SIMM

Accessing and Allocating Shared Host Memory
Sharing host memory requires that you configure the controller to share memory and then make NI-VXI or NI-VISA function calls to allocate and access the memory. The two LabVIEW examples shown in Figures 8 and 9 illustrate the use of both NI-VXI and NI-VISA to allocate and access the memory.

[+] Enlarge Image
Figure 8. LabVIEW NI-VISA Example for Sharing Host Memory

[+] Enlarge Image
Figure 9. LabVIEW NI-VXI Example for Sharing Host Memory

Figures 10 and 11 contain similar C examples. Note that on some platforms it is possible to perform a direct pointer dereference to access the VXI/VME shared memory when using the NI-VXI functions in a C-based environment. This results in extremely efficient code because you can avoid the small amount of overhead associated with making a function call. The result of the VXIMemAlloc function determines whether you can use direct pointer dereferencing. It should be mentioned that VISA uses pointer dereferences for the low-level viPeek and viPoke functions if it is able to. Thus, both LabVIEW and C programs that use VISA low-level register access calls will run just as efficiently as a similar application that used NI-VXI and pointer dereferencing. The examples in this application note do not include calls to the low-level register access functions/macros. Both NI-VXI and NI-VISA are shipped with several examples that illustrate the use of these low-level functions and you should refer to those examples to learn how to use these low-level functions.

/**************************************************************/
/*This code listing does not include variable declarations or error checking routines due to space considerations and will not compile. It serves to show the correct sequence of VISA calls for allocating and accessing shared memory. Note that it is assumed that shared memory has been configured in either T&M Explorer or VXI Edit. The general flow of this code is:  
   Open Resource Manager
   Open a session to LA 0
   Allocate the shared memory
   Use viGetAttribute to determine the offset of the shared memory.
   Use viOut16 to write a value into shared memory.
   Use viIn16 to read the value to see if the data was written correctly.
   Use viMemFree to free the shared memory buffer.
   Close Visa sessions
This example also does not show how to use the ViPeek and ViPoke low-level register access functions/macros.   */
/**************************************************************/
main()
{
status = viOpenDefaultRM (&defaultRM);
       /* Error check */
status = viOpen (defaultRM, "VXI0::0::INSTR", VI_NULL, VI_NULL, &instr);
       /* Error check */
size = 0x100;
/* This is how much memory we are going to set aside in our local RAM. Even though we have possibly many megs requested in VXI space, we are only going to use x100 bytes. */
status = viMemAlloc (instr, size, &offset);
       /* Error check */
       /* Determine in which address space the shared memory is located. */
viGetAttribute (instr, VI_ATTR_MEM_SPACE, &addrspace);

/* Find base address of our controller so another bus master can access shared memory. The shared memory is accessible at absolute address base +offset */
viGetAttribute (instr, VI_ATTR_MEM_BASE, &base);

       /* write a value into shared memory. */
status = viOut16 (instr, addrspace, offset, 0xBEEF);
       /* Error check */
/* At this point, you can use another bus master to access the shared memory at the Base + Offset. Read back from shared memory */
status = viIn16 (instr, addrspace, offset, &value);
       /* Error check */
       /* Compare response with stimulus */
if (value == 0xBEEF)
       printf ("Value written = value read\nSharing is successful!\n");
else
       printf ("We wrote 0xBEEF, but read back 0x%hX\n", value);

status = viMemFree (instr, offset); //free the allocated memory
       /* Error check */
status = viClose (instr);
status = viClose (defaultRM);
}
Figure 10. C VISA Example for Sharing Host Memory

/*This code listing does not include variable declarations or error checking routines due to space considerations and will not compile. It serves to show the correct sequence of NI-VXI calls for allocating and accessing shared memory. It is assumed that shared memory has been configured in either T&M Explorer or VXI Edit */
main()
{
size = 0x100;
InitVXIlibrary()
/* error check */

AllocStat = VXImemAlloc (size, &useraddr, &vxiaddr);
/* error check */

/* Can read the shared memory using VXImemcopy and/or direct pointer de-reference. If the Status from VXImemAlloc was 0, you can directly de-reference the pointer. If the Status was 1, you can only access the local buffer by using VXImemCopy. You can also use VXIIn/Out and VXIMove on MITE based platforms */

if ( AllocStat == 0 ) /* can access memory directly */
    value = *(UINT16 *)useraddr;   //deref the pointer directly
else     / * need to use VXImemCopy to access shared memory */
    {
        direction = 1;  / *move from local RAM to "value" */
        size = 2;              /* read 1 word. */
        Status = VXImemCopy (useraddr, &value, size, direction);
        /* error check */
    }
VXImemFree (useraddr);  /* free allocated memory */
CloseVXIlibrary();      /* close VXI library */

}
Figure 11. C NI-VXI Example for Sharing Host Memory

Common Questions and Troubleshooting


1.
VXImemAlloc/viMemAlloc fails when attempting to allocate a "locked down" physically contiguous buffer.

This may be a result of several things:

a. Ensure that the VXI Shared RAM Size is set larger than the Size parameter in VXImemAlloc or viMemAlloc. Typically, set the VXI Shared RAM Size to All of System Memory.

b. Ensure that the amount of Reserved Physical Memory (also referred to as the Shared RAM Pool) is smaller than the VXI Shared RAM Size parameter.

c. Any memory reserved from the operating system is allocated in a contiguous region; the operating system may not have been able to reserve the amount of memory you specified if there were not a large enough contiguous region available to it. You may want to start by reserving less than 1 MB initially and then incrementally increasing this to determine the amount of memory that can be reserved on your system.

d. Ensure that the Size parameter in VXImemAlloc or viMemAlloc is at least 1 KB smaller than the Shared RAM Pool Size (amount of reserved memory).

2.You get a system crash when your application attempts to access the shared memory buffer directly using the User Address pointer returned from VXImemAlloc().

In most nonvirtual memory systems, your user process can access the shared memory directly. Some virtual memory systems, such as using the AT-MXI under Windows NT, do not have the capability for a user process to access the kernel memory directly. In such systems, VXImemAlloc returns a value of 1, which indicates that the user address returned is not directly accessible by the user process. The user address is actually the kernel virtual address of the allocated shared memory. In this situation, you must use the function VXImemCopy to access the shared memory. Note that LabVIEW and VISA programmers do not need to be concerned about this.

3.
How can I access the shared memory allocated with VXImemAlloc() or viMemAlloc()?

With VISA, you can access the shared memory buffer using viIn8/16/32 or viOut8/16/32. You can also use pointer dereferencing with NI-VISA if you map the allocated address with viMapAddress and verify that the VI_ATTR_WIN_ACCESS attribute returns VI_DEREF_ADDR.

With the NI-VXI functions, you must use VXImemCopy() or you may use pointer dereferencing if
VXImemAlloc() returns 0 as its Return value. You cannot reliably use direct VXI access (VXIin, VXIout, or VXImove) to access the shared memory buffer on non MITE-based platforms.

4.
Why can't I use NI-VXI direct access functions to access a shared memory buffer allocated by VXImemAlloc()?

If you use VXIin, VXIout, or VXImove to access the shared memory buffer, the computer CPU or the VXI/VME controller may not allow that access. VXI/VME controllers without a MITE (e.g. AT-MXI or VXIpc-500 Series) do not allow VXI cycles to addresses on the controller performing the cycle (i.e. they do not allow self-access). Your PC may also not be able to do this self access even in the case where you are using a MITE-based controller. Since the MITE is located on the PCI bus, the processor writes to or reads from the MITE address space. Then the MITE needs to get control of the PCI bus to continue the read or write to the shared RAM. Some computer CPUs will NOT allow a device on the PCI bus to arbitrate for the PCI bus while a cycle is in progress. In some cases, you may be able to write successfully, while VXIin fails with a Bus Error.

You must use functions with which the CPU can directly access the shared memory on platforms for which VXImemAlloc returns a nonzero value. C developers using the NI VXI API must use VXImemCopy to access the shared memory buffer in such situations.

Developers using LabVIEW or VISA functions do not need to be concerned with this issue. Both LabVIEW and VISA handle this automatically.

5.
Which kind of SIMMs can I install on the PCI-MXI-2, VXI-MXI-2, VME-MXI-2 or VXI-MIO boards?

72 pin, 70 ns or faster SIMMs. Parity/nonparity does not matter.

6.
Can I configure my system to share both system memory and onboard memory (SIMMs installed in PCI-MXI-2, VXI-MXI-2 or VME-MXI-2)?

Yes, typically you will configure the VXI Shared RAM size to be twice the greater of system memory in your computer or onboard RAM. Under the Advanced Shared RAM settings button, select the Lower Half Window to System memory. Configure the Upper Half Window to Onboard memory. Remember that you cannot access the lower 4 KB of the onboard RAM because this is the location of the EEPROM.

Summary



National Instruments VXI/VME controllers provide at least one of two options for dual porting memory onto the VXI backplane. With some controllers, you can install a dedicated RAM SIMM; with some, you can map the operating system memory onto the VXI/VME bus; and with some, you can do both. This memory appears as if it resides on the VXI/VME bus but resides on the host controller. VXI/VME bus mastering instruments can use this memory to store data required during analysis, generation or acquisition. Using shared memory with low-cost RAM SIMM modules, you can solve your data storage problems without having to purchase expensive dedicated memory modules for your instruments. Most users should consider sharing the host controller RAM and using NI-VISA to access the shared memory buffer as their best option. Developers using VISA do not need to be concerned with having to use special functions to access the local shared memory buffer.
6 ratings | 4.50 out of 5
Print

Reader Comments | Submit a comment »

student
it was a fairly decent source of information. thank you - answered my question.
- brianlui_911@hotmail.com - Mar 1, 2006

 

Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).