Watchdog ISR is not entered on Kinetis

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Watchdog ISR is not entered on Kinetis

2,757 Views
baltech
Contributor II

We try to activate the Watchdog interrupt in a Kinetis MK22FN512 without success.
As you can see in the attached code snippet we enabled the watchdog and activated the watchdog interrupt.
Then we start a endless loop.
As expected the watchdog does a resets after the timeout.
But it does not call the interrupt routine (WDOG_EWM_IRQHandler) before rebooting also "enableInterrupt" is set.

What are we doing wrong?

Best Regards,
robert

#include "hal/nxp_mk/fsl_mk22fn512xxx12/drivers/fsl_wdog.h"


void main(void)
{
        wdog_config_t config;
        
        __enable_interrupt();
        
        // Activate Watchdog
        WDOG_GetDefaultConfig(&config);
        config.prescaler = kWDOG_ClockPrescalerDivide8;
        config.timeoutValue = 3000000;
        config.enableWindowMode = false;
        config.clockSource = kWDOG_AlternateClockSource;
        config.enableInterrupt = 1;
        WDOG_Init(WDOG, &config);
        
        while (1);
}


void WDOG_EWM_IRQHandler(void)
{
        // #is never entered
        return;
}

0 Kudos
7 Replies

1,885 Views
Anonymous
Deactivated User

#include "hal/nxp_mk/fsl_mk22fn512xxx12/drivers/fsl_wdog.h"

void main(void)
{
        wdog_config_t config;
        

this line only enable the already configured and enabled ISRs only 

        __enable_interrupt();   
        
        // Activate Watchdog
        WDOG_GetDefaultConfig(&config);
        config.prescaler = kWDOG_ClockPrescalerDivide8;
        config.timeoutValue = 3000000;
        config.enableWindowMode = true;
        config.clockSource = kWDOG_AlternateClockSource;
        config.enableInterrupt = 1;
        WDOG_Init(WDOG, &config);
        
        while (1);
}

 


void WDOG_EWM_IRQHandler(void)
{
        // #is never entered
        return;
}

 

USE this configuration for this 

/*Read the default condition for watchdog interrupt*/
WDOG_GetDefaultConfig( &wdog_info);

/*Set the time out value*/
wdog_info.enableWdog = true;
wdog_info.timeoutValue = WDOG_TIME_MS;

/*Initialize the watch dog timer*/
WDOG_Init(WDOG, &wdog_info);

/*Enable watch dog interrupt*/
WDOG_EnableInterrupts(WDOG, WDOG_EWM_IRQn);

/* Enable at the NVIC*/
EnableIRQ(WDOG_EWM_IRQn);

0 Kudos

1,894 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi robert,

I agree with the opinion of Mark. Please enalbe the watchdog interrupt in the NVIC.

If you are using Kinetis SDK2.x, please refer the code shown below:

NVIC_EnableIRQ(WDOG_EWM_IRQn);

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,894 Views
mjbcswitzerland
Specialist V

Robert

In fact the problem that you have is very likely to be the method you are using to check that the interrupt takes place. When the watchdog fires it generates an interrupt and WCNT later (256 clocks if I remember correctly) it unconditionally resets too. Using break points to detect this will probably not work because the debugger will show a reset before it has had time to show that the break point was hit.

If you set a port output or write something to SRAM that can be checked after the reset you should find that it does in fact work. I have attached a binary that verifies the operation that can be checked on the FRDM-K22F.

1. It runs " normally" for about 20 s and in this time the SRAM content can be checked via the VCOM interface at 115kBaud.

2. It will create a forever loop after this time that causes the watchdog to fire. The watchdog interrupt will write a pattern to SRAM.

The SRAM locations 0x2000fffc..0x2000ffff are reserved for this. They will power up to random values. When the forever loop starts 0x2000fffc is set to 0x1234. When the watchdog interrupt takes place 0x2000fffe is set to 0x55aa.

This is what it looks like (after powering the board) - using the command line interface to request memory content

Hello, world... KINETIS
OS Heap use = 0x0189 from 0x6000

Serial number: 00
Software version V1.4.012
Device identification: KINETIS

     Main menu
===================
1              Configure LAN interface
2              Configure serial interface
3              Go to I/O menu
4              Go to administration menu
5              Go to overview/statistics menu
6              Go to USB menu
7              Go to I2C menu
8              Go to utFAT disk interface
9              FTP/TELNET client commands
a              CAN commands
help           Display menu specific help
quit           Leave command mode
3


 Input/Output menu
