Electrical – Attempt to implement a scheduler in STM32F4

cstm32f4-discovery

I have a question regarding scheduler implementation. I have tried to implement a scheduler according to my understanding.

In this example, i have taken advantage of the Systick handler provided by STM32, so my handler looks somewhat like this:

void SysTick_Handler(void)
{
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();    

  if(ticks_for_scheduler++==100)
      ticks_for_scheduler=0;    
}

I have a scheduler.h file which looks like this:

void (*task1)() = read_temp;
void (*task2)() = Display_temp_lcd;

and my scheduler.c looks like this:

extern uint16_t ticks_for_scheduler;
void sched_system()
{

  if(ticks_for_scheduler==20)
      (*task1)();

  if(ticks_for_scheduler==40)
  {
      (*task2)();
  }   
}

The function sched_system is called in main(){while(1){sched_system();}My goal is to execute task1 every 20ms, and task2 every 40ms, but somehow I'm not able to get it right. I'm not sure what I'm doing wrong? I don't see the results on my LCD as expected.

Best Answer

Your ticks_for_scheduler variable simply counts from 0-99 over and over again, one count per millisecond. This means that it contains any particular value once every 100 ms.

In your main function, that's all you're checking for — whether the variable contains a particular value. So each task will only execute once every 100 ms.

My goal is to execute task1 every 20ms, and task2 every 40ms

In the most general case, where any given task needs to execute every N ms, you need to maintain a separate counter for each task. In the more constrained case in which every period N has a common multiple of 100 ms, you can use a modulo operator:

if (ticks_for_scheduler%20 == 0) (*task1)();
if (ticks_for_scheduler%25 == 0) (*task2)();

Note that 40 ms does not have 100 ms as a multiple, but you could make the ticks_for_scheduler run from 0-199 if you want to use 40 ms as an interval.

There's a more subtle problem here, too. You're assuming that sched_system() runs at least every 1 ms, so that it can "see" every possible value of ticks_for_scheduler. But if any given task runs for longer than 1 ms, this cannot be guaranteed. You need to take precautions that the operation of your scheduler cannot be perturbed by the tasks themselves, which is a topic far too broad to address here.