Forum Rule: Always post complete source code & details to reproduce any issue!
-
Hi Martinayotte - do you mind sharing your watchdog code? What Froeber describes in post #24 is exactly what I'm trying to achieve.
A very simple working code example would be extremely helpful that illustrates how to use the watchdog feature in this manner.
-
Hi RBrockman,
I've simply added the following startup_early_hook() and then call WatchdogReset() function periodically to avoid watchdog restarts.
#ifdef __cplusplus
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = 1000; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compa
WDOG_TOVALH = 1;
WDOG_PRESC = 0; // prescaler
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
}
#ifdef __cplusplus
}
#endif
void WatchdogReset()
{
// use the following 4 lines to kick the dog
noInterrupts();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
interrupts();
// if you don't refresh the watchdog timer before it runs out, the system will be rebooted
delay(1); // the smallest delay needed between each refresh is 1ms. anything faster and it will also reboot.
}
-
Would watchdog make more sense like this?
I really dislike delay() and it's pretty easy on a Teensy3 to set up a millisecond clock so you know when it's time to kick the dog. I've set it so it resets the watchdog every 3 milliseconds. You need to make it at least 2 as even set to 2 it can be called in 1.001 milliseconds or so if everything adds up wrong.
And even if you don't use this for a watchdog, Timer1 and Timer3 are really useful for keeping track of time if you need that.
Code:
unsigned char _watchTheDog // how many milliseconds since we last reset the watchdog
void Setup()
{
Timer3.initialize(1000000 / 1000); // set to fire every millisecond. initialize takes microseconds as an argument.
Timer3.attachInterrupt(WatchTheDog ); // call WatchTheDog every millisecond
}
void WatchTheDog ()
{
_watchTheDog+= 1
}
void WatchdogReset()
{
if (_watchTheDog> 2){
// use the following 4 lines to kick the dog
noInterrupts();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
interrupts();
_watchTheDog = 0
}
}
-
What are the units of these two values and how do they translate into time?
WDOG_TOVALL = 1000; // The next 2 lines sets the time-out value.
WDOG_TOVALH = 1;
I've implemented this and it is resetting about every 60 seconds with these values above. I want to set this to a value less than 1 second - actually in microseconds if possible.
Is there a minimum amount of elapsed time required between calls to kick the dog?
Last edited by rbrockman; 09-18-2014 at 10:06 PM.
-
Thanks Martinayotte!
How do you start/enable the watchdog after a period of time in your code? Like after completing setup()
-
Please provide input on the code below. There are still a few watchdog items here I do not have an understanding of as of yet, but the code seems to be more or less working.
Goal: Start a watchdog when the Teensy first runs with a long timeout value, then after setup() change the timeout to a much smaller timeout period. Kick the dog more often than the timeout period.
Code:
#ifdef __cplusplus
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = 2000; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compares itself to
WDOG_TOVALH = 0;
WDOG_PRESC = 0; // prescaler
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
}
#ifdef __cplusplus
}
#endif
void setup(){
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
WDOG_TOVALL = 10; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compares itself to
WDOG_TOVALH = 0;
WDOG_PRESC = 0; // prescaler
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
}
void loop(){
WatchdogReset();
}
void WatchdogReset(){
static elapsedMillis watchdogTimer;
if (watchdogTimer > 5){
watchdogTimer = 0;
noInterrupts();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
interrupts();
}
}
-
Hello forum,
as far as I see, you use different approaches to simulate a watchdog behavior.
I am not to sure about the work of an interrupt watchdog.
Does it only work if the teensy hangs due to infinite (or to long) loops
or does it also works, if the teensy hangs for no obvios reason.
I use a teensy3.1 with an MFRC522 door reader and there are no "bad loops" inside.
The program works fine for days, sometimes weeks, sometimes months, but
somtimes it just stops working (and I have to go to that place an open the door with a key...)
When switching the teensy off and on again, everything is fine and it starts working for the next
unsure period of time.
A watchdog would be great, but would an interrupt watchdog prevent the teensy from these
types of chrashes?
If yes, which is the best approach for this?
I would love to keep the .c file unchanged...
If no, what would you reccomend? An oldfashioned 555 circuit?
Thanks for your help
Roland
-
Hello duff
Great and working code, but where in Your code is definition of 6 second delay ?
Max
-
The idea of a watchdog is that your app will "and" together several conditions and states to know whether to reset the watchdog timer.
-
Senior Member
There are a number of external watchdog ICs, with programmable or fixed reset windows. I personally have used the ADM706SANZ with Teensy, which gives you a 1.6s reset window. You could also use a STM6321S or TPS3828-33DBVT.
I've also made a simple external watchdog with programmable delay by using a NE556 timer IC. I can share the schematic and workings if you like.
-
Senior Member

