VMIWDT-7326: GE Fanuc Watchdog Timer Driver
Contents:Abstract Installation Loading and Unloading the Module Using Module Parameters Writing Applications Using the VMIWDT-7326 Driver Using the Watchdog Timer
Abstract
The vmiwdt-7326 driver is a loadable Linux device driver module for GE Fanuc SBCs with a watchdog timer device. SBCs currently supported by this driver include:
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 vmiwdt-7326 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
Warning: Linux kernel source code must be installed to build the driver module.
|
To use the vmiwdt-7326 driver, it must first be compiled (built) into executable code and installed. The next code listing illustrates how to compile and install the vmiwdt-7326 driver.
Code listing 1: Compiling and Installing the VMIWDT-7326 Driver |
// From the vmiwdt-7326 base directory execute:
sh$ make
sh# make install
|
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/
vmiwdt-7326.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 vmiwdt-7326.
Use the lsmod command command to verify that the module loaded successfully. When you enter lsmod, the module name vmiwdt-7326 should appear in the output.
To unload the module, enter modprobe -r vmiwdt-7326.
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 vmiwdt-7326 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 VMIWDT-7326 Driver
The vmiwdt-7326 driver supports the following standard Linux system calls:
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 = 33;
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 vmiwdt-7326
// Now let's run our code.
sh$ ./wd_test
Watchdog module is vmiwdt-7326
Firmware revision 1
Supported options are:
SETTIMEOUT
Watchdog will timeout in 20 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 > 67 seconds, the ioctl call will return an error. The WDIOC_GETTIMEOUT ioctl command returns the current timeout value in seconds. The vmiwdt-7326 driver supports the following timeout values.
- 67 seconds
- 33 seconds
- 21 seconds
- 524 milliseconds
- 262 milliseconds
- 131 milliseconds
- 32 milliseconds
- 2 milliseconds
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.
|