Project

General

Profile

Using Watchdog » watchdog.cpp

Jonathan Cormier, 10/14/2014 03:43 PM

 
1
#include "watchdog.h"
2
#include <sys/ioctl.h>
3
#include <sys/types.h>
4
#include <sys/stat.h>
5
#include <fcntl.h>
6
#include <string.h>
7
#include <unistd.h>
8
#include <stdio.h>
9
#include <linux/watchdog.h>
10

    
11
using namespace MityDSP;
12

    
13
/**
14
 *  Constructor for the watchdog abstraction
15
 *
16
 *  \param apDevice filename of device (defaults to /dev/watchdog)
17
 */
18
tcWatchdog::tcWatchdog(const char* apDevice)
19
: mnMask(0)
20
, mnSet(0)
21
, mnFd(-1)
22
{
23
	sem_init(&mhSem, 0, 1);
24
	mpFileName = new char[strlen(apDevice)+1];
25
	strcpy(mpFileName, apDevice);
26
}
27

    
28
/**
29
 *  Destructor.  Shuts down running watchdog.  cleans up resources.
30
 */
31
tcWatchdog::~tcWatchdog(void)
32
{
33
	const char *no_reboot = "V\n";
34
	if (mnFd >= 0)
35
	{
36
		printf("shutting down watchdog\n");
37
		write(mnFd,no_reboot,strlen(no_reboot));
38
		close(mnFd);
39
	}
40
	delete [] mpFileName;
41
	sem_destroy(&mhSem);
42
}
43

    
44
/**
45
 *   Enable the watchdog.  This should typically be
46
 *   called after at least 1 checkpoint has been registered
47
 *   and the application is ready for the watchdog operation
48
 *   to begin.
49
 *
50
 *   \param TimeoutSecs number of seconds before watchdog timeout
51
 *   \return non-zero on error.
52
 */
53
int tcWatchdog::StartWatchDog(int TimeoutSecs)
54
{
55
	mnFd = open(mpFileName, O_RDWR);
56
	if (mnFd < 0)
57
	{
58
		perror("open watchdog:");
59
		return mnFd;
60
	}
61
	// NOTE: L138 watchdog driver doesn't support WDIOC_SETTIMEOUT.
62
	//  Timeout defaults to 60 seconds
63
	ioctl(mnFd,WDIOC_SETTIMEOUT,&TimeoutSecs);
64
	return 0;
65
}
66

    
67
/**
68
 *  Register a checkpoint.  The tcWatchdog class supports multiple
69
 *  checkpoints (or threads, etc.) that must Checkin() prior to the
70
 *  watchdog being tagged.  This routine generates a handle for a 
71
 *  newly registered checkpoint.
72
 *
73
 *  \return handle to use for Checkin() or -1 on failure.
74
 */
75
int tcWatchdog::RegisterCheckpoint(void)
76
{
77
	int i, mask;
78
	int rv = -1;
79
	sem_wait(&mhSem);
80
	/* find next available slot in mask */
81
	for (i = 0, mask=1; i < 31; i++, mask<<=1)
82
	{
83
		if (!(mask & mnMask))
84
		{
85
			mnMask |= mask;
86
			rv = mask;
87
			break;
88
		}
89
	}
90
	sem_post(&mhSem);
91
	return rv;
92
}
93

    
94
/**
95
 *  Remove a registered checkpoint from the monitor list.
96
 *  \param handle the checkpoint previously from RegisterCheckpoint
97
 *  \return non-zero on error.
98
 */
99
int tcWatchdog::UnRegisterCheckpoint(int handle)
100
{
101
	int rv = -1;
102
	sem_wait(&mhSem);
103
	if (handle & mnMask)
104
	{
105
		mnMask &= ~handle;
106
		rv = 0;
107
	}
108
	sem_post(&mhSem);
109
	return rv;
110
}
111

    
112
/**
113
 *  Check in for the watchdog update.  When all registered 
114
 *  methods have checked in, the watchdog timer will be
115
 *  tagged/reset.
116
 *
117
 *  \param Checkpoint checkpoint handle from RegisterCheckpoint
118
 *
119
 *  \return non-zero on error.
120
 */
121
int tcWatchdog::Checkin(int Checkpoint)
122
{
123
	if (mnFd < 0)
124
		return -1;
125

    
126
	sem_wait(&mhSem);
127
	mnSet |= Checkpoint;
128
	if (mnSet == mnMask)
129
	{
130
		/* tag watchdog */
131
		mnSet = 0;
132
		ioctl(mnFd, WDIOC_KEEPALIVE, 0);
133
	}
134
	sem_post(&mhSem);
135

    
136
	return 0;
137
}
138

    
139
#ifdef WATCHDOG_MAIN
140
int main()
141
{
142
	tcWatchdog watch;
143
	int watchHandle;
144

    
145
	printf("Starting watchdog! Timeout interval 60s.\n");
146
	watch.StartWatchDog(60000);
147
	watchHandle = watch.RegisterCheckpoint();
148

    
149
	while (1 == 1)
150
	{
151
		printf(".");
152
		fflush(stdout);
153

    
154
		// Tickle watchdog
155
		watch.Checkin(watchHandle);
156
		// Sleep 1 second
157
		sleep(1);
158
	}
159

    
160
	return 0;
161
}
162
#endif
(5-5/7) Go to top
Add picture from clipboard (Maximum size: 1 GB)