KB: Watchdog Timer Functionality and Usage on the RSL10


[RSL10 - Knowledge Base]


Question

The RSL10 has an internal timer called the Watchdog Timer, intended to behave as a safety measure that resets the entire device if part of the firmware execution has malfunctioned. This timer must be periodically acknowledged by the code being executed, otherwise the RSL10 will assume something has gone wrong and will hard-reset the device to fix the problem.

What interactions are offered by the RLS10 to configure the Watchdog Timer, and how is its functionality affected by each of these changes?


Description

By default, the Watchdog timer is enabled within the hardware registers and will have a default period of 4.194 seconds (the longest period allowed by the hardware). This value is configurable by writing to the TIMEOUT_VALUE within the WATCHDOG_CFG register directly, or by using the Sys_Watchdog_Set_Timeout() function. The image below outlines the values that are available.

The system reset will not occur on the first timeout of the Watchdog. Instead, an internal interrupt (WATCHDOG_IRQn) is triggered, to act as a warning that the first Watchdog period has elapsed without a refresh occurring. If, following the first Watchdog timeout, a second period passes and no refresh has occurred, the RSL10 device will assume something has went wrong and will reset itself to resume normal system functionality.

To prevent this reset from occurring, the WATCHDOG_REFRESH register within WATCHDOG_CTRL must have the specific 32-bit key written to it, or the firmware running must execute the Sys_Watchdog_Refresh() function available within the RSL10 libraries.

The Sys_Watchdog_Refresh() is called by all of the RSL10 sample applications within the main() function’s while(1) loop, to ensure that the timer is always refreshed unless a fault has occurred and has halted the firmware execution. If a different code structure is used for a custom project, or if another trapping while() loop is executed within main(), it is up to the developer to call the Sys_Watchdog_Refresh() function as they see fit.

If you would like to disable this Watchdog safety system during development or testing processes, it can be done by writing the DEBUG_HALT_CTRL_C_DEBUGEN bit within the DEBUG_HALT_CTRL register.


1 Like

Hi, can anyone please tell me how to set the DEBUG_HALT_CTRL_C_DEBUGEN bit within the DEBUG_HALT_CTRL register? I cannot find the described register. The compiler tells me, that it is not found.
I’m using the latest version of the RSL10-Stack.
Thanks in advance!

Hi @bobl,

More information regarding the register referenced above can be found in Section 14.3 of the RSL10 Hardware Reference manual. Specifically, details about the specific register can be found in Sub-Section 14.3.5.2 of the manual.

It should be noted that the CM3 cannot directly write to this register itself during run-time, so disabling the Watchdog reset must be done through the RSL10 register debugger manually, prior to launching the code execution. Section 3.4.2 of the RSL10 Getting Started Guide offers a step-by-step walk-through of how this register debugging can be accessed within the ON Semiconductor Eclipse IDE.

Let us know if you have any further questions, and thank you for using our Community Forums!

Thanks a lot @brandon.shannon for your reply!
I have managed it to view the register (although it was not possible to reset the bit (“Verify failed”)). But I saw that it is set per default when I’m entering the debug mode. So, the Watchdog should be disabled.
I still get into the WATCHDOG_IRQHandler() which shouldn’t be the case.

Hi @bobl,

This is the correct behavior. The ‘WATCHDOG_IRQHandler()’ will be triggered regardless, but the reset will not occur.

As an example, if you use our Blinky sample project (with the ‘Sys_Watchdog_Refresh()’ call removed from ‘main()’) to test the functionality, it will behave differently if it is running through the Eclipse Debugger vs running on its own.

When running through the Eclipse Debugger, the Watchdog Reset is disabled by default, and therefore the Blinky sample will continue to run, even with the ‘Sys_Watchdog_Refresh()’ call removed.

When running without the Eclipse Debugger attached, the firmware will reset every ~8 seconds when the second Watchdog IRQ in received.

Essentially, there is no need to set the Register manually, as attaching the Eclipse Debugger is required to directly write registers, but will also automatically disable the Watchdog on Debugger launch.

Thanks a lot for the quick reply @brandon.shannon.

Ok, I understand this. But my code gets stuck in the default handler and is not returning to the point from where the WATCHDOG_IRQHandler is called. So it does not continue to run…
But I guess this is a different problem then, right? Strange though that the problem occurs on different points in the code and every time the Watchdog IRQ Handler is shown on top of the call stack.

Hi @bobl,

This is definitely unexpected behavior of the Watchdog Reset, as it should never trap the execution. Judging by the fact that the WATCHDOG_IRQHandler()’ is in ‘startup_rsl10.S’ I think it is safe to assume that you have not defined ‘WATCHDOG_IRQHandler()’ within your own code?

Have you made any changes to the Interrupt Vector Table within your application?

Also, the ‘WATCHDOG_IRQHandler()’ should never be called directly, but is instead triggered when the Watchdog Timer hardware encounters a timeout. If this interrupt is triggered twice consecutively without a ‘Sys_Watchdog_Refresh()’ call occurring during the period (each timeout takes ~4s), it will trigger the device to reset (unless Debugging is run through Eclipse).

Can you possibly elaborate on any changes you have made to the Watchdog code logic within your application?

Hi @brandon.shannon
Thanks for your Reply!

You’re correct, I didn’t define a WATCHDOG_IRQHandler within my own code. I didn’t make a change to the vector table, but I did increase the priority of the DIO1_IRQn and the I2C_IRQn.

As I understand it, the time between two Sys_Watchdog_Refresh() calls has to be at least 8s in order to trigger the reset (although it shouldn’t be triggered in debug mode anyway). But it doesn’t take 8 seconds here. Maybe it’s even shorter then 4 seconds.

I didn’t made changes to the watchdog code logic. The only thing I did was inserting Sys_Watchdog_Refresh() and in the beginning the Sys_Watchdog_Set_Timeout(WATCHDOG_TIMEOUT_4194M3); (which is the default anyway).

Is it possible that something else triggers the Watchdog IRQ?

Hi @bobl ,

That is strange behavior to say the least. You are correct that it usually takes ~8s for the Watchdog Reset to occur, and this is because the Reset requires two consecutive Watchdog Timeouts to occur (~4s each) without a Refresh occurring. That said, both occurrences will trigger the ‘WATCHDOG_IRQHandler()’, so this might be why you are seeing the code execution getting stuck in this handler after ~4s.

To allow us to debug this issue further, can you possibly share your firmware code with us, or otherwise implement similar logic in our Blinky sample code so we can reproduce the issue and investigate the cause further?

Hi @brandon.shannon

Yes, it would be possible to share my code. But I cannot disclose it here in the forum. Is there another way?

Regards

Hi ,

if
SLOWCLK=1.28MHz and
CYCLES=1024*2**(0xB+1) with 0xB=WATCHDOG_CFG_TIMEOUT

then

CYCLES/SLOWCLK = 3.2768 sec.

According to the doc, 4.194 sec are expected; what is it wrong here?

Hi @darrew,

Good catch. This seems to be an error in our documentation, as it is our recommendation that the Slow Clock should be set to 1MHz for general use-cases.

The document should read “The times are based on a 1MHz clock.” instead, as this will cause the formula and expected times to align properly. I will ensure this is addressed internally and will be fixed in future updates.

Thank you again for the feedback and using our Community Forum.

2 Likes