VMINVR: GE Fanuc Non-Volatile RAM Driver

Contents:

Abstract
Installation
Loading and Unloading the Module
Using Module Parameters
Writing Applications Using the VMINVR Driver
Testing Non-Volatile RAM (NVRAM)

Abstract

The vminvr driver is a loadable Linux device driver module for non-volatile RAM (NVRAM) on GE Fanuc single board computers (SBCs). SBCs currently supported include:

  • VMICPCI-7305
  • VMICPCI-7593
  • VMICPCI-7594
  • VMICPCI-7696
  • VMICPCI-7697
  • VMICPCI-7699
  • VMICPCI-7715
  • VMICPCI-7716
  • VMICPCI-7753
  • VMICPCI-7755
  • VMICPCI-7756
  • VMICPCI-7757
  • VMIPC4-7301
  • VMIOMAX-8451
  • VMIVME-7591
  • VMIVME-7592
  • VMIVME-7695
  • VMIVME-7696
  • VMIVME-7697
  • VMIVME-7697a
  • VMIVME-7698
  • VMIVME-7700
  • VMIVME-7740
  • VMIVME-7750
  • VMIVME-7751
  • VMIVME-7765
  • VMIVME-7766
  • VMIVME-7805
  • VMIVME-7807
  • VMIVME-7810

This list may not be complete. If your board is not listed please contact GE Fanuc Customer Care to confirm support.

This document describes installation and usage of the vminvr non-volatile RAM (NVRAM) driver for GE Fanuc SBCs.

This document assumes that you have some knowledge of the Linux operating system and C programming for POSIX/UNIX machines.

Installation

Building

Warning: Linux kernel source code must be installed to build the driver module.

To use the vminvr driver, it must first be compiled (built) into executable code and installed. The next code listing illustrates how to compile and install the vminvr driver.

Code listing 1: Compiling and Installing the VMINVR Driver

// From the vminvr base directory execute:
sh$ make
sh# make install

Verifying the Installation

If the project is built and installed correctly, you should have the following file installed on your system:

Code listing 2: Verify the Installation

// This is the driver module.  Make sure you use `uname -r`, not 'uname -r'.
sh$ ls /lib/modules/`uname -r`/extra/
vminvr.ko
// This is the device file we will use to access NVRAM.
sh$ ls /dev/nvram
/dev/nvram
// /dev/watchdog should be a character special file with
// major device number 10 and minor device number 144

Loading and Unloading the Module

Use the modprobe command to load the driver module by entering modprobe vminvr.

Use the lsmod command command to verify that the module loaded successfully. When you enter lsmod, the module name vminvr should appear in the output.

To unload the module, enter modprobe -r vminvr.

Using Module Parameters

To use module parameters, add them to the /etc/modules.conf file or specify them on the insmod or modprobe command line.

The following parameters are defined for the vminvr driver:

  • phys_addr - The physical address of NVRAM
  • size - Size of NVRAM in bytes

Warning: Module parameters can be passed in using insmod, but insmod does not read parameters from /etc/modules.conf.

Writing Applications Using the VMINVR Driver

The vminvr driver supports the following standard Linux system calls:

  • open
  • close
  • read
  • write
  • lseek
  • mmap
  • pread
  • pwrite

Code listing 3: Writing an application that uses NVRAM

// Here is some test code that demonstrates use of the NVRAM driver.
// This source code is included in the test directory.
// The file is called interface_test.c

/*
 * Test the interface to the NVRAM driver
 */


#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>


/*===========================================================================
 * Main routine
 */
int main()
{
	off_t size;
	char *ptr = NULL;
	char data, pattern;
	int fd;

	fd = open("/dev/nvram", O_RDWR);
	if (-1 == fd) {
		perror("open");
		return -1;
	}

	/* Use lseek to determine the size of the NVRAM
	 */
	size = lseek(fd, 0, SEEK_END);
	if (0 >= size) {
		perror("lseek");
		goto err_out;
	}

	fprintf(stderr, "NVRAM size is 0x%x bytes\n", (int) size);

	fprintf(stdout, "First pass read/write: ");

	pattern = 0x55;

	lseek(fd, -1, SEEK_CUR);
	write(fd, &pattern, sizeof (pattern));
	lseek(fd, size - 1, SEEK_SET);
	read(fd, &data, sizeof (data));

	if (data != pattern) {
		fprintf(stdout, "FAILED\n");
		goto err_out;
	}

	fprintf(stdout, "PASSED\n");

	fprintf(stdout, "Second pass read/write: ");

	pattern = ~pattern;

	lseek(fd, size - 1, SEEK_SET);
	write(fd, &pattern, sizeof (pattern));
	lseek(fd, -1, SEEK_CUR);
	read(fd, &data, sizeof (data));

	if (data != pattern) {
		fprintf(stdout, "FAILED\n");
		goto err_out;
	}

	fprintf(stdout, "PASSED\n");

	fprintf(stdout, "Memory-mapped access: ");

	/* NVRAM on some devices does not start on a page boundry; mmap() on
           these devices is not supported, use it at your own risk.
	 */
	if (size % getpagesize()) {
		fprintf(stdout, "NOT SUPPORTED\n");
	} else {
		ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
		if (MAP_FAILED == ptr) {
			perror("mmap");
			goto err_out;
		}

		if (ptr[size - 1] != pattern) {
			fprintf(stdout, "FAILED\n");
			goto err_out;
		}

		fprintf(stdout, "PASSED\n");

		if (munmap(ptr, size)) {
			perror("munmap");
			goto err_out;
		}
	}

	if (close(fd)) {
		perror("close");
		return -1;
	}

	return 0;

      err_out:
	close(fd);
	return -1;
}


// If you have not already done so, load the driver.
sh# modprobe vminvr
// Now let's run our code. From the test directory run,
sh$ ./interface_test

NVRAM size is 0x8000 bytes
First pass read/write: PASSED
Second pass read/write: PASSED
Memory-mapped access: PASSED

Note: On some GE Fanuc SBCs, NVRAM does not start on a PAGE boundary, but mmap() requires the base address and size of the region to be PAGE aligned. Therefore, the mmap() function is not supported on SBCs with non-page-aligned NVRAM.

Testing Non-Volatile RAM (NVRAM)

In the test directory, there is a piece of test code, nvram_test.c. This application performs a full test of the NVRAM device.

Warning: The test done by nvram_test.c will erase all data stored in NVRAM!



Copyright 2006 GE Fanuc Embedded Systems, Inc. Questions, Comments, Corrections? Email support.embeddedsystems@gefanuc.com.