pjv's RTOS adapted to preemptive single main level interrupt task
Peter Verkaik
Posts: 3,956
Hi (pjv and others),
Pjv, I adapted your RTOS to have a single preemptive task
that is to be executed as if it were the main interrupt task.
The idea is to have a single preemptive task that executes
at the main code level (but outside isr) at a much lower rate than the
isr itself. The isr is to be used by VP code, whereas the main isr code
is to be used with a timer list to run small routines that are not timecritical.
Having only one task·allowed me to save the main code context in the fifo.
Could you comment on this setup?
regards peter
Pjv, I adapted your RTOS to have a single preemptive task
that is to be executed as if it were the main interrupt task.
The idea is to have a single preemptive task that executes
at the main code level (but outside isr) at a much lower rate than the
isr itself. The isr is to be used by VP code, whereas the main isr code
is to be used with a timer list to run small routines that are not timecritical.
Having only one task·allowed me to save the main code context in the fifo.
Could you comment on this setup?
regards peter
Comments
Perhaps I am somewhat dense, but I don't totally grasp the significance of what you're trying to accomplish; albeit you have significantly simplified the RTOS I posted, but also imposed limitations.
If you are running a timer/scheduler in the mainline, and the mainline can be pre-empted and its context saved, you are stuck with interrupting only a single mainline thread. The scheduler will require that all other mainline threads be completed before a new one may be scheduled.
While that may have merit in low activity circumstances, I believe it is rather limiting if there are many threads (I often have a dozen) and if any of those take a long time to complete.
I recognize that you still will run VP's in the ISR......that is something I was wanting to get (mostly) away from; the exception being very short PWM DAC's that, for precision, require execution at EXACTLY the same time every pass. So, I end up using the ISR (almost) only for running the RTOS.
While I have not stated as much, the pre-emptive RTOS that was posted as my contest entry had some bugs and inefficiencies, and is now totally re-written and improved. It consumes only 99 bytes of code, and I think some 35 instructions per interrupt "tick", but alas, almost half the SX28 RAM if one implements all 8 (this is not a requirement) thread levels.
I have now used this improved RTOS in a number of applications, and have found it to be quite robust. It is very convenient to have up to 8 threads run, each one interruptable by a higher priority, and then carry on where it left off when it is restored. The only (obvious) caveat being that each thread be finished before it is re-started again; ie they are not re-entrant.
I will take a closer look at what you have done, and also run the code you have provided to try and gain a better insight into what you are up to.....at first scan I think I see some errors, but that could be that I don't yet fully understand it.
Cheers,
Peter (pjv)
Post Edited (pjv) : 2/11/2006 9:12:11 PM GMT
The mainlevel code can only be interrupted by the sx isr routine, which has·limited instruction
cycles (in my example program 217). What I do is create a new mainlevel isr that is
executed every N'th sx isr cycle. This mainlevel isr executes as mainlevel code (and thus gets
interrupted by the sx isr) but it appears as an interrupt routine to the·mainloop code.
This mainlevel isr·can have more instruction cycles than the sx isr routine.
So I don't have multiple threads, but still only one thread, but with an interrupt routine
that can be larger. It is intended for lower frequency events like·postprocessing
serial receive events, scheduled timer events etc. It is not intended as a tight realtime design,
unlike your RTOS. I got this idea after studying an old MSX BIOS listing (home computer mid 80's)
where there is an interrupt cycle every 20 millisecs in which a complete keyboard was scanned,
several uarts were processed and some other checks. For my applications, that mostly involve
uarts,·this approach may work well, without the overhead of saving context for preemptive
threads (the mainlevel isr, being an interrupt routine by definition, must always completes its code and has
no context that must be saved).
I hope this clarifies what I had in mind.
BTW, can I have a view on your rewritten RTOS?
regards peter
Well, I took a closer look at things, and have suggested some simplifications and some corrections I believe are required as attached. I think I made notes on all changes in the comment section.
Unfortunately one cannot debug this code with the SX-Key, because that devices uses and hence alters the contents of the 8 level FIFO.
That said though, you probably have some suitable application code to merge it with, so give it a try, and let us know what happens.
Cheers,
Peter (pjv)
I think I've got it right now.
One question though, just before pushstat in saveMainLoopContext,
you clear w to make reti work.
In your original RTOS you have in startT1
··mov·w,#T1uSec10>>4&$E0·;high 3 address bits
··pushstat···;prep thread address hi
which preserves the high 3 bits of the T1 thread code.
But these are already loaded in pc shadow.
Why must these status bits be setup, and if so, shouldn't
I setup status with 3 high bits of MainIsr address instead of 0?
regards peter
Please remember what you are referring to is my old version of RTOS, and it had some bugs; the new one is quite different.
That said, I will explain that in this case I DID want to pre-set the status high page bits so that any subsequent jumps I did in the T1 thread would already be to the proper page. In your case, you suggested initializing the (Main) ISR routine irrelevant, so I stuck the ISR page set-up in the MainISR itself.
And I won't go into the reasoning here, but bits 4 and 3 if the status need to be set to zero in the status shadow.
Hope this helps!
Cheers,
Peter (pjv)
To me, your RTOS project has been one of the most interesting and most puzzling of the 2005 contest winners. It has taken me quite a bit of time to appreciate what you have done.
As I am still learning, I just haven't gotten deeply into the code yet. Since you say that it had bugs, I am sure many of us would like to see the revision. Nonetheless, I can also understand if you feel it is something you want to keep to yourself.
It shows a certain brilliance.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"When all think alike, no one is thinking very much.' - Walter Lippmann (1889-1974)
······································································ Warm regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
I think you may be overdoing it with "brilliance". Anyone with a good load of assembler experience, a logical approach and a LOT of persistance can accomplish the same things.
However, I do appreciate your recognition.
As for now, I'm trying to decide about commercializing this effort, so I'm being a bit secretive.
Cheers,
Peter (pjv)
One of the mainstream PIC authors, Mike Predko, has another RTOs. I started reading both his material and yours in depth. He manages to set a limit to how much RAM is used. His introduction to it makes is all the more appealing as he refers to it as 'one of the most-useful application programming environments that can be used in a microcontroller'.
Since you seem to be the first to try it on the SX, I don't think 'brilliance' is too strong. Most of us are just interfacing hardware rather than thinking about the 'meta-structure' that software can create, even with a tiny 8-bit unit.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"When all think alike, no one is thinking very much.' - Walter Lippmann (1889-1974)
······································································ Warm regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
Post Edited (Kramer) : 2/15/2006 8:27:11 AM GMT