Forums

RTOS popularity

Started by Philipp Klaus Krause December 26, 2015
Wouter van Ooijen <wouter@voti.nl> wrote:

> Note that there is a middle way between pre-emptive (with the nice can > of worms labeled '(absence of) mutual exclusion errors') and > run-to-competion (with the headache pills labeled 'where do I store my > context'): cooperative.
For coperative multitasking, consider also Ethernut. It first started with the AVR8, so it has 8-bit in mind. It also include AVR32 and several ARM. I have done a lot on STM32. As STM32 peripherals evolved from STM8 peripherals, work for the STM8 can perhaps profit from this work. However I must admit that my work on the STM32 peripherals didn't have STM8 in mind. Adapting ethernut for SDCC probably will need some work. But the comon code already cared for non-gcc compilers. Bye -- Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt --------- Tel. 06151 1623569 ------- Fax. 06151 1623305 ---------
On Wed, 06 Jan 2016 14:49:30 +0100, Philipp Klaus Krause wrote:

> On 04.01.2016 10:32, pozz wrote: >> Il 26/12/2015 19:54, Philipp Klaus Krause ha scritto: >>> There are a lot of RTOSes around. I wonder which are the most used >>> ones. >>> In particular, I'm interested in the free ones supporting the STM8, >>> which currently are: >>> >>> * OSA * atomthreads * ChibiOS * ScmRTOS >>> >>> But I'd also like to know about the general 8/16-bit situation. >> >> Maybe you already made this question to yourself. Anyway I make it: why >> do you need a RTOS on those kind of platforms? >> >> >> > People are writing RTOSes for 8-bit platforms, so I guess there are > people wanting to use them. > So if I want a reasonably complete toolchain for those platforms to > exist, some RTOSes should be ported to free compilers.
I'm not sure I follow your reasoning on this. I will comment that RTOSs tend to use up considerably more memory and clock ticks than the usual "ISRs and a task loop" scheme that you see in 8-bit processors. In this day and age, if you're cost-constrained enough to use an 8-bitter, I would expect you'd be willing to go the extra mile and not use an RTOS, to save the expense of the more capable processor you'd need to host it. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
Wouter van Ooijen wrote:
> Op 06-Jan-16 om 7:09 PM schreef Les Cargill: >> upsidedown@downunder.com wrote: >>> On Mon, 4 Jan 2016 10:32:38 +0100, pozz <pozzugno@gmail.com> wrote: >>> >>>> Il 26/12/2015 19:54, Philipp Klaus Krause ha scritto: >>>>> There are a lot of RTOSes around. I wonder which are the most used >>>>> ones. >>>>> In particular, I'm interested in the free ones supporting the STM8, >>>>> which currently are: >>>>> >>>>> * OSA >>>>> * atomthreads >>>>> * ChibiOS >>>>> * ScmRTOS >>>>> >>>>> But I'd also like to know about the general 8/16-bit situation. >>>> >>>> Maybe you already made this question to yourself. Anyway I make it: why >>>> do you need a RTOS on those kind of platforms? >>> >>> >>> Why not ? >>> >>> If you just have less than 10 KiB of code and a single programmer, >>> some simple state machines would be enough. >>> >>> With tens of KiB of code or multiple programmers, the project >>> management with a pre-emptive RTOS simplifies a lot. I have used small >>> pre-emptive kernels at least for 8080/8085/6502/6809. >>> >>> >> >> >> Preemptive opens up a lot of disparate and ugly cans of worms. With >> "run to completion". you can get a lot closer to proving the system >> correct to within some epsilon ( sometimes a rather large epsilon ). >> >> The only thing preemptive gets you is if somebody's thread is taking too >> long, you jerk the CPU away from them. Well, maybe you really want that >> to be an exception rather than a context switch. >> >> "Mulitple programmers" is more about configuration management >> discipline, unit and integration testing than architecture >> anyway. > > Note that there is a middle way between pre-emptive (with the nice can > of worms labeled '(absence of) mutual exclusion errors') and > run-to-competion (with the headache pills labeled 'where do I store my > context'): cooperative. >
Right you are, although the differences between run to completion and cooperative are quite subtle. "Run to completion" is really a strategy based on a cooperative multitasker or a "big loop" ( meaning "no bespoke O/S") architecture.
> Wouter van Ooijen >
-- Les Cargill
Niklas Holsti wrote:
> On 16-01-06 20:09 , Les Cargill wrote: >> upsidedown@downunder.com wrote: >>> On Mon, 4 Jan 2016 10:32:38 +0100, pozz <pozzugno@gmail.com> wrote: >>> >>>> Il 26/12/2015 19:54, Philipp Klaus Krause ha scritto: >>>>> There are a lot of RTOSes around. I wonder which are the most used >>>>> ones. >>>>> In particular, I'm interested in the free ones supporting the STM8, >>>>> which currently are: >>>>> >>>>> * OSA >>>>> * atomthreads >>>>> * ChibiOS >>>>> * ScmRTOS >>>>> >>>>> But I'd also like to know about the general 8/16-bit situation. >>>> >>>> Maybe you already made this question to yourself. Anyway I make it: why >>>> do you need a RTOS on those kind of platforms? >>> >>> >>> Why not ? >>> >>> If you just have less than 10 KiB of code and a single programmer, >>> some simple state machines would be enough. >>> >>> With tens of KiB of code or multiple programmers, the project >>> management with a pre-emptive RTOS simplifies a lot. I have used small >>> pre-emptive kernels at least for 8080/8085/6502/6809. >>> >>> >> >> >> Preemptive opens up a lot of disparate and ugly cans of worms. With >> "run to completion". you can get a lot closer to proving the system >> correct to within some epsilon ( sometimes a rather large epsilon ). > > Without preemption, how are you going to combine sporadic or periodic > short, urgent computations, with longer, less urgent computations? By > using interrupt handlers (i.e. pre-emption of a sort) for all the urgent > stuff? Or by manually slicing the longer computations into short "run to > (intermediate) completion" steps? The latter leads to a real mess, IMO. >
You simply manage it. It's much less horrible than it sounds. You set things up to where each run through a thread/task/routine must complete within a rigorous time budget. You can also set things up to where there's global state that indicates that the high priority stuff needs to run. It all depends on how deterministic you want the system to be. If there's no preemption, you can have the advantage of more deterministic behavior. And yes - I'd be perfectly happy using (software) interrupts, perhaps triggered by a hardware/timer ISR to enable high-priority processing without the benefit of a kernel. And rather than a full-on kernel, you might just have something equivalent to the Linux "ucontext()" call to separate the background processing from the high-priority stuff. But you still need to get in and get out at all times. If you're *careful*, you can enable the "ucontext()" thing to switch in middleware driven by a timer/hardware interrupt. Just about anything that can be done with a kernel can be done without one, up to a limit where it just gets too ugly to look at. In reality, if you can get posix threads working, it's hardly worth worrying about. But on a small 8-bitter, you might need to think differently. -- Les Cargill
Dimiter_Popoff wrote:
> On 06.1.2016 &#1075;. 20:09, Les Cargill wrote: >> ... >> Preemptive opens up a lot of disparate and ugly cans of worms. > > ... > > Not really if you know what you are doing. Processors have user and > supervisor levels for a reason, there is nothing special about > switching user level tasks without them needing to know it (i.e. > preemptively). Can be useful under severe system load and is definitely > a remedy against poorly written code which tries to hog the > system for no good reason.
I'd rather fix the code, myself.
> And even for good code for good reason, > say computationally intensive tasks - they don't have to bother > how much system time they take, just get on with it while the > system takes care of the scheduling. >
Lotta trades in this space.
> Dimiter > > ------------------------------------------------------ > Dimiter Popoff, TGI http://www.tgi-sci.com > ------------------------------------------------------ > http://www.flickr.com/photos/didi_tgi/ >
-- Les Cargill
Dimiter_Popoff wrote:
> On 06.1.2016 &#1075;. 19:35, upsidedown@downunder.com wrote: >> ... I have used small >> pre-emptive kernels at least for 8080/8085/6502/6809. >> > > And no 6800 or HC11? Come on :-). > > The first MT kernel I wrote was for the 6809... maintained a bitmap > of memory clusters to allocate/deallocate on dynamic requests by tasks > (there was no need for that but I was doing what I thought was > interesting to do...). My second one was 68020, a one-off thingie > which I did for my then employer in Cologne (late 80-s). > > Oops, I never wrote a 6800 kernel really :D. Just a HC11 - no dynamic > RAM allocation of its 512 bytes though... > > I never touched a 6502/80xx part though. >
On 8086/8088/80286/80386, it was not uncommon to fake multitasking on top of DOS, whether with Terminate and Stay Resident or just by butching together a threading library which respected the DOS Critical Section Flag. This was extremely deterministic, down to the jitter on the various clocks. "Why on Earth would you do that???" you may ask - well, it was nice to have the programming just about done while the hardware guys did whatever it is they do. And once you got the basic infrastructure in place, it was eminently useful for things like test fixtures, or even products sometimes. Besides, it was cool :)
> Dimiter > > ------------------------------------------------------ > Dimiter Popoff, TGI http://www.tgi-sci.com > ------------------------------------------------------ > http://www.flickr.com/photos/didi_tgi/ > >
-- Les Cargill
Dimiter_Popoff  wrote:

>And no 6800 or HC11? Come on :-).
Motorola provided a free one for the '11, "MCX11." (Written in assembler.) R.W.
On Wed, 6 Jan 2016 12:09:24 -0600, Les Cargill
<lcargill99@comcast.com> wrote:

>upsidedown@downunder.com wrote: >> On Mon, 4 Jan 2016 10:32:38 +0100, pozz <pozzugno@gmail.com> wrote: >> >>> Il 26/12/2015 19:54, Philipp Klaus Krause ha scritto: >>>> There are a lot of RTOSes around. I wonder which are the most used ones. >>>> In particular, I'm interested in the free ones supporting the STM8, >>>> which currently are: >>>> >>>> * OSA >>>> * atomthreads >>>> * ChibiOS >>>> * ScmRTOS >>>> >>>> But I'd also like to know about the general 8/16-bit situation. >>> >>> Maybe you already made this question to yourself. Anyway I make it: why >>> do you need a RTOS on those kind of platforms? >> >> >> Why not ? >> >> If you just have less than 10 KiB of code and a single programmer, >> some simple state machines would be enough. >> >> With tens of KiB of code or multiple programmers, the project >> management with a pre-emptive RTOS simplifies a lot. I have used small >> pre-emptive kernels at least for 8080/8085/6502/6809. >> >> > > >Preemptive opens up a lot of disparate and ugly cans of worms.
I have successfully used preemptive operating systems for 40 years.
>With >"run to completion". you can get a lot closer to proving the system >correct to within some epsilon ( sometimes a rather large epsilon ).
Like Windows 3.x environment :-) :-)
>The only thing preemptive gets you is if somebody's thread is taking too >long, you jerk the CPU away from them. Well, maybe you really want that >to be an exception rather than a context switch.
The first thing in RTOS system design is to divide the application to manageable tasks, estimate how long each needs to run and assign priorities to the tasks. If there are performance problems with some tasks, never try to increase the priority of the starving task, instead look for other tasks, which priority can be _lowered_ without suffering too much, if interrupted by a short run time high priority tasks. Use a server task for each resource such as serial port or shared data structure, so not much need for object locking (with priority inversion etc. issues).
On Wed, 6 Jan 2016 20:43:43 +0200, Dimiter_Popoff <dp@tgi-sci.com>
wrote:

