Archive | Embedded Programming RSS feed for this section

#define – Simple Embedded C Multitasking

19 Mar

An interesting video on multitasking

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
}
}
DesignSpark – 29/06/11

Advertisements
%d bloggers like this: