VMIWDTF: GE Fanuc Watchdog Timer Driver

Contents:

Abstract
Installation
Loading and Unloading the Module
Using Module Parameters
Writing Applications Using the VMIWDTF Driver
Using the Watchdog Timer

Abstract

The vmiwdtf driver is a loadable Linux device driver module for GE Fanuc SBCs with a watchdog timer device. SBCs currently supported by this driver include:

  • VMICPCI-7755
  • VMICPCI-7756
  • VMICPCI-7757
  • VMIVME-7700
  • 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 vmiwdtf watchdog timer 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 vmiwdtf driver, it must first be compiled (built) into executable code and installed. The next code listing illustrates how to compile and install the vmiwdtf driver.

Code listing 1: Compiling and Installing the VMIWDTF Driver

// From the vmiwdtf 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/
vmiwdtf.ko
// This is the device file we will use to access the watchdog device.
sh$ ls -l /dev/watchdog
/dev/watchdog
// /dev/watchdog should be a character special file with
// major device number 10 and minor device number 130

Loading and Unloading the Module

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

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

To unload the module, enter modprobe -r vmiwdtf.

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 vmiwdtf driver:

  • serr - Generate PCI bus SERR instead of system reset upon watchdog timeout

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

Writing Applications Using the VMIWDTF Driver

The vmiwdtf driver supports the following standard Linux system calls:

  • open
  • close
  • write
  • ioctl

Code listing 3: Writing an application that uses the watchdog timer

// Here is some test code that demonstrates use of the watchdog timer.
// This source code is included in the test directory.
// The file is called wd_test.c


#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/types.h>
#include <linux/watchdog.h>
#include <sys/ioctl.h>


/* Older 2.4.x kernel versions did not have *TIMEOUT operations in "watchdog.h"
 */
#ifndef WDIOC_SETTIMEOUT
#define WDIOC_SETTIMEOUT        _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)
#define WDIOF_SETTIMEOUT        0x0080
#endif				/* WDIOC_SETTIMEOUT */


/*===========================================================================
 * Main routine
 */
int main(int argc, char **argv)
{
	struct watchdog_info wdt_info;
	int c, fd, to = 0;

	while (-1 != (c = getopt(argc, argv, "s:"))) {
		switch (c) {
		case 's':	/* timeout in seconds */
			to = strtol(optarg, NULL, 0);
			break;
		default:
			fprintf(stderr, "USAGE: wd_test [-s seconds]");
		}
	}

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

	if (ioctl(fd, WDIOC_GETSUPPORT, &wdt_info)) {
		perror("ioctl");
		goto error_exit;
	}

	printf("Watchdog module is %s\n", (char *) wdt_info.identity);
	printf("Firmware revision %d\n", wdt_info.firmware_version);
	printf("Supported options are:\n");
	if (0 == wdt_info.options)
		printf("  none\n");
	if (WDIOF_OVERHEAT & wdt_info.options)
		printf("  OVERHEAT\n");
	if (WDIOF_FANFAULT & wdt_info.options)
		printf("  FANFAULT\n");
	if (WDIOF_EXTERN1 & wdt_info.options)
		printf("  EXTERN1\n");
	if (WDIOF_EXTERN2 & wdt_info.options)
		printf("  EXTERN2\n");
	if (WDIOF_POWERUNDER & wdt_info.options)
		printf("  POWERUNDER \n");
	if (WDIOF_CARDRESET & wdt_info.options)
		printf("  CARDRESET\n");
	if (WDIOF_POWEROVER & wdt_info.options)
		printf("  POWEROVER\n");
	if (WDIOF_SETTIMEOUT & wdt_info.options)
		printf("  SETTIMEOUT\n");
	if (WDIOF_KEEPALIVEPING & wdt_info.options)
		printf("  KEEPALIVEPING\n");

	if (to) {
		if (ioctl(fd, WDIOC_SETTIMEOUT, &to)) {
			perror("ioctl");
			goto error_exit;
		}
	} else {
		if (ioctl(fd, WDIOC_GETTIMEOUT, &to)) {
			perror("ioctl");
			goto error_exit;
		}
	}

	/* Just testing the ioctl keepalive interface
	 */
	if (ioctl(fd, WDIOC_KEEPALIVE)) {
		perror("ioctl");
		goto error_exit;
	}

	printf("Watchdog will timeout in %d seconds\n", to);

	c = 0;
	while ('q' != c) {
		/* Write anything to the watchdog file to keepalive
		 */
		if (-1 == write(fd, &c, sizeof (c))) {
			perror("write");
			goto error_exit;
		}

		printf("Press <enter> to keepalive or 'q'<enter> to quit\n");
		c = getchar();
	}

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

	return 0;

      error_exit:

	close(fd);
	return -1;
}


// To compile the application run:
// If you have not already done so, load the driver.
sh# modprobe vmiwdtf
// Now let's run our code.
sh$ ./wd_test


Watchdog module is vmiwdtf
Firmware revision 1
Supported options are:
  SETTIMEOUT
Watchdog will timeout in 135 seconds
Press <enter> to keepalive or 'q'<enter> to quit


Using the Watchdog Timer

The watchdog timer starts immediately when the device file /dev/watchdog is opened. A keepalive signal must be sent to the watchdog device before the timer expires to prevent a system reset (or SERR assertion). There are two methods of sending the keepalive signal.

  • Write a value (any value) to the /dev/watchdog device -or-
  • Use the WDIOC_KEEPALIVE ioctl command.

The timeout duration of the watchdog timer is configurable. The timeout value can be set by using the WDIOC_SETTIMEOUT ioctl command. This command returns the timeout value set which may differ from the value you requested, depending on the timer's resolution. The timeout value set will always be equal to or greater than the value that you requested. If you request > 135 seconds, the ioctl call will return an error. The WDIOC_GETTIMEOUT ioctl command returns the current timeout value in seconds. The vmiwdtf driver supports the following timeout values.

  • 135 seconds
  • 33 seconds
  • 2 seconds

The watchdog timer is disabled by closing the /dev/watchdog device file unless your kernel was built with CONFIG_WATCHDOG_NOWAYOUT in which case, there is no way to disable the watchdog timer once it has started.

On VMIVME SBCs, the watchdog timer can generate a VMEbus SYSFAIL interrupt. To do this, you must load the vmiwdtf driver with the parameter serr=1. You must also load the VMEbus driver with the WDSYS bit set in the COMM register. See your VMEbus driver documentation or SBC manual for a description of the COMM register.



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