Originally Posted by
Max
Hello duff
Great and working code, but where in Your code is definition of 6 second delay ?
Max
I haven't actually used the watchdog since posting that so I'll have to look at it again and get back to you.
-

Originally Posted by
rbrockman
What are the units of these two values and how do they translate into time?
WDOG_TOVALL = 1000; // The next 2 lines sets the time-out value.
WDOG_TOVALH = 1;
I've implemented this and it is resetting about every 60 seconds with these values above. I want to set this to a value less than 1 second - actually in microseconds if possible.
Is there a minimum amount of elapsed time required between calls to kick the dog?
WDOG_TOVALH and WDOG_TOVALL are the high and low, respectively, registers for the 32-bit timeout value of the watchdog timer. This must be at least 4 cycles. WDOG_PRESC is the 3 bit, at bit 8-10 for some reason, prescaler which divides the watchdog clock by 1 + the three bit prescale value. The watchdog clock is running at 1kHz as far as I can tell. So, to get a WDT of 3 seconds you'd use WDOG_TOVALH = 0, WDOG_TOVALL = 3000 and WDOG_PRESC = 0.
With your values there of VALH = 1 and VALL = 1000 you should get a WDT of about 1<<16+1000 = 66536 ms which from what you say sounds reasonable.
To sum up, the final WDT in milliseconds will be (VALH<<16 + VALL) * (1 + PRESC >> 8).
-
Watchdog stopped working with Teensy V1.27 - solved
Thanks to everyone that contributed to this topic. I had a strange experience with the watchdog today, and am posting in the hope that it helps someone else. I've had the watchdog working well for quite some time with Arduino 1.6.5-r2 and Teensyduino V1.24, but when I transitioned to Arduino 1.6.5-r5 and Teensyduino V1.27, the sketches with watchdog would just hang. I found out that the watchdog was what was causing the problem - commenting out startup_early_hook() would get it working again. I then found that I had to make the watchdog period longer in order to get the sketch working again. My guess is that the new Teensyduino code takes longer to get to setup() than the old one. I have the watchdog reset as the first statement in setup(), and I found that I had to increase WDOG_TOVALL to 259 in order to get it to work OK. 258 causes it to hang. I'm guessing from the post above, that this is 259ms watchdog. I was trying to minimize this, so that if the program does ever hang, the watchdog would reset it as quickly as possible. I'm using "72MHz Optimized" as the CPU speed selection in the Arduino IDE.
#ifdef __cplusplus
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = 259; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compa
WDOG_TOVALH = 0;
WDOG_PRESC = 0; // prescaler
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
}
#ifdef __cplusplus
}
#endif
-
Member
Does this work on teensy 3.6?
-
Senior Member
It should work on 3.6. The watchdog hardware is identical. Please give it a try and let us know if it works for you?
-
Member
No problem. I am a bit of a noob in programming so ppeas can you tell me what code to use? Post #31?
Thank you
-
Member
tried the watchdog today... It works
but like someone else said i can't figure out the time interval.. i used this code for testing
Code:
#ifdef __cplusplus
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = 3000;
WDOG_TOVALH = 0;
WDOG_PRESC = 0;
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN);
}
#ifdef __cplusplus
}
#endif
int led = 13;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
Serial.println("Setup");
}
void loop() {
WatchdogReset();
Serial.println("Begin");
delay(2608);
}
void WatchdogReset(){
static elapsedMillis watchdogTimer;
if (watchdogTimer > 5){
watchdogTimer = 0;
noInterrupts();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
interrupts();
}
}
when the delay(2608); the sketch runs but when i use delay(2609); the watchdog kicks in. I expected a 3 sec reset time... But all and all this works for me .. I don't need accurate timing, just a reset if the code hangs 
Thank you!
-
Senior Member+

