Skip to content | Skip to navigation
Powered by RSPowered by RSPowered by RS

#define – Simple Embedded C Multitasking

jkvasan

India

Paul's blog deals nicely on several aspects on multi-tasking.

Multi-tasking as we know is all about doing several actions simultaneously or at least so fast so that it appears that all actions appear to happen simultaneously. When we switch an electric fan on, at the start we see a few blades rotating in a circular fashion. Once the fan picks up the speed, only a circular plate is visible. As we know, the blades are moving so fast, our eyes could not tell the difference.

Microcontrollers do several actions pretty fast and if we program them to do the actions sequentially yet in rapid succession, we could mimic the fan’s characteristics. For the user of the end product, it never appears that the particular gadget is doing things one by one.

 

 However, this is not easy for several reasons. One primary reason is that most gadgets have displays, keypads, sensors,etc, which either work slowly or act suddenly to events. This means, if the microcontroller works on one peripheral after another, the concept of simultaneous action goes for a sixer.

In practical terms, the only way available for the designer using speed-starved microcontrollers  is to split these tasks.

 

Splitting or breaking the tasks into small sub-tasks resulting in  each sub-task getting done in a jiffy helps in minimising the time spent on each sub-task. Each time a sub-task is completed, the status is noted and whenever the status changes , the next sub-task is executed.

 

Thus, we get all the tasks executed almost simultaneously through what is called ‘Time-Slicing’ approach.

 

The code provided below attempts to provide an understanding on how this can be realised.

 

We need simple counters to keep track of each of these subtasks. To make it more convenient, let us package flags with these counters to inform that it is time for the next sub-task.

 

#define                                KEY_SCAN_INTERVAL    5

#define                                DISPLAY_INTERVAL         10

// Declare a Structure

struct MyStruct{

                                unsigned Flag : 1;

                                unsigned int Counter;

                                }KeyScan,Display;

unsigned char KeyscanState,DisplayState;

 

// Timer Interrupt Routine

void TimerIsr(void)

                {

                if(KeyScan.Flag==0)

                                {

                                if(++KeyScan.Counter>KEY_SCAN_INTERVAL)

                                                {

                                    KeyScanState++;

                                                KeyScan.Flag=1;

                                                KeyScan.Counter=0;

                                                }

                if(Display.Flag==0)

                                {

                                if(++Display.Counter>DISPLAY_INTERVAL)

                                                {

                                    DisplayState++;

                                                Display.Flag=1;

                                                Display.Counter=0;

                                                }

                }

 

void KeyScanTask(void)

                {

                switch(KeyScanState)

                                {

                                case 0:

                                //Do First SubTask

                                break;

                    case 1:

                                //Do Second SubTask

                                break;

 

                                // and so on

                                }

                }

 

void DisplayTask(void)

                {

                switch(DisplayState)

                                {

                                case 0:

                                //Display Units Digit

                                break;

                    case 1:

                                //Display Tens Digit

                                break;

 

                                // and so on

                                }

                }

Comments

JorgeMendez

Guatemala

45 weeks ago

Great intro and example. Keep them coming Please!

dwendelboe

United States

45 weeks ago

Very good example. Many micros have more than one timer, so Paul's concept can be extened by using separate timers. I recently placed a PID control algorithm in a separate timer interrupt. The PID kept the deck temperature of a biomed device at a constant 22 deg C. Initialize it and forget it. Worked great as a complete separate background task with no connection or interaction with the primary tasks.