Multiple Watchdogs for Multiple Tasks

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

Multiple Watchdogs for Multiple Tasks

ソリューションへジャンプ
2,233件の閲覧回数
audi_mcavoy
Contributor IV

The MQX user's guide says that an old-school hardware watchdog "monitors the entire application on a processor; it does not monitor individual tasks."

It then goes on to say that the "MQX watchdog component provides a software watchdog for each task."  Unfortunately the example code only monitors one task, and I want multiple watchdogs to monitor multiple tasks.

It sounds like there can be only one watchdog component created, which implies only one expiry function.  I need to have different responses to different timeouts, so I need to know which task has timed out.  The reference manual suggests the expiry function can expect to receive a TD_STRUCT_PTR; however, there is no example of what to do with this thing.

Does anyone have an example of an expiry function that handles timeouts from multiple tasks?

タグ(2)
1 解決策
1,700件の閲覧回数
audi_mcavoy
Contributor IV

> I grabbed the tf (Task Descriptor structure definition from the PSP mqx_prv.h header and copied it into my example.

Hmm.  Yeah, that worked for me too, but it leaves a sinking feeling in my stomach.  As soon as that structure is modified, I'm screwed.

I decided to add the directory containing mqx_prv.h to my "include user search paths (-i)" in my project settings, and add an "#include <mqx_prv.h>" to my source.  Which was a bit of a pain -- no matter what I try, I always get an "unresolved inclusion" warning; but, it does compile.

To help anyone else that may read this thread, here's what my expiry function looks like...

void handle_watchdog_expiry(TD_STRUCT_PTR td_ptr)

{

    _task_id tid = td_ptr->TASK_ID;

    if (tid==task1_id) {

        _lwevent_set(...);

    }

    else {

        // reset the processor

    }

}

In my project only the main_task() is auto started by MQX.  When my main task created task1(), it saved the returned _task_id in the task1_id variable.  Now my expiry function can tell why it's here, and what it should do in this case.

Obviously, I could save the _task_id of additional tasks created by the main task, then extend my "if..else" to "if..else if" and have a different response to each time out.

By the way, only the main_task needs to call _watchdog_create_component().  All other tasks simply call watchdog_start() as needed.

Thank you David.  Without your help, I would still be struggling with this.

I hope a future MQX release will have a watchdog expiry function that returns useful information.  A _task_id would be good; but, the task index constant that is used in the TASK_TEMPLATE_STRUCT would be even better!  That way I could just create a case statement in my expiry function and be done with it.

Thanks again.

- Audi

元の投稿で解決策を見る

5 返答(返信)
1,700件の閲覧回数
DavidS
NXP Employee
NXP Employee

Hi Audi,

I played around with having a second task running.  The attached code might help you to get where you want.

Post back if it does (and I guess if it doesn't :-) ).

Regards,

David

1,700件の閲覧回数
audi_mcavoy
Contributor IV

I've made a small step forward.  Here's a clip of your example. . .

void handle_watchdog_expiry(pointer td_ptr) {

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

   printf("\nTask Index = %x", ((_mqx_uint *)td_ptr)[3]);

I can see (by stepping though with a debugger) that ((_mqx_uint *)td_ptr)[3] is the _task_id that was returned when the task was created (which I had squirreled away).  But, what does td_ptr actually point to?

I would really rather use a "structure->member" notation to get the _task_id.

0 件の賞賛
返信
1,700件の閲覧回数
DavidS
NXP Employee
NXP Employee


Hi Audi,

Attached is my update.  I grabbed the tf (Task Descriptor structure definition from the PSP mqx_prv.h header and copied it into my example.

I'm sure there is a better method to do this but what I have works.

TD_STRUCT_PTR des_tsp; //DES


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

"\nTask Index = 0x%x", des_tsp->TASK_ID); //DES added the td structure definition above to get access to this structure.

Regards,

David

1,701件の閲覧回数
audi_mcavoy
Contributor IV

> I grabbed the tf (Task Descriptor structure definition from the PSP mqx_prv.h header and copied it into my example.

Hmm.  Yeah, that worked for me too, but it leaves a sinking feeling in my stomach.  As soon as that structure is modified, I'm screwed.

I decided to add the directory containing mqx_prv.h to my "include user search paths (-i)" in my project settings, and add an "#include <mqx_prv.h>" to my source.  Which was a bit of a pain -- no matter what I try, I always get an "unresolved inclusion" warning; but, it does compile.

To help anyone else that may read this thread, here's what my expiry function looks like...

void handle_watchdog_expiry(TD_STRUCT_PTR td_ptr)

{

    _task_id tid = td_ptr->TASK_ID;

    if (tid==task1_id) {

        _lwevent_set(...);

    }

    else {

        // reset the processor

    }

}

In my project only the main_task() is auto started by MQX.  When my main task created task1(), it saved the returned _task_id in the task1_id variable.  Now my expiry function can tell why it's here, and what it should do in this case.

Obviously, I could save the _task_id of additional tasks created by the main task, then extend my "if..else" to "if..else if" and have a different response to each time out.

By the way, only the main_task needs to call _watchdog_create_component().  All other tasks simply call watchdog_start() as needed.

Thank you David.  Without your help, I would still be struggling with this.

I hope a future MQX release will have a watchdog expiry function that returns useful information.  A _task_id would be good; but, the task index constant that is used in the TASK_TEMPLATE_STRUCT would be even better!  That way I could just create a case statement in my expiry function and be done with it.

Thanks again.

- Audi

1,700件の閲覧回数
msinger
Contributor I

why not just add to init_bsp.c this?  No problem with headers that way.

uint32 _bsp_get_task_id_from_descriptor(TD_STRUCT_PTR td_ptr)

{

    return td_ptr->TASK_ID;

}