Author Topic: Multiple Tasks  (Read 8001 times)

Offline Pursuit20

  • Newbie
  • *
  • Posts: 11
    • View Profile
Multiple Tasks
« on: August 15, 2008, 02:36:51 PM »
Is it possible to schedule an already scheduled tasks so it runs again a little bit later.  For example, I need one task to have multiple purposes.  I need to schedule the task once for purpose A and before A is able to run I need to schedule the tasks for purpose B.  I still need both of them to run in the order they were scheduled but I don't want A to get canceled since I "rescheduled" the task.  Is this possible?

thanks,

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Multiple Tasks
« Reply #1 on: August 15, 2008, 04:45:18 PM »
Hi

I think that Interrupt Events could be the solution to this. An interrupt event will wake a task with an event number. The events are queued and the queued events always arrive in the order that they were queued.

    fnInterruptMessage(MY_TASK, EVENT_A);
    fnInterruptMessage(MY_TASK, EVENT_B);


You will need to define EVENT_A and EVENT_B (eg. add to application.h). This will cause MY_TASK to be woken and it will have 2 events in its input queue. It will recognise EVENT_A and thus do task A work first, then it will recognise EVENT_B and do task B work.

    fnInterruptMessage(MY_TASK, EVENT_B);
    fnInterruptMessage(MY_TASK, EVENT_A);


This will do the same but cause MY_TASK to process in the reverse order.

The processing will look something like this (in the task):
    while ( fnRead( PortIDInternal, ucInputMessage, HEADER_LENGTH )) {   // check input queue
        switch ( ucInputMessage[MSG_SOURCE_TASK] ) {                     // switch depending on message source
        case INTERRUPT_EVENT:
            switch (ucInputMessage[MSG_INTERRUPT_EVENT]) {
            case EVENT_A:
                // Do A work
                break;
            case EVENT_B:
                // Do B work
                break;
            }
        break;
    }


Another method is to do the same with timer events (assuming the scheduling is not required immediately but after a defined time). As long as you have GLOBAL_TIMER_TASK support you can do

    uTaskerGlobalMonoTimer( MY_TASK, (CLOCK_LIMIT)(1*SEC),     E_TIMER_A );    // start a 1s timer
    uTaskerGlobalMonoTimer( MY_TASK, (CLOCK_LIMIT)(1.2*SEC),   E_TIMER_B );    // start a 1.2s timer
    uTaskerGlobalMonoTimer( MY_TASK, (CLOCK_LIMIT)(1.3*SEC),   E_TIMER_A );    // start a 1.3s timer


In this case the task's job is defined by the timer event received.
(Note that without the global SW timer support a task has a single mono-stable timer and so only the last event would be received - each subsequent timer cancels the previous and re-triggers with the new delay. See the following for an introduction to the timers:
http://www.utasker.com/docs/uTasker/uTaskerV1.3.PDF )

Regards


Mark