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?
解決済! 解決策の投稿を見る。
> 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
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.
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
> 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
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;
}