How to determine which task triggered watchdog timeout?

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

How to determine which task triggered watchdog timeout?

2,831件の閲覧回数
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 件の賞賛
返信
2 返答(返信)

1,766件の閲覧回数
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 件の賞賛
返信

1,766件の閲覧回数
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 件の賞賛
返信