I don't much about how watchdog timer works in embedded environment and I am facing issue related to watchdog timer
Maximum time out value defined in one of the macro is 55 and when we try to set up this value from watchdog_set_period function ,our board is getting reboot
#define Max_time_out 55
watchdog_set_period(int period) // Set watchdogs timeout counter
where period = 55
Now is it something expected or how what is the reason for reboot
We are writing this period value to some driver which we are accessing through file descriptor.
The link states this description on watchdog timers.
A watchdog timer is a piece of hardware that can be used to automatically detect software anomalies and reset the processor if any occur. Generally speaking, a watchdog timer is based on a counter that counts down from some initial value to zero. The embedded software selects the counter's initial value and periodically restarts it. If the counter ever reaches zero before the software restarts it, the software is presumed to be malfunctioning and the processor's reset signal is asserted. The processor (and the embedded software it's running) will be restarted as if a human operator had cycled the power.
You haven't posted the code so we can't judge what exactly is the problem. If you have written the code check if your code is causing any problems which is causing the watch dog timer to reset.
A watchdog timer is a special kind of timer usually found on embedded systems that is used to detect when the running software/firmware is hung up on some task. The watchdog timer is basically a countdown timer that counts from some initial value down to zero.
When zero is reached, the watchdog timer understands that the system is hung up and resets it.
Therefore, the running software must periodically update the watchdog timer(in a infinite while loop) with a new value to stop it from reaching zero and causing a reset. When the running software is locked up doing a certain task and cannot update(refresh fails) the watchdog timer, the timer will eventually reach zero and a reset/reboot will occur.
So in summary, if you enable watchdog timer then you need to periodically refresh watchdog timer. Otherwise the board reboots when the watchdog timer expires.
Related
I have a conceptual question, I'm currently working on a project that have to implement a watchdog timer to ensure that the code works properly, I'm using a STM32F4, from the datasheet I can see that the max timeout allow by the IWDG (independent Watchdog) is 32768 ms, I'm using a SIM800L for communication via GPRS, so some communications take longer than that, during this process the UC is busy waiting for the answers, so it cannot reset the IWDG, so I was thinking on deactivating the Watchdog in those parts, or implement my own watchdog whit a timer and a simple reset function so can make longer timeout periods.
My question is:
Is this a sign of a flaw on my code design? Should I instead adapt my code to reset the IWDG every 30 seconds or so and never deactivate it? Is implementing my own WDG with a timer bad practice?
¿is this a sign of a flaw on my code design?,
¿should instead adapt my
code to renew the IWDG every 30 seconds or so?
No, you simply need to write the key register or load a new value to the downcounter before the downcounter reaches zero. It shows the watchdog that your software is alive and no reset is needed.
during this process the UC is busy waiting for the answers, so it
cannot reset the IWDG
This means that your implementation is bad. You need to implement it non-blocking way. It is not dificult.
¿implementing my own
WDG whit a timer is a bad practice?
It is a very bad idea. What will happen if your program hardfault? Your own watchdog will be useless. Hardware WDG is also clocked from its one clock source - so if your program does something wrong with the clocks - it will still work.
Programs should never deactivate the watchdog in run-time, as that defeats the purpose of having a watchdog in the first place. Many watchdog hardware peripherals don't even allow you to disable it once enabled.
You cannot implement your own watchdog using timers, because the watchdog hardware is explicitly using a different timer than what's available to the application programmer. So if your program halts for whatever reason, your timer solution will halt as well. Forget about implementing watchdogs using on-chip timers or software. You can only implement your own watchdog using a external hardware, such as a binary counter IC or monostable multivibratior IC.
Is this a sign of a flaw on my code design?
It is - you should not busy-wait for external resources to become available. Rather than
while(some_serial_bus == BUSY) {} // bad, busy wait
you should be doing:
for(;;)
{
kick_wdog();
if(some_serial_bus != BUSY) // good, polling
{
do_stuff();
}
}
When implementing the driver for the external serial bus you should provide a method to check if data is available, then allow the caller to decide whether to busy wait for that function or not. An ideal, properly written driver should never contain any busy waits nor should it contain any "sleep/delay" calls.
I don't think you can stop the IWDG once it starts (nor would you want to). I'm not familiar with the SIM800L, but your best bet would be to find a way to kick the watchdog intermittently while GPRS is operating. You want to do this in firmware, not hardware. (Don't use a HW timer to kick the WDT because if your SW crashes, the HW timer could keep doing its thing.) Alternatively, the STM32F4 also as a window watchdog (WWDG) timer you could use. You might be able to configure longer window times with the WWDG.
I am working with Cortex M3 ARM processor.So, I have a main loop like this;
while(true){
foo();
System_Watchdog_Refresh();
__ASM("wfe");//System wait for event...
}
So, manufacturer company said to me this;
If you don't want to reset your program from wdt(Watchdog Timer), you should set a empty timer ISR for every 1 ms.
There is problem for me here because ı have used "System_Watchdog_Refresh();" function and yeah processor running this function every loop.How watchdog timer reset the processor in this state?
Note that:
System_Watchdog_Refresh(): Reset wdt timer
Wdt can't be disable
foo() function doesn't matter for this state
When ı remove "__ASM("wfe");" processor doesn't reset from wdt
Thank you...
WFE sets the processor to standby until the next interrupt (or event). So even though you refresh the watchdog, the processor goes to sleep immediately after that and in the absence of any other events, stays in that state until the watchdog expires and resets the processor. To prevent that, you will need something that periodically triggers an interrupt (like an empty timer that the manufacturer suggests) to ensure the processor wakes up and resumes execution, thereby also refreshing the watchdog.
The timer interval should be something reasonably close to, but much less than, the watchdog timeout to ensure you get the ideal mix of power-saving and reliability.
(Moved my comments to an answer, since the OP says it works for him.)
I am working with a STM8 timer (not my code, but maintaining it) and in it it uses a timer. Apparently the clock is set at 16MHz erfo 0.0625uS. The settings of the timer are ARRH=0x03 ARRL=0x20 therefore (0x0320=800) it resets at 800 (ergo 50us)
PSCR is set at 0 so the timer has the same freq as the micro.
Anyway, when checking this with an oscilloscope, it does not give good readings.
The timer interrupt is called at:
56us , 54uS, 54uS, 52uS, 52uS, 52us, 38us(!!!), 42us(?), 50us, 50us....
curiosly summed up it gives 500uS so it does count as 10 times 50uS
The first 8 times at the timer interrupt some AD conversion is happening so there is the possibility that an AD interrupt is being called in between too.
1) Do you think this is affecting the frequency of the timer?
2) why does it "correct" itself by firing an interrupt at 38uS??
I would appreciate any comment based on your embedded or STM8 experience, since I know precise answers would need to examine the code...
I'm not sure if you still need an answer. I once had the same and searched for a long time... simple solution in my case:
I had an ADC ISR with high jitter. That came from my main loop. In some sub-sub-sub routine the ADC interrupt was temporarily deactivated for a critical section (data transfer between interrupt and main loop context). The effect is exactly what you discribe:
Sometimes the time between two interrupts is longer, because the interupt is pending and waiting for execution until the interrupt is enabled again. The timer is still continuing to run. Timing example:
interrupt is disabled in main loop (or sub routine)
interrupt flag is set by timer -> interrupt pending
interrupt is enabled again -> ISR is executed too late
interrupt is disabled in main loop
interrupt flag is set by timer -> pending
interrupt is enabled again -> ISR is executed much too late
main loop does NOT disable interrupt for some case (maybe by control flow, maybe timing issue)
The next interrupt is executed at the right time which is 50 us after raising the last interrupt, NOT 50 us after calling the last ISR. --> time between ISR calling is shortened.
I hope I could help.
I'm working on an embedded project that's running on an ARM Cortex M3 based microcontroller. Some code provided by our vendor uses a delay function that sets up built-in hardware timer and then spins until the timer expires. Typically this is used to wait between 1 and a couple hundred microseconds. These delays are almost because they are waiting on some register, chip or bus to complete an action and need to wait at least the given number of microseconds. The hardware timer also appears to cost at least 6 microseconds in overhead to setup.
In a multithreaded environment this is a problem because there are N threads but only 1 hardware timer. I could disable interrupts while the timer is being used to prevent context switches and thus race conditions but it seems a bit ugly. I am thinking of replacing the function that uses the hardware timer with a function that uses the ARM CPU Cycle Counter (CCNT). Are there are pitfalls I am missing or other alternatives? Obviously the cycle counter function requires it be tuned to the proper CPU frequency which will never change for our system, but I suppose could be detected at boot programmatically using the hardware timer.
Setup the timer once at startup and let the counter run continuously. When you want to start a delay, read the counter value and remember this start value. Then in the delay loop read the counter value again and loop until the counter value minus the start value is greater than or equal to the requested delay ticks. (If you do the subtraction correctly then rollovers will wash out and you don't need special handling to check for them.)
You could multiplex your timer such that you have a table of when each thread wants to fire off and a function pointer / vector for execution. When the timer interrupt occurs, fire off that thread's interrupt and then set the timer to the next one in the list, minus elapsed time. This is what I see many *nix operating systems do in their kernel code, so there should be code to pull from as example.
A bigger concern is the fact that you are spin locking the thread waiting for the timer. Besides CPU usage, and depending on what OS you have (or if you have an OS) you could easily introduce thread inversion issues or even full on lock ups. It might be better to use thread primitives instead so that any OS can actually sleep your threads and wake them when needed.
I am writing an preemptive kernel in C and assembly. I've been looking at and setting up timer interrupts through the PIT and the PIC but one thing I am utterly unable to find an answer on.
We have initilized the 8254 chip to be counting on counter 0 in mode 2. We set it to fire an interrupt on IR0 on the PIC every 10 ms. After that we enable the IR0 on the PIC and things work as intended.
However lets say at certain conditions we want to alter the time that the PIT fires at by feeding it a new value. Or just restart the counter midcounting.
The intel manual for the chip has some detail on the gate and using it to restart the counter by getting a rising edge on the gate.
THe manual also says that if we give the counter a new value it doesn't reset the counter until after the current counting sequence is finished unless a trigger (rising edge on the gate) happens before the counting is over.
The manual also says that sending a new CW to the chip would reset the counter, however I don't believe this is the optimal way of restarting or altering the counter.
So the question is, how would this be done in either c or assembly? (We got full write access whenever we want).
To not leave a question unanswered and as I've somewhat of an answer I'll answer it myself.
As far as I've understood the chip has 3 counters but only counter 2 (we start counting at 0) has the gate pin connected (and this one has it connected to the speaker). As a result counter 0 which is the real timer counter doesn't have a connection on the gate which means we can't cause a trigger on it after sending it a new value.
This means that sending a value to it and then restarting it on the value before the timer is up is impossible without sending it new ICW.
In case we want to reset the timer when we get out of an interrupt caused by the 8259 chip which the 8254 is connected to at the end of the handling of that interrupt (that is we don't want the time to be running during the actual interrupt) we would be best of changing the mode to mode 0 which doesn't restart the timer on terminal count and then just manually restart it with the time we want to use for it each time we are about to end and interrupt.