===================
up             go to main menu
md             Memory Display [address] [<l>|<w>|<b>] [num]
mm             Memory Modify [address] [<l>|<w>|<b>] [val]
mf             Memory Fill [address] [<l>|<w>|<b>] [val] [num]
sd             Storage Display {as md}
sm             Storage Modify {as mm}
sf             Storage Fill {as mf}
se             Storage Erase [address] [len-hex]
set_ddr        Set port type [1..4] [<i>|<o>
get_ddr        Get data direction [1..4]
read_port      Read port input [1..4]
write_port     Set port output [1..4] [0/1]
save           Save port setting as default
help           Display menu specific help
quit           Leave command mode

#md 2000fff8 w 4
Memory Display
0x2000fff8     41bb 0000 5340 3a04  A...S@:.  <---- Notice random content

After the watchdog reset

Hello, world... KINETIS
OS Heap use = 0x0189 from 0x6000

Serial number: 00
Software version V1.4.012
Device identification: KINETIS

     Main menu
===================
1              Configure LAN interface
2              Configure serial interface
3              Go to I/O menu
4              Go to administration menu
5              Go to overview/statistics menu
6              Go to USB menu
7              Go to I2C menu
8              Go to utFAT disk interface
9              FTP/TELNET client commands
a              CAN commands
help           Display menu specific help
quit           Leave command mode
3


 Input/Output menu
===================
up             go to main menu
md             Memory Display [address] [<l>|<w>|<b>] [num]
mm             Memory Modify [address] [<l>|<w>|<b>] [val]
mf             Memory Fill [address] [<l>|<w>|<b>] [val] [num]
sd             Storage Display {as md}
sm             Storage Modify {as mm}
sf             Storage Fill {as mf}
se             Storage Erase [address] [len-hex]
set_ddr        Set port type [1..4] [<i>|<o>
get_ddr        Get data direction [1..4]
read_port      Read port input [1..4]
write_port     Set port output [1..4] [0/1]
save           Save port setting as default
help           Display menu specific help
quit           Leave command mode

#md 2000fff8 w 4
Memory Display
0x2000fff8     41bb 0000 1234 55aa  A....4U.  <-- notice the expected pattern in memory

If I try to debug this I never hit the break point but the test shows that it does work, but the debugger probably can't handle the situation.

Regards

Mark

0 Kudos

1,894 Views
baltech
Contributor II

Hello Mark,

Thx a lot for your detailed answer!

Forgetting to activate the NVIC Interrupt for WDT was a bloody beginners fault...

Could it be that Breakpoints do not work in your Watchdog ISR because you set the WDOG_STCTRLH_WAITEN / WDOG_STCTRLH_STOPEN bits in WDOG_STCTRLH?!?

I was able to run your uTaskerV1.4.12_FRDM-K22F_WDOG_INT_TEST.bin on my FRDM-K22 board and reproduce your results. But when trying it with my own mini-firmware I still suffer from the same problem, although:

  - activated the watchdog IRQ in the NVIC

  - I tried the same WDOG settings as you

  - instead of a Breakpoint I outputted some data via seggers RTT interface in the ISR.

  - I even added a debugmessage when the INTFLG of the WDOG_STCTRLL is set during the mainloop. But this message is also never printed...

Regards,

robert

0 Kudos

1,894 Views
mjbcswitzerland
Specialist V

Robert

>>Could it be that Breakpoints do not work in your Watchdog ISR because you set the WDOG_STCTRLH_WAITEN / WDOG_STCTRLH_STOPEN bits in WDOG_STCTRLH?!?

These allow the watchdog to continue running in STOP and WAIT modes so have no effect. I did also try without them and with WDOG_STCTRLH_DBGEN (which allows the watchog to continue when paused by the debugger) and I never ever hit a break point in the watchdog interrupt service routine.

I would toggle a pin or write to memory - certain don't trust debugger communication channels in such a situation! Any code there may also not work if it takes too many clock cycles to actually copy the debug data to the output and have it sent (also the UART would need a very high speed to actually get a couple of bytes out before the HW reset also kills it....).

In fact the firmware that I posted (and you checked) also polls the INTFLG in its forever loop. If it were to detect it being set (before the interrupt is taken) it would set 0x5678 instead of 0x1234 at the address 0x2000fffc. However, after doing several watchdog tests, I never saw this being set, meaning that either the flag is not 'visibly' set or the interrupt is always taken 'before' the flag becomes visible. Since this situation is a very special one (the processor will reset within a small number of clock cycles no matter what is done at this point) the reactions may not be absolutely as expected in normal operation. I find that the interrupt is hit, which is the main thing of real interest, and this is intended for saving some memory in order to possibly allow the 'crash' to be analysed for this.

Regards

Mark

0 Kudos

1,894 Views
mjbcswitzerland
Specialist V

Robert

As reference, this is the watchdog initialisation code:
UNLOCK_WDOG();
WDOG_TOVALL = (2000/5);                                         // 2s timeout
WDOG_TOVALH = 0;
WDOG_STCTRLH = (WDOG_STCTRLH_STNDBYEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN | WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_IRQRSTEN) // watchdog enabled to generate reset on 2s timeout (no further updates allowed)

Registration of interrupt handler:
fnEnterInterrupt(irq_WDOG_ID, 0, wdog_irq);                    // test WDOG interrupt (highest priority)

The watchdog interrupt handler itself:
static void wdog_irq(void)
{
    WDOG_STCTRLL = (WDOG_STCTRLL_INTFLG | WDOG_STCTRLL_RES1); // clear interrupt flag
    *BOOT_MAIL_BOX = 0x9876;                                  // set a pattern to the boot mailbox to show that the watchdog interrupt took place
}

Beware that if code hangs / crashes in a region where interrupts are disabled also the watchdog interrupt will not be able to be executed.

Regards

Mark

0 Kudos

1,894 Views
mjbcswitzerland
Specialist V

Hi

Are you sure that the watchdog initilisation code also enables the watchdog interrupt in the NVIC? If not you will need to enable it there too.

Regards

Mark