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.
Working:
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.
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.
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.
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish.ACCEPTPrivacy Policy
Manage consent
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.