Originally Posted by
Tady
when the delay(2608); the sketch runs but when i use delay(2609); the watchdog kicks in. I expected a 3 sec reset time... But all and all this works for me .. I don't need accurate timing, just a reset if the code hangs

Thank you!
If your teensy 3* watchdog timer is configured to use the LPO, that internal oscillator is spec'd only at 10% accuracy (100,000 ppm). Using the LPTMR, i've measured the accuracy of LPO on various teensy's (anecdotal results at https://github.com/manitou48/crystal...r/crystals.txt). I tested my T3.2 with LPO accuracy of 18934 ppm with the watchdog timer. I modified the BasicUsage example from https://github.com/adafruit/Adafruit_SleepyDog to adjust the delay before "kicking the watchdog" in loop().
Code:
if (micros() -t > 3927000) {
Watchdog.reset();
t=micros();
Serial.println("running");
}
If i wait longer the 3.927 seconds, the teensy resets. if i wait less than 3.926 secs to kick the dog, then reset is avoided. That timing roughly agrees with measured LPO accuracy for that T3.2. The LPO accuaracy will vary from chip to chip and with temperature.
2nd test: T3.6 (LPO drift of -3232 ppm). If wait less than 4.011 secs, then reset is avoided.
Last edited by manitou; 04-06-2017 at 12:42 PM.
-
Senior Member+

