I'm working on a project to implement a simple, priority based, rate monotonic real-time task scheduler. I already completed task structures, task creation function and task scheduling algorithm. Scheduler works with timer interrupt periodically. Then it decides which task to run in next time slice. My problem is as follows, I want to make my scheduler pre-emptive. So while task-1 is running, and scheduler runs with interrupt, and if it decides task-1 should wait and task-2 should work in next time slice, I need to do context saving. Stop executing task-1 and run task2. But I can not figure out how to do this exactly. Because when timer interrupt occurs and timer-1 pauses for a while, normally after the interrupt handler function completes, program counter will return back to last execution address of task-1. But probably I won't want to program counter return back to task-1 after scheduler execution on timer-1, I might want it to jump to task-2 instaad of task-1. So, I think I have to take all control of interrupt mechanism and do returns etc manually. What do you suggest me to read and try?
Sobak Ava wrote: > But I can not figure out how to do this exactly. Because when timer > interrupt occurs and timer-1 pauses for a while, normally after the > interrupt handler function completes, program counter will return back > to last execution address of task-1. That does not happen automatically. Take a look at how an interrupt handler works in assembler: the return address is taken from the IRQ link register (LR_IRQ) and copied to the program counter (PC). Instead you can simply do this: save the contents of LR_IRQ somewhere so that you know where to continue with task1, and load the saved address of task2 to the program counter. Voila, task2 is running. There are plenty of open source scheduler implementations around that you can learn from, for example FreeRTOS.
Yes I know Free-RTOS. It is nice but I'm trying to implement so simple scheduler and Free-RTOS is too deep to trace and understand how does task scheduling works. Do you know any other simple scheduler ( I do not need all OS ) for ARM7?
Well, it is not really a problem of how to do the sheduling startegie. Eventually all schedulers have the same problem: How to do the context switch from one task to the next task. This is a problem, which cannot be solved by pure C-code alone. So you can take any task scheduler you know of, eg. Free-RTOS and study the core to figure out how the context switch is done.
Actually it can be done in C by abusing setjmp and longjmp (at least for a non-preemtive scheduler), but that's about as ugly as hacks get.
The method a pre-emptive scheduler uses is to switch the stack pointer (for the mode in which your tasks will run - USER or SYS) to the stack of the task that should run next, and also to fix up the stack (or on ARM, I think the link register) so that on return-from-interrupt, the Program Counter for the ready task task is loaded rather than the original return address. Of course this also means you need to store the PC of the pre-empted task - that is usually stored in a Task Control Block (TCB). For a thorough treatment of the subject, you should read Jean Labrosse's "MicroC/OS II: The Real time Kernel", and then look at the ARM ports for it available on the Micrium website. I think you will struggle without a deeper understanding. You should also read the ARM Insider's Guides available free from Hitex. they explain ARM interrupt mechanisms and calling conventions and mode switching. You will also need a little ARM assembler knowledge. Clifford
Would this article help out ? http://www.embedded.com/columns/technicalinsights/190302110?_requestid=547647 There is an AVR/NXP implementation on avrfreaks By Artur Lipowski http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=725&item_type=project But i think you might have to register to see/download it. Bingo