aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-applications/watchdog-test/files/watchdog-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-applications/watchdog-test/files/watchdog-test.c')
-rw-r--r--meta-amd-bsp/recipes-applications/watchdog-test/files/watchdog-test.c288
1 files changed, 288 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-applications/watchdog-test/files/watchdog-test.c b/meta-amd-bsp/recipes-applications/watchdog-test/files/watchdog-test.c
new file mode 100644
index 00000000..daedce98
--- /dev/null
+++ b/meta-amd-bsp/recipes-applications/watchdog-test/files/watchdog-test.c
@@ -0,0 +1,288 @@
+/*****************************************************************************
+*
+* Copyright (c) 2014, Advanced Micro Devices, Inc.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of Advanced Micro Devices, Inc. nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*
+***************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <readline/readline.h>
+#include <linux/watchdog.h>
+
+#define WATCHDOG_APP_VERSION "0.1"
+
+int fd; /* /dev/watchdog file descriptor */
+volatile int ping;
+
+char *show_prompt(void)
+{
+ return "$ ";
+}
+
+void sighandler(int sig)
+{
+ printf("\n%s", show_prompt());
+}
+
+void pinghandler(int sig)
+{
+ ping = 0;
+ printf("\n");
+ /* Set the signal handler back to the original */
+ signal(SIGINT, sighandler);
+}
+
+void show_license(void)
+{
+ printf("/*****************************************************************************\n"
+ "*\n"
+ "* Copyright (c) 2014, Advanced Micro Devices, Inc.\n"
+ "* All rights reserved.\n"
+ "*\n"
+ "* Redistribution and use in source and binary forms, with or without\n"
+ "* modification, are permitted provided that the following conditions are met:\n"
+ "* * Redistributions of source code must retain the above copyright\n"
+ "* notice, this list of conditions and the following disclaimer.\n"
+ "* * Redistributions in binary form must reproduce the above copyright\n"
+ "* notice, this list of conditions and the following disclaimer in the\n"
+ "* documentation and/or other materials provided with the distribution.\n"
+ "* * Neither the name of Advanced Micro Devices, Inc. nor the names of\n"
+ "* its contributors may be used to endorse or promote products derived\n"
+ "* from this software without specific prior written permission.\n"
+ "*\n"
+ "* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n"
+ "* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
+ "* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"
+ "* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY\n"
+ "* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n"
+ "* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
+ "* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n"
+ "* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
+ "* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n"
+ "* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
+ "*\n"
+ "*\n"
+ "***************************************************************************/\n");
+}
+
+void print_usage()
+{
+ printf("\nCommands Supported ->\n");
+ printf(" disablewatchdog : Disables the Watchdog Timer\n");
+ printf(" enablewatchdog : Enables the Watchdog Timer\n");
+ printf(" getfeatures : Shows the features supported by the Watchdog implementation\n");
+ printf(" getstatus : Gives the current status of Watchdog Timer\n");
+ printf(" getbootstatus : Displays the status of Watchdog Hardware after reboot or fresh boot\n");
+ printf(" ping : Resets Watchdog Timer at regular intervals\n");
+ printf(" gettimeout : Gives the value of Watchdog timeout (in frequency units)\n");
+ printf(" gettimeleft : Gives the current value of Watchdog Timer (in frequency units)\n");
+ printf(" sendmagicchar : Sends the magic character 'V' to the Watchdog device\n");
+ printf(" settimeout <timeout> : Sets the new value for Watchdog timeout (in frequency units)\n");
+ printf(" license : Displays the terms of LICENSE for this application\n");
+ printf(" help : Displays help text\n");
+ printf(" exit : Exits the application\n\n");
+}
+
+void parse_cmd(const char *cmdline)
+{
+ if ((cmdline == NULL) || (strncmp(cmdline, "exit", 4) == 0)) {
+ printf("\nExiting...\n");
+ printf("\nIf the Watchdog Timer was not disabled, and you did not send the magic character,\n"
+ "Watchdog Timer is still ticking, and your system will reboot soon\n");
+
+ if(close(fd) < 0)
+ perror("Error closing /dev/watchdog");
+ exit(EXIT_SUCCESS);
+ } else if (strncmp(cmdline, "help", 4) == 0)
+ print_usage();
+ else if (strncmp(cmdline, "disablewatchdog", 7) == 0) {
+ int flags;
+
+ printf("\nDisabling watchdog timer...\n");
+ flags = WDIOS_DISABLECARD;
+ if (ioctl(fd, WDIOC_SETOPTIONS, &flags) < 0)
+ perror("Could not disable watchdog");
+ } else if (strncmp(cmdline, "enablewatchdog", 6) == 0) {
+ int flags;
+
+ printf("\nEnabling watchdog timer...\n");
+ flags = WDIOS_ENABLECARD;
+ if (ioctl(fd, WDIOC_SETOPTIONS, &flags) < 0)
+ printf("Could not enable watchdog");
+ } else if (strncmp(cmdline, "getfeatures", 10) == 0) {
+ struct watchdog_info info;
+
+ if(ioctl(fd, WDIOC_GETSUPPORT, &info) < 0)
+ perror("Could not get watchdog features");
+
+ printf("\nIdentity:\t\t%s\n", info.identity);
+ printf("Firmware Version:\t%u\n", info.firmware_version);
+ printf("Options Set: \n"
+ "%s%s%s%s%s%s%s%s%s%s%s\n",
+ info.options & WDIOF_OVERHEAT ? "\t\t\tReset due to CPU overheat\n": "",
+ info.options & WDIOF_FANFAULT ? "\t\t\tFan failed\n": "",
+ info.options & WDIOF_EXTERN1 ? "\t\t\tExternal relay 1\n": "",
+ info.options & WDIOF_EXTERN2 ? "\t\t\tExternal relay 2\n": "",
+ info.options & WDIOF_POWERUNDER ? "\t\t\tPower bad/power fault\n": "",
+ info.options & WDIOF_CARDRESET ? "\t\t\tCard previously reset the CPU\n": "",
+ info.options & WDIOF_POWEROVER ? "\t\t\tPower over voltage\n": "",
+ info.options & WDIOF_SETTIMEOUT ? "\t\t\tSet timeout (in frequency units)\n": "",
+ info.options & WDIOF_MAGICCLOSE ? "\t\t\tSupports magic close character\n": "",
+ info.options & WDIOF_PRETIMEOUT ? "\t\t\tPretimeout (in frequency units)\n": "",
+ info.options & WDIOF_KEEPALIVEPING ? "\t\t\tKeep alive ping reply\n": "");
+ } else if (strncmp(cmdline, "getstatus", 9) == 0) {
+ int status;
+
+ printf("\n");
+ if(ioctl(fd, WDIOC_GETSTATUS, &status) < 0)
+ perror("Could not get watchdog status");
+
+ if (status & (1 << 0))
+ printf("\nWatchdog device is active\n");
+ if (status & (1 << 1))
+ printf("Watchdog device opened via /dev/watchdog\n");
+ if (status & (1 << 2))
+ printf("Received magic char\n");
+ if (status & (1 << 3))
+ printf("nowayout set\n");
+ if (status & (1 << 4))
+ printf("Watchdog device unregistered\n");
+ } else if (strncmp(cmdline, "getbootstatus", 7) == 0) {
+ int bootstatus;
+
+ if(ioctl(fd, WDIOC_GETBOOTSTATUS, &bootstatus) < 0)
+ perror("Could not get bootstatus");
+
+ printf("\nbootstatus: \n"
+ "%s%s%s%s%s%s%s%s%s%s%s\n",
+ bootstatus & WDIOF_OVERHEAT ? "\t\t\tReset due to CPU overheat\n": "",
+ bootstatus & WDIOF_FANFAULT ? "\t\t\tFan failed\n": "",
+ bootstatus & WDIOF_EXTERN1 ? "\t\t\tExternal relay 1\n": "",
+ bootstatus & WDIOF_EXTERN2 ? "\t\t\tExternal relay 2\n": "",
+ bootstatus & WDIOF_POWERUNDER ? "\t\t\tPower bad/power fault\n": "",
+ bootstatus & WDIOF_CARDRESET ? "\t\t\tCard previously reset the CPU\n": "",
+ bootstatus & WDIOF_POWEROVER ? "\t\t\tPower over voltage\n": "",
+ bootstatus & WDIOF_SETTIMEOUT ? "\t\t\tSet timeout (in frequency units)\n": "",
+ bootstatus & WDIOF_MAGICCLOSE ? "\t\t\tSupports magic close character\n": "",
+ bootstatus & WDIOF_PRETIMEOUT ? "\t\t\tPretimeout (in frequency units)\n": "",
+ bootstatus & WDIOF_KEEPALIVEPING ? "\t\t\tKeep alive ping reply\n": "");
+ } else if (strncmp(cmdline, "ping", 4) == 0) {
+ int dummy;
+
+ printf("\nContinuosly resetting Watchdog...press Ctrl+C to stop\n");
+ printf("\nOnce you stop pinging, Watchog Timer will start counting down...\n");
+ printf("...If the Watchdog Timer was enabled\n");
+
+ /* Lets set a different handler for Ctrl+C */
+ signal(SIGINT, pinghandler);
+
+ ping = 1;
+ while (ping) {
+ if(ioctl(fd, WDIOC_KEEPALIVE, &dummy) < 0) {
+ perror("Error sending ping");
+ break;
+ }
+ sleep(1);
+ }
+ } else if (strncmp(cmdline, "gettimeout", 10) == 0) {
+ int timeout;
+
+ if(ioctl(fd, WDIOC_GETTIMEOUT, &timeout) < 0)
+ perror("Error getting watchdog timeout");
+
+ printf("\nCurrent setting of timeout is %d frequency units\n", timeout);
+ } else if (strncmp(cmdline, "gettimeleft", 11) == 0) {
+ int timeleft;
+
+ if(ioctl(fd, WDIOC_GETTIMELEFT, &timeleft) < 0)
+ perror("Error getting watchdog timeleft");
+
+ printf("\nTime left for system reboot/shutdown is %d frequency units\n", timeleft);
+ } else if (strncmp(cmdline, "sendmagicchar", 9) == 0) {
+ printf("\nSending magic character to Watchdog device...\n");
+ printf("\nWatchdog Timer will be stopped once you exit the application\n");
+ if(write(fd, "V", 1) < 0)
+ perror("Could not send magic character");
+ } else if (strncmp(cmdline, "settimeout", 10) == 0) {
+ const char *charp = cmdline;
+ int timeout;
+
+ /* Lets point to the end of first token */
+ charp += strlen("settimeout");
+ /* Skip blank characters */
+ while (*charp == ' ' || *charp == '\t' || *charp == '\n')
+ charp++;
+
+ /* Now we should be pointing to the first 'digit' character */
+ timeout = atoi(charp);
+
+ if(ioctl(fd, WDIOC_SETTIMEOUT, &timeout) < 0) {
+ perror("Could not set watchdog timeout");
+ return;
+ }
+
+ printf("\nSetting timeout to %d frequency units\n", timeout);
+ printf("Watchdog Timer will start counting down with the new timeout value\n");
+ } else if (strncmp(cmdline, "license", 7) == 0) {
+ show_license();
+ } else {
+ printf("\nUnknown command\n");
+ print_usage();
+ }
+}
+
+int main(void)
+{
+ char *cmdline= NULL;
+
+ printf("Watchdog sample application version: %s\n", WATCHDOG_APP_VERSION);
+ printf("Copyright (c) 2014, Advanced Micro Devices, Inc.\n"
+ "This sample application comes with ABSOLUTELY NO WARRANTY;\n"
+ "This is free software, and you are welcome to redistribute it\n"
+ "under certain conditions; type `license' for details.\n\n");
+
+
+ if ((fd = open("/dev/watchdog", O_WRONLY)) < 0) {
+ perror("Could not open /dev/watchdog");
+ exit(1);
+ }
+
+ /* Handler for Ctrl+C */
+ signal(SIGINT, sighandler);
+
+ while (1) {
+ cmdline = readline(show_prompt());
+ parse_cmd(cmdline);
+ /* Free the memory malloc'ed by readline */
+ free(cmdline);
+ }
+
+ /* Should never reach here */
+ return 0;
+}