How to determine which task triggered watchdog timeout?

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

How to determine which task triggered watchdog timeout?

2,514 Views
ironsean
Contributor V

Hello, I'm using MQX 4.2 and CodeWarrior 10.6.4 with a Freescale FRDM K64F development board.

I recently implemented watchdog timers in several of my tasks in my firmware, but am running into an issue determining which task caused the timer to expire.

I based my implementation on a combination of this example (MQX Watchdogs for Multiple Tasks ) and the MQX watchdog example application. However, it seems that even DavidS​ might be uncertain which method is best for determining the task which caused the timer expiry.

printf("\nWatchdog expired for task: 0x%P", td_ptr);

printf("\nTask Index = %x", ((_mqx_uint *)td_ptr)[3]); //DES added increment td_ptr address to point to TASK_ID

printf("\nTask Index = %x", _task_get_id()); //DES added

I settled with the _task_get_id() method, but it seems to fail in certain situations. For instance, if a task somehow delays or blocks and then the watchdog timer expires, that expiry gets attributed to the MQX_Idle_task. I've also had the timer expire during a socket operation and get attributed to the TCP/IP task. This doesn't work well with my watchdog implementation which does the following:

1) reads the task_id of the expired task.
2) sets a variable to that task ID so it can be reset by the main task.
3) log the error.

void handle_watchdog_expiry(void   *td_ptr)

{

uint32_t error_data[2];

printf("\nTask Index = %x", _task_get_id()); //DES added

Watchdog_resets++;

if (watchdog_resets > 5 || _task_get_id() == 0x10003 ) //check if main task, as that will lock all

{

SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK;

}

else

{

expired_task = _task_get_id();

error_data[0] = _task_get_id();

error_data[1] = ETC_WATCHDOG_RESET_TASK;

_lwmsgq_send(error_log, error_data, 0);

}

}

Which causes the main task to reset the expired task (or resets the full system if the main task is the one to fail the watchdog timer)

if (expired_task != MQX_NULL_TASK_ID)

  {

  _task_restart(expired_task, NULL, FALSE);

  expired_task = MQX_NULL_TASK_ID;

  }

  _time_delay(150);

The problem is, when the task is read as the idle task, or the TCP/IP task, the main task can't restart it properly, nor restart the actual problem task.

So my question is this:

Is there a better way to determine which task's watchdog timer expired in a generic watchdog handling ISR?

Or should I change it so each task has a task specific ISR which is set as each task sets up the watchdog timer, bypassing any reading of the current task.

Sean

0 Kudos
2 Replies

1,449 Views
soledad
NXP Employee
NXP Employee

Hello Sean,

You could use the KLOG.

Information taken from the MQXUG.pdf

Kernel Log

Kernel log lets an application log any combination of:

• Function entry and exit information for all calls to MQX functions.

• Function entry and exit information for specific function calls.

• Context switches.

• Interrupts.

You may take a look at it. Please let me now if that helps.


Have a great day,

Sol

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

0 Kudos

1,449 Views
ironsean
Contributor V

That looks useful for determining what happened after the fact, but is there a more consistent way for the running firmware to detect which watchdog timer expired? I suppose I could force it by having a different interrupt function for each task I'm using Watchdog with rather than a generic one. But I'm definitely running into issues where a watchdog expires sometime when a short delay or something is occurring, and mqx_idle_task gets attributed with the expiry and is reset. In the meantime I went with a more scotched earth policy of just rebooting the whole device instead of trying to reset specific tasks.

0 Kudos