How can I change the timeout value and kick watchdog on Jetson TX1?

Hi.

I am trying to use watchdog timer on Jetson TX1.

Firstly, I tried following sample code after setup TX1 by JetPack for L4T 2.1, but it did not work.

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>

int main (void) {
	int fd, ret;
	int timeout = 0;
 
	/* open WDT0 device (WDT0 enables itself automatically) */
	fd = open("/dev/watchdog0", O_RDWR);
	if(fd < 0) {
		fprintf(stderr, "Open watchdog device failed!\n");
		return -1;
	}
	/* WDT0 is counting now,check the default timeout value */
	ret = ioctl(fd, WDIOC_GETTIMEOUT, &timeout);
	if(ret) {
		fprintf(stderr, "Get watchdog timeout value failed!\n");
		return -1;
	}
	fprintf(stdout, "Watchdog timeout value: %d\n", timeout);
 
	/* set new timeout value 60s */
	/* Note the value should be within [5, 1000] */
	timeout = 60;
	ret = ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
	if(ret) {
		fprintf(stderr, "Set watchdog timeout value failed!\n");
		return -1;
	}
	fprintf(stdout, "New watchdog timeout value: %d\n", timeout);
 
	/*Kick WDT0, this should be running periodically */
	ret = ioctl(fd, WDIOC_KEEPALIVE, NULL);
	if(ret) {
		fprintf(stderr, "Kick watchdog failed!\n");
		return -1;
	}
}

Then, setup TX1 again by building the NVIDIA kernel according to “Tegra Linux Driver Package Development Guide”.
I set kernel configuration as follows:

CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_CORE=y
# CONFIG_WATCHDOG_NOWAYOUT is not set

#
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_SOFT_PLATFORM_WATCHDOG=y
CONFIG_TEGRA_WATCHDOG=y
CONFIG_MAX77620_WATCHDOG=y
# CONFIG_ALIM7101_WDT is not set
# CONFIG_I6300ESB_WDT is not set

#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set

But, “WDIOC_GETTIMEOUT” and “WDIOC_SETTIMEOUT” shows error “operation not supported”.
And it seems that “WDIOC_KEEPALIVE” does not work, so TX1 reboot after 120 seconds.

I have tried changing kernel source (tegra_wdt.c) as follows:

-static int heartbeat = 120;
+static int heartbeat = 10;

The timout value does not change, either.

How can I change the timeout value and kick WDT?

The kernel version is 3.10.67, and it is able to kick and close WDT by the following way.

# tail -f /dev/watchdog0   // open wdt
# echo 1 > /dev/watchdog0  // kick wdt
# echo V > /dev/watchdog0  // close wdt

Can anyone help me?

Thanks.

I don’t know enough about this to offer any big insight, but realize that when ioctl says operation not supported it implies the driver supporting the device special file does not support that operation. In the case of watchdog there can be multiple drivers involved depending on what the watchdog looks at. The kernel docs mention that all drivers supporting ioctl must support WDIOC_KEEPALIVE, and so WDIOC_SETTIMEOUT is optional…and dependent upon the specific driver the watchdog is for. So the answer as to what will or won’t work depends upon the driver design behind the ioctl call.

Thank you for your reply.

I didn’t know WDIOC_SETTIMEOUT is optional.
It is strange thant the driver does not support this option although it is written in the official guide.

Should I make a change to the drivers?

I do not know anything about what any particular driver implements. If a driver does not implement that ioctl then you’d have to actually alter the source code of the driver to change this (there wouldn’t be any config option to change in the kernel for a particular driver).

Ktsrn, The program seems working on my side. What’s the issue you’re facing?

I have following probrems.

  1. cannot change the default timeout value by changing heartbeat in kernel source "tegra_wdt.c"
  2. cannot get the timeout value by "ioctl(fd, WDIOC_GETTIMEOUT, &timeout)"
  3. cannot set the timeout value by "ioctl(fd, WDIOC_SETTIMEOUT, &timeout)"
  4. cannot kick WDT by "ioctl(fd, WDIOC_KEEPALIVE, NULL)"

I get the error message “operation not supported” for 2 & 3.
There is no error message for 4, but TX1 reboot after 120 seconds.

It is able to kick by using “tail” and “echo” command, so I want to solve at least probrem 1.

Thanks.

All these are working on my side. I tried on two DevKits with R24.1/R24.2.

Did you possible try on Ubuntu 16.04?

I think that the target OS version of R24.1/R24.2 is Ubuntu 16.04.
But I need to use Ubuntu 14.04 due to requirement of middleware.

p.s.
The writer of following topic is me.
https://devtalk.nvidia.com/default/topic/975867/?comment=5019418
I apologize my mistake.

Although R24.1 and R24.2 use the same kernel the default config is different. I am unsure of other differences, but this might explain why the ioctl works on one but not the other. Also I think R24.1 is Ubuntu 14 and the transition to R24.2 was when Ubuntu 16 was used (also R24.1 has an optional 32-bit sample rootfs, but most people would be using 64-bit on R24.1).

hello ktsrn,

here is trial patch to WAR the system reboot issue for your reference.

diff --git a/arch/arm64/configs/tegra21_defconfig b/arch/arm64/configs/tegra21_defconfig
index 6b51b2d..1663448 100644
--- a/arch/arm64/configs/tegra21_defconfig
+++ b/arch/arm64/configs/tegra21_defconfig
@@ -339,7 +339,6 @@ CONFIG_PWM_FAN=y
 CONFIG_MAX77620_THERMAL=y
 CONFIG_TRUSTY=y
 CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_SOFT_PLATFORM_WATCHDOG=y
 CONFIG_TEGRA_WATCHDOG=y

Thank you for your reply.

I confirmed again “tegra21_defconfig”, but there was no description according to “CONFIG_TRUSTY=y”.
I’m assuming the target kernel of this patch is R24.1/R24.2.
Do I need to add this option?

hello ktsrn,

no, you don’t. you should able to WAR the system reboot issue by disabling CONFIG_WATCHDOG_NOWAYOUT.
thanks