Skip to content

Instantly share code, notes, and snippets.

@MelvinTo
Created April 2, 2017 15:30
Show Gist options
  • Save MelvinTo/ab6eadd6e80e8eb1c8751e44776662a5 to your computer and use it in GitHub Desktop.
Save MelvinTo/ab6eadd6e80e8eb1c8751e44776662a5 to your computer and use it in GitHub Desktop.
watchdog sample code
cat a.c
/*
* Linux watchdog demo for LPC313x
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <linux/watchdog.h>
#define WATCHDOGDEV "/dev/watchdog"
static const char *const short_options = "hd:i:";
static const struct option long_options[] = {
{"help", 0, NULL, 'h'},
{"dev", 1, NULL, 'd'},
{"interval", 1, NULL, 'i'},
{NULL, 0, NULL, 0},
};
static void print_usage(FILE * stream, char *app_name, int exit_code)
{
fprintf(stream, "Usage: %s [options]\n", app_name);
fprintf(stream,
" -h --help Display this usage information.\n"
" -d --dev <device_file> Use <device_file> as watchdog device file.\n"
" The default device file is '/dev/watchdog'\n"
" -i --interval <interval> Change the watchdog interval time\n");
exit(exit_code);
}
int main(int argc, char **argv)
{
int fd; /* File handler for watchdog */
int interval; /* Watchdog timeout interval (in secs) */
int bootstatus; /* Wathdog last boot status */
char *dev; /* Watchdog default device file */
int next_option; /* getopt iteration var */
char kick_watchdog; /* kick_watchdog options */
/* Init variables */
dev = WATCHDOGDEV;
interval = 0;
kick_watchdog = 0;
/* Parse options if any */
do {
next_option = getopt_long(argc, argv, short_options,
long_options, NULL);
switch (next_option) {
case 'h':
print_usage(stdout, argv[0], EXIT_SUCCESS);
case 'd':
dev = optarg;
break;
case 'i':
interval = atoi(optarg);
break;
case '?': /* Invalid options */
print_usage(stderr, argv[0], EXIT_FAILURE);
case -1: /* Done with options */
break;
default: /* Unexpected stuffs */
abort();
}
} while (next_option != -1);
/* Once the watchdog device file is open, the watchdog will be activated by
the driver */
fd = open(dev, O_RDWR);
if (-1 == fd) {
fprintf(stderr, "Error: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
/* If user wants to change the watchdog interval */
if (interval != 0) {
fprintf(stdout, "Set watchdog interval to %d\n", interval);
if (ioctl(fd, WDIOC_SETTIMEOUT, &interval) != 0) {
fprintf(stderr,
"Error: Set watchdog interval failed\n");
exit(EXIT_FAILURE);
}
}
/* Display current watchdog interval */
if (ioctl(fd, WDIOC_GETTIMEOUT, &interval) == 0) {
fprintf(stdout, "Current watchdog interval is %d\n", interval);
} else {
fprintf(stderr, "Error: Cannot read watchdog interval\n");
exit(EXIT_FAILURE);
}
/* Check if last boot is caused by watchdog */
if (ioctl(fd, WDIOC_GETBOOTSTATUS, &bootstatus) == 0) {
fprintf(stdout, "Last boot is caused by : %s\n",
(bootstatus != 0) ? "Watchdog" : "Power-On-Reset");
} else {
fprintf(stderr, "Error: Cannot read watchdog status\n");
exit(EXIT_FAILURE);
}
/* There are two ways to kick the watchdog:
- by writing any dummy value into watchdog device file, or
- by using IOCTL WDIOC_KEEPALIVE
*/
fprintf(stdout,
"Use:\n"
" <w> to kick through writing over device file\n"
" <i> to kick through IOCTL\n" " <x> to exit the program\n");
do {
kick_watchdog = getchar();
switch (kick_watchdog) {
case 'w':
write(fd, "w", 1);
fprintf(stdout,
"Kick watchdog through writing over device file\n");
break;
case 'i':
ioctl(fd, WDIOC_KEEPALIVE, NULL);
fprintf(stdout, "Kick watchdog through IOCTL\n");
break;
case 'x':
fprintf(stdout, "Goodbye !\n");
break;
default:
fprintf(stdout, "Unknown command\n");
break;
}
} while (kick_watchdog != 'x');
/* The 'V' value needs to be written into watchdog device file to indicate
that we intend to close/stop the watchdog. Otherwise, debug message
'Watchdog timer closed unexpectedly' will be printed
*/
write(fd, "V", 1);
/* Closing the watchdog device will deactivate the watchdog. */
close(fd);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment