I develop a project on the K10 chip and use the software watchdog to detect 'system running', and then I met with the following strange issue:
I feed the wdog periodically, but the MCU still reset after running for a short time.
Watchdog is set as follows, can anyone check if it's right :
static void wdog_unlock(void)
{
DisableInterrupts;
WDOG_UNLOCK = 0xC520;
WDOG_UNLOCK = 0xD928;
EnableInterrupts;
}
void wdog_init(void)
{
wdog_unlock();
WDOG_PRESC = 0x0400;
WDOG_TOVALH = 0x01c9; /*timer out is 3s*/
WDOG_TOVALL = 0xc380;
WDOG_STCTRLH = 0x01D3;
}
void wdog_feed(void)
{
wdog_unlock();
WDOG_PRESC = 0x0400;
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
}
The place I feed the watchdog is:
void pvPollingThread()
{
if( eMBPoll( ) != MB_ENOERR )
break;
wdog_feed();
}
It's a polling thread, and every 2 seconds, the MCU will receive a message, then go handle the event (cost about 100 milli seconds). Otherwise, it'll go into the next loop.
I use oscillograph to detect the wdog_feed frequency. When no events need to be handled, the wdog is feed after several microseconds; when event occurs, the wdog is feed after several milli-seconds. Thus, wdog is not feed at a fixed frequency( first short interval ,then long interval, but all within 1s, less than the required 3s ). Does it matter?
When no events need to be handled, the wdog is always feed at a high frequency, the MCU won't reset.
已解决! 转到解答。
Hi
The watchdog feed sequence should be:
DisableInterrupts;
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
EnableInterrupts;
Regards
Mark
Yanli
You ONLY need to use the unlock sequence when writing configuration changes to the wathdog, but you DO need to protect the sequence again interrupts.
An interrupt occuring between the two refresh writes will require 22 clock cycles to save and restore the stack, or 56 if it has an FPU. Assuming your bus clock is half your core clock, and you don't use a part with FPU, you don't need to disable interrupts as long as you:
- have only one interrupt routine that can ever occur
- this interrupt routine requires less that 18 clock cycles to complete
Otherwise you need it - unless you can accept your product having a high probability of resetting each time you service its watchdog (as you already have seen).
Regards
Mark
Hi, Mark:
From your explanation, you mean that:
(1) "feed the watchdog" doesn't belong to "writing configuration changes to the watchdog", so I needn't do the 'unlock' process.
(2) When I "feed the watchdog" (write 2 different values to WDOG Refresh Register), interrupt will produce and cost more than "20 bus clock". So I need "DisableInterrupts" first. The feed dog sequence should be as you mentioned above,
DisableInterrupts;
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
EnableInterrupts;
Am I right? I'll try your method next Monday. Thanks a lot for your answer.
Regards
Yanli
Thanks very much, Mark.
I tried your method, and it did work. The MCU doesn't reset any more.
But I'm still confused about one point: Why my old "watchdog feed" method work right in the old project (in which wdog was fed at a regular frequency about 0.5s) ?
According to your explanation ,the old way to feed the wdog should always end with "MCU reset".
I'd appreciate your further explanation.
Regards,
Yanli