Multitasking in AVR (A demo to run 7 tasks on an atmega32)


Switching multiple tasks on a same CPU is the one of the major function of an operating system. What I did now is a time sharing multitasking (time multiplexing) on an AVR. Here an atmega32 is configured to use Round-Robin Multitasking. Round-Robin allows quasi-parallel execution of several tasks. Tasks are not really executed concurrently but are time-sliced (the available CPU time is divided into time slices).
Here, in my code below, it consist of 7 independent tasks and those are switched from one to another on a timer interrupt. ‘May be’ this could be considered as a simple & very basic RTOS demo…
Scheduling algorithm used: Round-robin (RR)
(one of the simplest scheduling algorithm)
Each led on the demo represents a task. Task1 (right most led, WHITE) is a software PWM task. All other tasks (2 to 7 from right to left) are toggling tasks. If you concentrate on a single LED, U may notice that the particular LED is toggling with a constant delay and is independent of others.


 Here, total RAM (2KB) is divided among 7 tasks almost equally in such a way that each one get around 300 bytes of RAM space. This 300 bytes is considered as the stack for each task. When the timer reaches the compare value, it trigger an interrupt. Now inside ISR, at first all the registers are pushed onto it’s stack. Program counter is already push (automatically) at first when the interrupt is triggered. Now after pushing all the registers, the status register is pushed onto the stack(avr doesn’t do it automatically). Thus we made a backup of all the register values and the status register and we are safe to use those register for some other purpose. Now the next process is the switching between tasks ie the context switching. Before that we need to backup the current stack pointer otherwise we will miss it and couldn’t resume the task when it’s time slot appears for the next time. So a 50(more than enough) bytes are reserved from the RAMEND to store the task index(which task is running now) and the stack pointers of all the tasks. This is considered as the stack pointer backup table or array.

Multitasking in AVR (A demo to run 7 tasks on an atmega32)

Now, when the task1 is interrupted by the switching timer interrupt, as said above, it push all CPU registers and the status register. Then it checks the ‘task index’ which will be there on the RAMEND. From the task index, we get the task number and thus we can obtain the exact location on the stack backup table on which the stack pointer value is to be stored. Also we can get the next task’s stack pointer value relative to the location where we stored the current one and that is loaded to the stack pointer.

So, we got the stack pointer of the next task. Now, we can pop the status register and all the cpu registers and finally the RETI instruction will enable the global interrupt and then divert (jump to new PC value) the cpu to resume the next task…. This repeats with a time slot in range of micro seconds and thus we feel all the tasks are running in parallel and also purely independent even though they are using the same cpu registers in common.

Here are some pictures which I drawn to make the above explanation more clear. It represent the RAM usage for the stack pointer backup table and the process stack.

For more detail: Multitasking in AVR (A demo to run 7 tasks on an atmega32)

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top