We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello new's group. My MCU is a ADuC7026. It has only two interrupt priorities, FIQ is high priority, IRQ is normal priority. I want to write a programm to generate some signals which are related to some sensor mesurements. Some of my cumputations are very resource killing. So this computations can only be performed not so often. So there are different task. The task with the highest priority has to be performed 200000 times per second. Another task with a middle priority has to be performed 25000 times per second. The next task with a mid-low priority has to be performed 2000 times per second. And one more task is to be performed 100 times per second. And the last task has to be performed 2 times per second with the lowest priority.
I hope i have explained this so someone can understand it. Of course maybe this is not the right Forum, but i use a keil compiler. My question is how can i programm all this different task without a operating system? Sorry, i'm not very experienced... :-)
Why do it without an operating system?
Anyway - you can not do it with the interrupts. They are not there to work as tasks, but to react to events.
A superloop can do a lot of things, but it requires that all tasks can be splitted down into small enough steps that each turn through the loop runs at least as fast as the fastest task you need to handle. This would mean that the 2 times/second task has to be split into sub-steps each taking less than 5us.
By the way: Have you started by making sure that the total computation time of all tasks are less than the total capacity of the processor? You need to have enough time left to handle interrupts and a bit of book-keeping and still have enough time left as safety margin for worst-case combinations.
Anyway - you can not do it with the interrupts.
Why not? Set up 3 timer interrupts to fire 200000, 25000 and 2000 times per second. Assign appropriate priorities to them (if the hardware allows.) Do the work in the corresponding ISR's. The time-consuming task can sit in the main loop. But I am concerned if the CPU is fast enough, too. If CPU clock is 40 MHz, then a 200000 times-per-second event only has 200 CPU cycles to be processed, that's not counting the other events...
The problem with doing everything with interrupts, is that all interrupt handlers are expected to be fast.
As I read the description, some of the tasks are not really fast. Having nested interrupts may possibly solve some of the problems, but the overhead of having 227002 interrupts/s is extremely high.
What may be possible is - if we assume the processor is fast enough - to only run the quickest task (or the quickest two tasks) in an interrupt handler and then do the rest in a polled loop.
But a big problem is the allowed jitter for each task. Life is easier if several of the calculations can be merged, i.e. not doing 25000 evaluations/second for task #2, but instead do 5 calculations at a time, but only 5000 times/second. Obviously the same thing for task #1. Task #3 is slow enough that the interrupt overhead can be ignored. Task #4 is very suitable for a main loop.
But the cost of a very high interrupt frequency is the big reason why communications devices normally has FIFO support - it is too expensive to take an interrupt for each received (or to be transmitted) character. If an ADC is involved - is it possible to run it in auto-mux mode, where it may scan 4 or 8 separate inputs automatically and where the ISR can pick up multiple ADC values at each interrupt?
Georg, your computation budget seems very tight. if your processor was doing nothing but the highest priority task, it would have to spend not more that 5 microseconds executing it before the next execution cycle. this period becomes even tighter when considering the total of 227102 times per second your tasks must do "something". that leaves you 1000000/227102 = 4.4 microseconds per task. now, with a rough estimate of 0.125 microsecond needed per instruction (that of course depends greatly on your specific MCU settings and if probably more, if you call functions or access external RAM...), you can run up to about 35 instruction per task before the next calculation must be performed. that is indeed tight, but you can try...
one more thing: if you choose to do it with interrupts, do bare in mind that you would have to take into account the extra overhead of handling them - hence, saving the processor context and recovering it. it sound to me like you would be running out of time, after all...
I have run multiple periodic threads like this without an RTOS in the past. My approach is hopefully described adequately by the following pseudocode. It is the timer ISR of a timer set to fire at the frequency of the most frequently required thread (200kHz in your example).
void Timer_ISR(void) { static int t = -1; ReEnableTimerInterrupt(); t += 1; HighFrequencyFunction(); if (0 == (t & 0x000f)) { MediumFrequencyFunction(); if (0 == (t & 0x00ff)) { LowFrequencyFunction(); } } }
The three functions are called at the timer rate, one sixteenth of the timer rate, and one 256th of the timer rate respectively. The structure is hopefully obvious, and it is clear how the frequencies can be altered, and the idea extended.
The key elements are that each of the functions is called periodically, and the priorities are linked to the call frequencies, in that the HighhFrequencyFunction() can interrupt MediumFrequencyFunction(), and MediumFrequencyFunction() can interrupt LowFrequencyFunction(). Any number of different frequencies (all must be divisions of the maximum, and it is convenient and efficient if they are power of two divisions) can be called with just one timer.
The details of getting this to work may require quite a deep understanding of how the processor handles interrupts, storing the context on the stack and such like. You also have to be certain that the worst-case execution time of each function does not exceed the period allocated to it, else you will get recursive calls and the stack will rapidly overflow.
However, having implemented this type of architecture on several processors over the last decade (8051, AVR etc) I am now a convert to the use of an RTOS in all but the most trivial of applications. As soon as you need to communicate between the threads, you will need locking primitives and such like, and then it becomes increasingly difficult to guarantee worst-case execution times, on which the above scheme absolutely depends.
I also share the concerns of the other respondents as to the wisdom of using a 200kHz timer interrupt for pretty much any purpose.
Christopher Hicks
Plus isnt there is a risk that due to inherent latencies and clock jitter one may probably end up losing data due to the processes not being able to make enough measurements?