Monday 12 December 2016

Implementation of Task Scheduler


Implementation of Task Scheduler with Function pointer
“In this blog we will discuss how to implement Task Scheduler in Embedded C programming”
Implementing Task Schedulers mainly require following steps:

  • Define task interval Counter Value
  • Define Task
  • Structure Declaration
  • Function Prototyping
  • Function Definition
  • Array of Structure Declaration
  • Main Routine

Define task interval Counter Value


In this example we have run a timer with ISR with 100 usec interrupt. System_Time_Counter value will be incremented in Timer ISR.

System_Time_Counter value for 1ms Interval = 10

System_Time_Counter value for 5ms Interval =  50 

 For all tasks we define macros for task interval value described below:



#define TICK_5ms      50     // 5ms = 5×10

#define TICK_10ms     100    // 10ms = 10×10

#define TICK_50ms     500    // 50ms = 50×10

#define TICK_100ms    1000   // 100ms= 100×10

#define TICK_200ms    2000   // 200ms= 200×10



After this we define as macros of NO_OF_TASK we want to execute


#define NO_OF_TASKS    5



Function Prototype


Function prototyping should be done before Task table declaration:

void TASK1_FUNC(void);

void TASK2_FUNC(void);

void TASK3_FUNC(void);

void TASK4_FUNC(void);

void TASK5_FUNC(void);


Function Definition


In function definition I have toggling a GPIO pin to check the execution time of each task:



void TASK1_FUNC(void)

{

TOGGLE_PIN1;

}

void TASK2_FUNC(void)

{

TOGGLE_PIN2;

}



void TASK3_FUNC(void)

{

TOGGLE_PIN3;

}





void TASK4_FUNC(void)

{

TOGGLE_PIN4;

}



void TASK5_FUNC(void)

{

TOGGLE_PIN5;

}



Structure Declaration Task Table Declaration


In this we declare a structure TASK_STRUCTURE for task table. In structure declaration defines three parameters i.e. function pointer associated with each task, Task repetitive interval and Task_Last_Execution_Time as shown in below:



typedef struct{

   void (TASK_FUNC)(void);

   unsigned int Repititive_Execution_Times;

   unsigned int Task_Last_Execution_Time;

  }TASK_STRUCTURE;



After this make the table of each task by making an array of structure:

TASK_STRUCTURE TASK_STRUCTURE _ARRAY[]=

       {

           {TASK1_FUNC,  TICK_5ms  , 0 },
           {TASK2_FUNC,  TICK_10ms  , 0 },
           {TASK3_FUNC,  TICK_50ms  , 0 },

           {TASK4_FUNC,  TICK_100ms  , 0 },

           {TASK5_FUNC,  TICK_200ms  , 0 }

      };

Initial value of Task_Last_Execution_Time set to zero.



Main Routine


In main routine we run a for loop using TASK_INDEX to execute all tasks. Here SYSTEM_TIME is the counter that is running in Timer ISR and incremented after every 100 usec. 

unsigned char TASK_INDEX=0;

static TASK_TYPE *TASK_PTR;      
// Pointer Declaration for Task Array

TASK_PTR= TASK_STRUCTURE _ARRAY;      

           

           

for(TASK_INDEX=0;TASK_INDEX<NO_OF_TASKS;TASK_INDEX++)

{

  if((SYSTEM_TIME-TASK_PTR[TASK_INDEX].LAST_EXECTION_TICKS)>=     TASK_PTR[TASK_INDEX]. Repititive_Execution_Times)

    {

       (*TASK_PTR[TASK_INDEX]. TASK_FUNC)();    // function call

TASK_PTR[TASK_INDEX]. Task_Last_Execution_Time =SYSTEM_TIME;

//Copy SYSTEM_TIME in Task_Last_Execution_Time value.

    }

}



So this is the implementation of Task Scheduler using function pointer. If you want to add more task functions these can be implemented easily. If any task requires higher priority of execution it can be map on the External Interrupt event.

No comments:

Post a Comment