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.