>On 06.1.2016 ?. 19:35, upsidedown@downunder.com wrote: >> ... I have used small >> pre-emptive kernels at least for 8080/8085/6502/6809. >> > >And no 6800 or HC11? Come on :-). > >The first MT kernel I wrote was for the 6809... maintained a bitmap >of memory clusters to allocate/deallocate on dynamic requests by tasks >(there was no need for that but I was doing what I thought was >interesting to do...). My second one was 68020, a one-off thingie >which I did for my then employer in Cologne (late 80-s). > >Oops, I never wrote a 6800 kernel really :D. Just a HC11 - no dynamic >RAM allocation of its 512 bytes though... > >I never touched a 6502/80xx part though.
A preemptive system requires private stacks for each task. thus some stack pointer relative addressing modes would be nice, which unfortunately lacks in many older 8 bitters. Even with such old processors, one could allocate the stack spaces at compile/link time, thus each task could use precompiled absolute addressing to access your data.
On 06/01/16 19:35, Wouter van Ooijen wrote:
> > Note that there is a middle way between pre-emptive (with the nice can > of worms labeled '(absence of) mutual exclusion errors') and > run-to-competion (with the headache pills labeled 'where do I store my > context'): cooperative. >
Another middle way that I often use is a three layer system. At the bottom, you have the main loop, which is where you have the longer-term tasks (they can be just as critical as anything else in the system, but not with critical timing). And at the top, you have your interrupts for immediate response (motor control, UART buffers, etc.). So far, that's "standard bare metal". Now in the middle, you have a layer of "software timers". These are handled from a timer interrupt at a regular rate (such as 100 Hz or 1000 Hz, depending on the requirements and the hardware). The timer interrupt first makes sure that other interrupts are enabled, so that the critical interrupts can break in. Then you run each of the time-dependent or repetitive tasks as frequently as needed, from within the same context. It makes it easy to have tasks that are shorter but more time-critical than "background mainloop" tasks, but not interrupt functions. It makes it easy to know exactly what can pre-empt what - interrupts can pre-empt software timers and mainloop, and software timers can pre-empt mainloop - but you can never get pre-emptions the other way, or between software timer tasks. Sharing data between tasks becomes easy - between software timer tasks, you can have global data. Up and down between mainloop and software timers or interrupt functions, careful use of "volatile" and perhaps memory barriers is sufficient - no need for locks, queues, shared data, etc. And no need for multiple stacks, race conditions, deadlock, or the dreaded "it worked fine in all our testing, but fails in the field" challenges of using an RTOS.