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.

  • 2
    ticks_for_schedulerneeds to be declared volatile. – brhans Oct 8 '17 at 15:21

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.

  • The systick is configured to generate an interrupt every 1ms, i checked it.I would need an oscilloscope to check if it is exactly 1ms. :)O my, you're right i can't make sure that one task takes longer than 1 ms. I guess i need to redesign the whole thing. Thanks! – Abel Tom Oct 8 '17 at 16:39

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.