Project

General

Profile

Watchdog » qwatchdog.cpp

Jonathan Cormier, 10/14/2014 02:24 PM

 
/**
* \file qwatchdog.cpp
*
* \brief Keep tickling the watchdog so we don't reboot
*
* o 0
* | / Copyright (c) 2005-2012
* (CL)---o Critical Link, LLC
* \
* O
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>

#if defined (WIN32)
#elif defined (__GNUC__)
#include <linux/types.h>
#include <linux/watchdog.h>
#elif defined (_TMS320C6X)
#endif

#include "qwatchdog.h"

#if defined(__GNUC__) // linux

/**
* @brief Constructor
* @param anBarkMs Bark Rate (How often to Ping the System Watchdog)
* @param apParent QT Parent Object
*/
tcQWatchDog::tcQWatchDog(int anBarkMs, QObject* apParent)
: QObject(apParent)
, mnBarkMs(anBarkMs)
, mnFd(-1)
, mnTimerId(-1)
{
mnBarkMs = mnBarkMs ?: 10000; // do not allow 0 interval

if(!getenv("DISABLE_WATCHDOG"))
{
struct watchdog_info ident;

mnFd = ::open("/dev/watchdog", O_WRONLY);
if(0 < mnFd) // should actually end up >> 0
{
int interval = mnBarkMs*2/1000;
int status = 0;
memset(&ident, '\0', sizeof(ident));
status = ioctl(mnFd, WDIOC_GETSUPPORT, &ident);
if(0 != status)
{
qWarning("Unable to get watchdog info!:%s\n",strerror(errno));
}
else
{
qDebug("Watchdog:%s - v%08x - opts = 0x%08x\n",
ident.identity, ident.firmware_version, ident.options);
}
status = ioctl(mnFd, WDIOC_SETTIMEOUT, &interval);
if(0 != status)
{
qWarning("Unable to set watchdog timeout!:%s\n",strerror(errno));
}
interval = -1;
status = ioctl(mnFd, WDIOC_GETTIMEOUT, &interval);
if((0 == status) && (interval*1000) < (mnBarkMs*2))
mnBarkMs = interval * 500; // set WD timeout to 1/2 interval

qDebug("Watchdog timeout set to %dms [%dms requested]\n", mnBarkMs, anBarkMs);

if(0 == status)
mnTimerId = startTimer(mnBarkMs);
}
else
{
qWarning("Unable to open /dev/watchdog!:%s\n",strerror(errno));
}
}
else
{
qWarning("Watchdod disabled.. DISABLE_WATCHDOG env var set\n");
}
}

/**
* @brief Destructor
*/
tcQWatchDog::~tcQWatchDog()
{
if(-1 != mnTimerId)
killTimer(mnTimerId);
if(-1 != mnFd)
::close(mnFd);
}

/**
* @brief Sends Ping to System Watchdog
*/
void tcQWatchDog::timerEvent(QTimerEvent *)
{
//bark
int dummy = 1;

ioctl(mnFd, WDIOC_KEEPALIVE, &dummy);

}
#else

// no watchdog on windows
/**
* \brief Constructor
*
* \param anBarkMs Bark Rate (How often to Ping the System Watchdog)
* \param apParent Pointer to parent QT Object
*/
tcQWatchDog::tcQWatchDog(int anBarkMs, QObject* apParent)
: QObject(apParent)
, mnBarkMs(anBarkMs)
, mnFd(-1)
{
qWarning("No watchdog support on this platform\n");
}

/**
* \brief Destructor
*/
tcQWatchDog::~tcQWatchDog()
{
}

/**
* \brief Timer Event does nothing for Windows
*/
void tcQWatchDog::timerEvent(QTimerEvent *)
{
}
#endif // __GNUC__

#ifdef WATCHDOG_UT
#include <iostream>
#include <QStringList>
#include <QtCore/QDebug>
#include <QtCore/QCoreApplication>

class CMyApp : public QCoreApplication
{
public:
CMyApp(int ms, int argc, char** argv);
protected:
void timerEvent(QTimerEvent*);
};

CMyApp::CMyApp(int ms , int argc, char** argv)
: QCoreApplication (argc, argv)
{
printf("My App here... printing a \'.\' every %d sec\n",ms/10000);
startTimer(ms);
}
void CMyApp::timerEvent(QTimerEvent*)
{
printf(".");
fflush(stdout);
}

int main(int argc, char** argv)
{
CMyApp a(10000, argc, argv);

qDebug() << "Building watchdog...";
tcQWatchDog woof;
qDebug() << "Entering main loop... reboot comin!";
return a.exec();

}
#endif // WATCHDOG_UT
(2-2/3)