The goal of the document is to illustrate how to use watchdog of SP7350.
Contents of Table
Table of Contents | ||
---|---|---|
|
1.
...
Checking Watchdog Device Existence
1.1
...
Checking Watchdog Devices in /dev/
Pleae use 'To verify the existence of watchdog devices, execute the command:
ls /dev/watchdog*
...
Typically, two watchdog devices are present, as shown illustrated below:
Code Block |
---|
~ # ls -l /dev/watchdog* crw-rw---- 1 root root 10, 130 Jan 1 00:00 /dev/watchdog crw-rw---- 1 root root 252, 0 Jan 1 00:00 /dev/watchdog0 ~ # |
If watchdog devices do are not exist, you need check:Check If found, ensure to:
Verify if the watchdog node in dts is not
...
set as "disabled".
...
Confirm the watchdog driver is enabled.
1.2
...
Verifying Watchdog Node Status in dts
...
Refer to the watchdog node in dtsDTS:
Code Block |
---|
&watchdog { timeout-sec = <10>; }; |
1.3
...
Ensuring Watchdog Driver Enablement
To check if verify the watchdog driver is enabled, please run 'make kconfig' to in project top directory. When configuration menu pops up, move cursor to “Device 's status, navigate to the project's top directory and execute:
make kconfig
In the kernel configuration menu, locate "Device Drivers > Watchdog Timer Support > Sunplus watchdog support” and make sure “Sunplus watchdog support” support" and ensure "Sunplus watchdog support" is enabled. Refer to the Linux kernel configuration menu below:
...
2.
...
Implementing Watchdog Setup and Feeding Application
Refer to the following C example code of demonstrating watchdog setup and feeding application. The This application setupsconfigures, startsinitiates, and then feeds the watchdog every 12 seconds. The maximum time-out time of watchdog of SP7021 have no watchdog on SP7350 has no maximum timeout limit.
watchdog.c
Code Block |
---|
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <pthread.h> #include <sys/ioctl.h> #define WATCHDOG_IOCTL_BASE 'W' #define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int) #define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int) #define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int) #define WDIOS_DISABLECARD 1 #define WDIOS_ENABLECARD 2 #define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int) int ret; int wd_fd; volatile int wd_feed_time = 12; // Feed watchdog every 12 second by default. int wd_timeout = 15; // Timeout time of watchdog. Reset event occurs if watchdog is not fed within this time. /* a thread feed dog */ void *feedwdt_thd() { while(1) { // Feed (reset) watchdog. ret = ioctl(wd_fd, WDIOC_KEEPALIVE, 0); if (ret != 0) { printf("Feed watchdog failed. \n"); close(wd_fd); } else { printf("Feed watchdog every %d seconds.\n", wd_feed_time); } sleep(wd_feed_time); } } /* a thread read counter and print the value */ void *readwdt_thd() { int arg; int i; while(1) { ret = ioctl(wd_fd, WDIOC_GETTIMELEFT, &arg); if (ret != 0) { printf("get data failed. \n"); } printf("cnt value is 0x%x\n", arg); usleep(200000); } } int main(void) { pthread_t wd_feed_thread; pthread_t wd_read_thread; int wd_option; char str[10]; int num = 0; char* ptr = str; // Get file handle of watchdog device. wd_fd = open("/dev/watchdog0", O_WRONLY); if (wd_fd == -1) { perror("watchdog"); exit(EXIT_FAILURE); } // Enable wacthdog. wd_option = WDIOS_ENABLECARD; ret = ioctl(wd_fd, WDIOC_SETOPTIONS, &wd_option); if (ret != 0) { printf("Failed to start watchdog!\n"); close(wd_fd); return -1; } // Setup timeout time. ret = ioctl(wd_fd, WDIOC_SETTIMEOUT, &wd_timeout); if (ret != 0) { printf("Failed to set timeout time!n"); close(wd_fd); return -1; } // Create a thread for feeding watchdog. ret = pthread_create(&wd_feed_thread, NULL, feedwdt_thd, NULL); if (ret < 0) printf("Failed to create feeddog thread!\n"); #if 0 // Create a thread for reading and printing counter value. ret = pthread_create(&wd_read_thread, NULL, readwdt_thd, NULL); if (ret < 0) printf("Failed to create read counter thread!\n"); #endif while(1) { printf("Press 'e' to disable watchdog and exit.\n"); printf("Enter a number for new feed time (current feed time is %d seconds, timeout time is %d seconds):\n", wd_feed_time, wd_timeout); scanf("%s", str); //printf("debug why feedtime invarible %s\n",str); if (!strcmp(str,"e")) { wd_option = WDIOS_DISABLECARD; ret = ioctl(wd_fd, WDIOC_SETOPTIONS, &wd_option); if (ret != 0) { printf("Failed to stop watchdog!\n"); } printf("Disabled watchdog!\n"); close(wd_fd); break; } if (strspn(str, "0123456789") == strlen(str)) { // Get new feed time. num = atoi(str); if (num > 0) { wd_feed_time = num; } else { printf("Feed time can not be zero!\n"); } } else { printf("Invalid feed time!\n"); } } return 0; } |
...
Makefile (You need to modify CC path):
Code Block |
---|
CC=/home/your_home_dir/your_sp7350_project_folder/crossgcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc LDFLAGS=-lpthread .PHONY: all clean all: watchdog watchdog: watchdog.c $(CC) $< -o $@ $(LDFLAGS) clean: rm -f watchdog |
...