Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

The goal of the document is to illustrate how to use watchdog of SP7350.

Contents of Table

1. Check if watchdog device exists

1.1 Check watchdog devices in /dev/

Pleae use 'ls /dev/watchdog*' command to check if watchdog devices exist. Normally, you will find two watchdog devices as shown below:

~ # 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 not exist, you need check:

Check If watchdog node in dts is not “disabled”.

Check if watchdog driver is enabled.

1.2 Check if watchdog node in dts is not “disabled”

Refer to watchdog node in dts:

&watchdog {
  timeout-sec = <10>;
};

1.3 Check if watchdog driver is enabled

To check if watchdog driver is enabled, please run 'make kconfig' to in project top directory. When configuration menu pops up, move cursor to “Device Drivers > Watchdog Timer Support > Sunplus watchdog support” and make sure “Sunplus watchdog support” is enabled. Refer to Linux kernel configuration menu below:

2. Run watchdog setup and feeding application

Refer to the following C example code of watchdog setup and feeding application. The application setups, starts, and then feeds watchdog every 12 seconds. The maximum time-out time of watchdog of SP7021 have no limit.

watchdog.c

#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;
}

Reference Makefile (You need to modify CC path):

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

 

  • No labels