Originally Posted by
duff
Here is more portable version of your watchdog code, no need to edit any core files but instead use the startup_early_hook. It also uses the interval timer to kick the dog.
Code:
#define RCM_SRS0_WAKEUP 0x01
#define RCM_SRS0_LVD 0x02
#define RCM_SRS0_LOC 0x04
#define RCM_SRS0_LOL 0x08
#define RCM_SRS0_WDOG 0x20
#define RCM_SRS0_PIN 0x40
#define RCM_SRS0_POR 0x80
#define RCM_SRS1_LOCKUP 0x02
#define RCM_SRS1_SW 0x04
#define RCM_SRS1_MDM_AP 0x08
#define RCM_SRS1_SACKERR 0x20
IntervalTimer wdTimer;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
// You have about 6 secs to open the serial monitor before a watchdog reset
while(!Serial);
delay(100);
printResetType();
wdTimer.begin(KickDog, 500000); // kick the dog every 500msec
}
void loop() {
Serial.println("doing loop things...");
delay(100);
}
void KickDog() {
Serial.println("Kicking the dog!");
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
noInterrupts();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
interrupts();
}
void printResetType() {
if (RCM_SRS1 & RCM_SRS1_SACKERR) Serial.println("[RCM_SRS1] - Stop Mode Acknowledge Error Reset");
if (RCM_SRS1 & RCM_SRS1_MDM_AP) Serial.println("[RCM_SRS1] - MDM-AP Reset");
if (RCM_SRS1 & RCM_SRS1_SW) Serial.println("[RCM_SRS1] - Software Reset");
if (RCM_SRS1 & RCM_SRS1_LOCKUP) Serial.println("[RCM_SRS1] - Core Lockup Event Reset");
if (RCM_SRS0 & RCM_SRS0_POR) Serial.println("[RCM_SRS0] - Power-on Reset");
if (RCM_SRS0 & RCM_SRS0_PIN) Serial.println("[RCM_SRS0] - External Pin Reset");
if (RCM_SRS0 & RCM_SRS0_WDOG) Serial.println("[RCM_SRS0] - Watchdog(COP) Reset");
if (RCM_SRS0 & RCM_SRS0_LOC) Serial.println("[RCM_SRS0] - Loss of External Clock Reset");
if (RCM_SRS0 & RCM_SRS0_LOL) Serial.println("[RCM_SRS0] - Loss of Lock in PLL Reset");
if (RCM_SRS0 & RCM_SRS0_LVD) Serial.println("[RCM_SRS0] - Low-voltage Detect Reset");
}
#ifdef __cplusplus
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = (1000); // The next 2 lines sets the time-out value. This is the value that the watchdog timer compare itself to.
WDOG_TOVALH = 0;
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN); // Enable WDG
//WDOG_PRESC = 0; // prescaler
}
#ifdef __cplusplus
}
#endif
Re: startup_early_hook()
i get a compile error if i try to compile Duff's watchdog sketch in post #21 ?? what is proper way to override weak startup_early hook?
Code:
sketch_apr09a: In function 'void startup_early_hook()':
sketch_apr09a:58: error: previous declaration of 'void startup_early_hook()' with 'C++' linkage
void startup_early_hook() {
^
sketch_apr09a:58: error: conflicts with new declaration with 'C' linkage
void startup_early_hook() {
^
previous declaration of 'void startup_early_hook()' with 'C++' linkage
i'm using 1.8.1 with 1.35
-

Originally Posted by
manitou
Re:
startup_early_hook()
i get a compile error if i try to compile Duff's watchdog sketch in post #21 ?? what is proper way to override weak startup_early hook?
Code:
sketch_apr09a: In function 'void startup_early_hook()':
sketch_apr09a:58: error: previous declaration of 'void startup_early_hook()' with 'C++' linkage
void startup_early_hook() {
^
sketch_apr09a:58: error: conflicts with new declaration with 'C' linkage
void startup_early_hook() {
^
previous declaration of 'void startup_early_hook()' with 'C++' linkage
i'm using 1.8.1 with 1.35
The Arduino preprocessor is a buggy piece of <CENSORED>. You need an explicit forward declaration:
Code:
#ifdef __cplusplus
extern "C" { void startup_early_hook(); }
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = (1000); // The next 2 lines sets the time-out value. This is the value that the watchdog timer compare itself to.
WDOG_TOVALH = 0;
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN); // Enable WDG
//WDOG_PRESC = 0; // prescaler
}
#ifdef __cplusplus
}
-
Senior Member+

Originally Posted by
tni
The Arduino preprocessor is a
buggy piece of <CENSORED>. You need an explicit forward declaration:
Thanks! like I would have guessed that.
Here is a variation on Duff's sketch in the spirit of SleepyDog lib BasicUsage example that kicks the watchdog a few times and then lets teensy 3* reset
https://github.com/manitou48/teensy3...r/wdogduff.ino
-
Hello, I have followed this thread and it is confusing. Is there a final answer on how to implement a watchdog on teensy 3.2 ?
-
Senior Member+

Originally Posted by
trichins
Hello, I have followed this thread and it is confusing. Is there a final answer on how to implement a watchdog on teensy 3.2 ?
Did you try the wdogduff.ino sketch in post #46 ?
-

Originally Posted by
manitou
Did you try the wdogduff.ino sketch in post #46 ?
Thanks, that seems to summarize what has been posted. I will try it
-
Senior Member
Some time ago I ported Adafruit's SleepyDog library. So if you'd like to avoid the complexity of directly accessing the watchdog, just use that library. Try it's BasicUsage example to get started.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules