Task managment - Kill various tasks

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

Task managment - Kill various tasks

Jump to solution
4,842 Views
CarlFST60L
Senior Contributor II

Hi,

 

Can someone give me some conceptual approachs to the most common way to have a parent task destroy its child tasks?

 

Basically, we have a 'main_task' that creates a heap of different tasks that have all sorts of drivers open (comm ports, SPI drivers, Flashx etc), some connect to external devices which are 'out of my control', all have I/O controllers to reset those devices. I need to add some software to my main task that will allow me to destroy all those tasks if something stops responding or act normally, however, i need my main task to keep running so i can report back errors and manage the reboot processes. If I cannot manage a reboot, I will need to reboot the entire processor.

 

What is 'the right' way to go about doing this?

 

Thanks in advance,

Carl.

1 Solution
1,664 Views
anthony_huereca
NXP Employee
NXP Employee

Hi Carl, here's some answers to some of the questions you had in this thread

 

1) For some reason the exit handlers do not run after _task_abort(); is called.

In the user_config.h file for the board you are using, set the following options:

#define MQX_TASK_DESTRUCTION     1
#define MQX_COMPONENT_DESTRUCTION 1

 

Then recompile the libraries with the build_libs.mcp project. Now the exit handler will run. Note that it exits gracefully, so if the task being aborted is not currently running, the exit handler will only run once that task has been scheduled to be the active task.

 

2)  What happens if you call _task_destroy(_task_id) on a task that is in the middle of doing fopen("gpio:....) or similar?

I assume you're asking if you had an interrupt that made another task active, and that other task called task_destory()? I would need to look into this more with the software team and get back with that answer for you.

 

3) How do we do _mutex_destroy(&mutex_struct); from a task other than the creater?

 I'm was able to create an example that destroyed a mutex in a child task. I took some of the code in the mutex example and added another task. Try it out and see if it works for you too:

 

#include <mqx.h>#include <bsp.h>#include <mutex.h>#define MAIN_TASK 1#define TASK_A    2void Main_task(uint_32);void task_a(uint_32);TASK_TEMPLATE_STRUCT MQX_template_list[] = { /*  Task number, Entry point, Stack, Pri, String, Auto? */   {MAIN_TASK,   Main_task,   1500,  9,   "main",   MQX_AUTO_START_TASK},   {TASK_A,      task_a,      1500,  10,  "task_a", 0},   {0,           0,           0,     0,   0,      0,                 }};//Global mutex variableMUTEX_STRUCT print_mutex;void Main_task(uint_32 initial_data){   MUTEX_ATTR_STRUCT mutexattr;   _task_id taska_id;   printf("\n Starting init task \n");       //Create Mutex   _mutatr_init(&mutexattr);   _mutex_init(&print_mutex, &mutexattr);      //Create Task A   taska_id = _task_create(0 ,TASK_A, 0);   //Let Task A Run   _time_delay(2000);   printf("Back in init task\n");   while(1)   {    asm(nop);   }}void task_a(uint_32 data){ _mqx_uint error; printf("In task A\n");        //Destroy mutex error=_mutex_destroy(&print_mutex);        //Should have a result of 0 printf("Result was %d\n",error);}

 

 

 

 

4) I am also having the same problems with _msq_close();

The problem might be that if you are using a private message queue (with msgq_open()) then only the task that opened the message queue can close it. However if you are using a system message queue (with msgq_open_system()) then any task should be able to close that. The reference manual has a short blurb on it.

 

Hope that helps! 

View solution in original post

26 Replies
1,602 Views
anthony_huereca
NXP Employee
NXP Employee

As a further answer to your second question, the user application is responsible for ensuring proper behavior with an IO when that task is destoryed. The opening device abort is not handled by MQX. The application is responsible for correct exception handling in this case.

 

For the MQX_IO_COMPONENT_DESTRUCTION flag, that is currently unused. The original purpose appears to be for use by the stacks when their tasks were closed. You can do a search on the <mqx>\source\ directory for that flag to see what it affects, but again, it is currently not being used so just leave it to 0.

 


 

 

Message Edited by amh on 2009-10-30 05:20 PM
0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II
Thanks amh.
0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

It is quite simple to do a software reset in MQX (Although this is Processor Specific):

 

 

 

#define MCF5225_CCM_RCR_SOFTRST                 (1 << 7)void MCF_5225_SoftwareReset(void){ VMCF5225_STRUCT_PTR reg_ptr = (VMCF5225_STRUCT_PTR)BSP_IPSBAR; //Pointer to data // DEBUG ONLY printf("SOFTWARE RESET REQUESTED!\n"); reg_ptr->CCM.RCR |= MCF5225_CCM_RCR_SOFTRST;       //Cause software reset //SOFTWARE NEVER RETURNS FROM HERE! }

 

 

 

 

Maybe the guys at MQX can build this into the MQX system as its quite simple. Maybe you could also handle allowing Software reset back to the MRAM code as well.... 

 

 

Message Edited by CarlFST60L on 2009-11-02 02:21 AM
0 Kudos
1,665 Views
anthony_huereca
NXP Employee
NXP Employee

Hi Carl, here's some answers to some of the questions you had in this thread

 

1) For some reason the exit handlers do not run after _task_abort(); is called.

In the user_config.h file for the board you are using, set the following options:

#define MQX_TASK_DESTRUCTION     1
#define MQX_COMPONENT_DESTRUCTION 1

 

Then recompile the libraries with the build_libs.mcp project. Now the exit handler will run. Note that it exits gracefully, so if the task being aborted is not currently running, the exit handler will only run once that task has been scheduled to be the active task.

 

2)  What happens if you call _task_destroy(_task_id) on a task that is in the middle of doing fopen("gpio:....) or similar?

I assume you're asking if you had an interrupt that made another task active, and that other task called task_destory()? I would need to look into this more with the software team and get back with that answer for you.

 

3) How do we do _mutex_destroy(&mutex_struct); from a task other than the creater?

 I'm was able to create an example that destroyed a mutex in a child task. I took some of the code in the mutex example and added another task. Try it out and see if it works for you too:

 

#include <mqx.h>#include <bsp.h>#include <mutex.h>#define MAIN_TASK 1#define TASK_A    2void Main_task(uint_32);void task_a(uint_32);TASK_TEMPLATE_STRUCT MQX_template_list[] = { /*  Task number, Entry point, Stack, Pri, String, Auto? */   {MAIN_TASK,   Main_task,   1500,  9,   "main",   MQX_AUTO_START_TASK},   {TASK_A,      task_a,      1500,  10,  "task_a", 0},   {0,           0,           0,     0,   0,      0,                 }};//Global mutex variableMUTEX_STRUCT print_mutex;void Main_task(uint_32 initial_data){   MUTEX_ATTR_STRUCT mutexattr;   _task_id taska_id;   printf("\n Starting init task \n");       //Create Mutex   _mutatr_init(&mutexattr);   _mutex_init(&print_mutex, &mutexattr);      //Create Task A   taska_id = _task_create(0 ,TASK_A, 0);   //Let Task A Run   _time_delay(2000);   printf("Back in init task\n");   while(1)   {    asm(nop);   }}void task_a(uint_32 data){ _mqx_uint error; printf("In task A\n");        //Destroy mutex error=_mutex_destroy(&print_mutex);        //Should have a result of 0 printf("Result was %d\n",error);}

 

 

 

 

4) I am also having the same problems with _msq_close();

The problem might be that if you are using a private message queue (with msgq_open()) then only the task that opened the message queue can close it. However if you are using a system message queue (with msgq_open_system()) then any task should be able to close that. The reference manual has a short blurb on it.

 

Hope that helps! 

1,602 Views
CarlFST60L
Senior Contributor II

Thanks amh.

 

The exit handlers now run when i call task abort. 

 

These settings seem to have fixed a few things along with finding a few more MQX tricks to get things running as required.


Thanks again.
0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

What exactly will MQX_IO_COMPONENT_DESTRUCTION look after? The MQX headers say "IO Components", I tried a few things but cannot get it to free up anything that I can tell...

0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

BUMP.

 

Its quite important that I get this working ASAP, has anyone else been able to get the exit handler to run???

0 Kudos
1,602 Views
DavidS
NXP Employee
NXP Employee

Hi Carl,

Not certain this is helpful or not so I apologize if not.

With one customer I helped, I setup the Backup Watchdog Module on the MCF52259 so that is the system dies for any reason, the device will reset since the Backup Watchdog does a hard reset.

I also used the core watchdog timer and if its isr routine is ever called, I generate a software reset.

One last point...with this customer we had implemented the Mass Storage USB Bootloader.  So each reset (Backup or core Watchdog) is flagged differently in the Reset Status Register so that the bootloader could determine to stay in bootloader mode or to jump to the FSLMQX application.

I hope to play with disabling and terminating a task soon but not certain it will meet your time frame.

Regards,

David

0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II
Thanks David, that is helpfull for the resetting, but I our project is being held up until we can get the exit handler to run as per the above example.
0 Kudos
1,602 Views
DavidS
NXP Employee
NXP Employee

Hi Carl,

I've spent a few BTU's on this and think something is not happening correctly.  I hacked a bit of PSP code and have asked our developers if what I'm doing is valid, lucky, or insane.  My hack allows me to restart a task that just did a "return;". 

I did test also with _task_destroy(); which wipes the task from the task list altogether.

Regards,

David

0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II
I just installed MQX3.4 this morning (fresh release), it now has an example of using the exit handler which I will try out now to see if i can get it working..
0 Kudos
1,602 Views
MQXuser
Contributor III

Could you tell me where is the exit handler example located?

I did a quick search into the release notes and didnt find it.

 

Thanks

0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

Hi MQX, its in the MQXRM.pdf under _task_abort(); however, it is not complete... Page 350 for the 3.4 release.

 

Here is a much simpler example I just wrote up which does NOT call the exit hanlder.  The TAD does say the task is terminating, but thats all....

 PS: I tested the below example using _task_destroy instead of _task_abort and the task is destroyed based on TAD. But this is no good as it cannot fclose everything and clearn up other special functions..

/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved                      
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName:
* $Version :
* $Date    :
*
* Comments:
*
*   Test task_abort, start a task, then abort it
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <fio.h>


#if ! BSPCFG_ENABLE_IO_SUBSYSTEM
#error This application requires BSPCFG_ENABLE_IO_SUBSYSTEM defined non-zero in user_config.h. Please recompile BSP with this option.
#endif


#ifndef BSP_DEFAULT_IO_CHANNEL_DEFINED
#error This application requires BSP_DEFAULT_IO_CHANNEL to be not NULL. Please set corresponding BSPCFG_ENABLE_TTYx to non-zero in user_config.h and recompile BSP with this option.
#endif

//Main task
void main_task(uint_32);
//Task 2
void task2(uint_32);
//Exit handlers for tasks
void task2_exit_handler(void);


TASK_TEMPLATE_STRUCT  MQX_template_list[] =
{
    {5, main_task, 1500, 6, "main_task", MQX_AUTO_START_TASK, 0, 0},
    {6, task2, 1500, 6, "task2", 0, 0, 0},
    {0,          0,          0,   0, 0,       0,                   0, 0}
};

/*TASK*-----------------------------------------------------
*
* Task Name    : hello_task
* Comments     :
*    This task prints " Hello World "
*
*END*-----------------------------------------------------*/
void main_task (uint_32 initial_data)
{
 _task_id task2_id_;

 printf("main_task: creating task2\n");

 task2_id_ = _task_create(0 , 6, 0);

 //Wait for 2 seconds before killing task2
 _time_delay(2000);

 printf("main_task: aborting task2\n");
 _task_abort(task2_id_);
 printf("Waiting for tasks to abort\n"); //TASKS STOP, BUT THE EXIT HANDER NEVER RUNS
 _time_delay(5000);
 printf("MQX Will now exit\n");
    _mqx_exit(0);

}

