Finish it up

punch line

It's about time to discuss the ISR, what should happen in there? Well, it is very straightforward, we just decrement the delay for every task since another scheduler period has been elapsed and we mark the tasks that are ready to run. Note that the ISR does not actually call any tasks and it shouldn't since it has to be quick, it just marks tasks and the dispatch routine invokes them within the main loop.


SIGNAL(SIG_OVERFLOW0)
{
   u8 m;

   // load timer
   TCNT0 = StartFrom;
       
   // traverse task array
   for (m=0; m<MAXnTASKS; m++)
   {
      // for each task
      if (TaskArray[m].pfunc)
      { 
         // if it is time to run
         if (TaskArray[m].delay == 0)
                           {
            TaskArray[m].run = 1;
            TaskArray[m].delay = TaskArray[m].period;
         }
         else TaskArray[m].delay--;
      }
   }
}
 

Each time we reload the timer for the next interrupt and we traverse the task array looking for pointers to functions (residing not at 0x0000). If the delay is zero the task has to run therefore the flag is set. It puzzles you, right? You would expect checking if the delay is greater than zero, then checking if the task period is greater than zero and if both are zero then execute the task otherwise decrease the non-zero variable. Well, if we do that we would forget what the desired task period is so, we would have to introduce another variable in the structure possibly with the name ticks2execute. However, we can do the job by relying only on the delay variable. On each task execution we copy the period to the delay. Now, as you would expect a task will either run and its delay will be initialized or its delay will be decreased by one. The dispatch should look reasonable, it just invokes the required routines and clears their run flag.


void DispatchTask (void)
{
   u8 k;
       
   for (k=0; k<MAXnTASKS; k++)
   {
      if (TaskArray[k].run == 1)
      {
         // run the task
         (*TaskArray[k].pfunc)();
         // clear its run flag
         TaskArray[k].run = 0;
      }
   }
}
 
 
 
victor@avrtutor.com