void task2(uint_32)
{

 _task_set_exit_handler(_task_get_id(), task2_exit_handler);

 printf("Task 2: Starting task2\n");

 for(;;) _time_delay(0100);

}
//Looks after closing up resources for task2
void task2_exit_handler(void)
{
 printf("****Task2 exit handler!****\n");
 fflush(stdout);
}

 

 Here is stdout log, its clear to see the exit handler does not work:

 

main_task: creating task2
                                                    
Task 2: Starting task2
                                                       
main_task: aborting task2
                                                    
Waiting for tasks to abort
                                                   
MQX Will now exit

 

 

 

Message Edited by CarlFST60L on 2009-10-27 12:12 AM
Message Edited by CarlFST60L on 2009-10-27 12:12 AM
Message Edited by CarlFST60L on 2009-10-27 12:20 AM
0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II
Also, what happens if you call _task_destroy(_task_id) on a task that is in the middle of doing fopen("gpio:....) or similar? Will the recouce be tied up? How should this be handled? How exactly will MQX deal with this?
I have issued a service request based on this thread (_task_abort() issue with exit handers) but have had no response... I would have thought this would be pretty easy for the MQX guys to answer.
Message Edited by CarlFST60L on 2009-10-28 11:53 PM
0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

How do we do _mutex_destroy(&mutex_struct); from a task other than the creater?

 

We can only get _mutex_destroy to work from the task that called _mutex_init()...

 

Basically, we need our task manager to destroy the mutex so it can start from scratch... btw, _mutatr_destroy() returns MQX_EOK, but _mutex_destroy() locks up when the MQX function trys to lock the mutex...

 

The MQX_RM.pdf or example do no have any information on thi, and certainly doesnt say that only the creater can destroy.
Message Edited by CarlFST60L on 2009-10-29 03:24 AM
0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

I am also having the same problems with _msq_close();

I am unable to close the message queue's outside the creating task...

 

Currently I can see no way to destroy a thread and recover from it as you cannot close / destroy anything unless you are still running in that threads context... Unless of coarse I write some tricky code or modify MQX itself...

 

Am I doing something wrong? Am I thinking about this wrong?

 

 

Message Edited by CarlFST60L on 2009-10-29 05:11 AM
0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

I guess the answer to my question is this:

 

You can set an exit handler which will run when you call task_abort, that handler can close message queue, drivers, clean up varibles etc

 

Carl.

Message Edited by CarlFST60L on 2009-10-09 10:51 PM
0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

What is the 'correct method' for a complete reset while MQX is running i.e. equivilant of hitting the reset button?

 

I have tried doing __boot(); but no luck as MQX is obviously aware its still running...

 

Do I have to call _mqx_exit(x); and call __boot from there? Is there some command thats not in the userguide or reference manual?

 

(searching the source code on reset isnt much good as there are just to many 'reset' results)

 

Carl

0 Kudos
1,602 Views
PetrM
Senior Contributor I

Since your peripherals are already configured somehow, I guess you want to initiate software reset to to return HW to initial state before MQX (re)booting. Here I've found some tips&tricks how to do it:

http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&message.id=44

0 Kudos
1,602 Views
CarlFST60L
Senior Contributor II

Thanks for the link Pete.

 

Wow, so I guess MQX doesnt support a soft reset?

 

I am suprised that the __boot(); / _mqx_init(); routines dont allow a soft reset... Could it be modified i wonder...? I know in the basic small processors we use, jumping to the reset vector is essentially the same as a soft reset, I guess there is another level to this in the 5225X?

 

I would think a soft reset option is a must, I know if the worst happens, I want everything to completely restart.

Message Edited by CarlFST60L on 2009-10-22 10:40 AM
0 Kudos