From: Vladimir Vassilevsky on

Some people are fine with for(;;) { loop }.
Some other people use C#.net or LabView.
What is the point?
Use whatever means adequate for your application.

VLV



Tim Wescott wrote:
> I pontificated by saying that a complete RTOS should have both binary
> and counting semaphores, and someone called me on it by asking just what
> a "complete" RTOS is.
>
> I realized that my definition of a "complete" RTOS is pretty fuzzy --
> mostly a mismash of every feature that I've ever wanted to use in an
> RTOS, with none of the features that I didn't want to use. This is
> ironic, because I also made a snide comment about RTOS vendors being
> self-centered.
>
> I know what the minimum set of features I want in an RTOS -- basically a
> prioritizing scheduler with deterministic performance, that allows tasks
> to be started under the programmer's control from software entities
> outside of the task. This gives you all the tools you need to fire off
> tasks from ISRs or other tasks, to block on resources, pass messages, etc.
>
> But what is a "complete" RTOS then? And if there is one, does anyone
> want it? Is a "complete" RTOS just like a CISC instruction set, wasting
> code space on features that one may never use, just so a vendor can crow
> about it being "all there"?
>
> And do you think my "minimum necessary" RTOS really includes everything
> you need? Or do you think that it's just not functional until you can
> pass messages and have Bertie Bott's Every Flavor Flag and Ethernet and
> USB and a hard drive and cotton candy on a stick?
>
From: 42Bastian Schick on
On Sat, 29 May 2010 11:09:32 -0700, Tim Wescott <tim(a)seemywebsite.now>
wrote:

>I pontificated by saying that a complete RTOS should have both binary
>and counting semaphores, and someone called me on it by asking just what
>a "complete" RTOS is.
>
>I realized that my definition of a "complete" RTOS is pretty fuzzy --
>mostly a mismash of every feature that I've ever wanted to use in an
>RTOS, with none of the features that I didn't want to use.

Actually I think a 'complete' RTOS is in the same category as the
perfect programming languange: It just does not exist.

It always like this: The hammer needs to fit the nail, else your thumb
gets hurt.

My problem with above statement of yours is that I am from the message
passing school. I write/wrote kernels and these do not offer
semaphores as part of the kernel because I strongly believe that
_direct_ message passing leads to better designed software.

But in paper-evaluations people ask for semaphores, so we need to
lenghty explain why my RTOS does not have it :(


>And do you think my "minimum necessary" RTOS really includes everything
>you need? Or do you think that it's just not functional until you can
>pass messages and have Bertie Bott's Every Flavor Flag and Ethernet and
>USB and a hard drive and cotton candy on a stick?

I think this is another problem I have with the _new_ embedded
engineers: They do not know the difference between a PC running
Windows,Linux or MAC OS (or ...) and an embedded device running an
RTOS kernel.

--
42Bastian
Do not email to bastian42(a)yahoo.com, it's a spam-only account :-)
Use <same-name>@monlynx.de instead !
From: Tim Wescott on
On 05/29/2010 12:25 PM, 42Bastian Schick wrote:
> On Sat, 29 May 2010 11:09:32 -0700, Tim Wescott<tim(a)seemywebsite.now>
> wrote:
>
>> I pontificated by saying that a complete RTOS should have both binary
>> and counting semaphores, and someone called me on it by asking just what
>> a "complete" RTOS is.
>>
>> I realized that my definition of a "complete" RTOS is pretty fuzzy --
>> mostly a mismash of every feature that I've ever wanted to use in an
>> RTOS, with none of the features that I didn't want to use.
>
> Actually I think a 'complete' RTOS is in the same category as the
> perfect programming languange: It just does not exist.
>
> It always like this: The hammer needs to fit the nail, else your thumb
> gets hurt.
>
> My problem with above statement of yours is that I am from the message
> passing school. I write/wrote kernels and these do not offer
> semaphores as part of the kernel because I strongly believe that
> _direct_ message passing leads to better designed software.

I had a really bad experience in my engineering youth that took me
almost ten years to get over. It was an application that used message
passing, but it was clear that the developers had read the OS manual's
chapter on message passing then misunderstood it.

They had one task that received messages over a serial port, parsed them
to figure out where they should go, and dispatched them as OS messages.
There's nothing with that, except that one of the tasks that received
messages controlled two motors doing two entirely different things. The
basic loop for that task was:

* check a message
* parse it
* if something for a motor to do
* do that thing
* go back to start

One motor's commands were basically "go up" or "go down", and the
increment took 50 or 100 milliseconds. The other motor's commands were
"go to point A" or "go to point B", and took two seconds.

If I grabbed the system controller and alternately hit the "point A"
button then the "point B" button long enough, the message queue would
fill. The OS or the code (I'm not sure which -- it wasn't good code)
really didn't respond well to a message queue filling, and about half of
the tasks in the system would stop talking to one another, leaving the
system so badly wedged that it needed a power cycle.

The customer was not amused.

Clearly, one solution to this would have been to have the parsing
happening all the time. Another extra solution would have been to have
one task per motor.

But the solution that I ended up implementing on the next similar
product that came down the pike was to not pass messages that had to be
queued, parsed, diddled with, polished, turned upside down, then parsed
again, all so that you could figure out that the target position for
your motor was A or B. In that (admittedly quite narrow case) the
solution was to just make an atomic memory access to a variable whose
contents were the target position of the motor. Then the motor control
task's only job was to make the motor go to where that variable said.

I've seen numerous other instances where the "make everything into a
message" model gets the job done, but at the expense of a whole lot of
processor thrashing. So yes, you can do everything with message passing.

You also drive to work in a semi truck, complete with trailer.

But it isn't always best.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
From: 42Bastian Schick on
On Sat, 29 May 2010 15:15:18 -0700, Tim Wescott <tim(a)seemywebsite.now>
wrote:

>
>I had a really bad experience in my engineering youth that took me
>almost ten years to get over. It was an application that used message
>passing, but it was clear that the developers had read the OS manual's
>chapter on message passing then misunderstood it.
>
>They had one task that received messages over a serial port, parsed them
>to figure out where they should go, and dispatched them as OS messages.
> There's nothing with that, except that one of the tasks that received
>messages controlled two motors doing two entirely different things. The
>basic loop for that task was:
>
>* check a message
>* parse it
>* if something for a motor to do
> * do that thing
>* go back to start
>
>One motor's commands were basically "go up" or "go down", and the
>increment took 50 or 100 milliseconds. The other motor's commands were
>"go to point A" or "go to point B", and took two seconds.

This describes a fault many peoble make when they you multitasking
systems. They don't obey a simple rule:Concurrent jobs should be done
in different tasks.


>Clearly, one solution to this would have been to have the parsing
>happening all the time. Another extra solution would have been to have
>one task per motor.

Actually, a proper design would have been with 4 processes:
- serial interrupt
- parser
- motor 1
- motor 2

>So yes, you can do everything with message passing.
>
>You also drive to work in a semi truck, complete with trailer.

I'd say, as of today _direct_ message passing, better asynchronous
DMP, can be anything from a motorcycle to a 40t truck (with the speed
of the motorcycle :-)

>But it isn't always best.

It is a different kind of thinking/programming. So far I did not have
a problem I couldn't solve with ADMP, but there might be such ...

--
42Bastian
Do not email to bastian42(a)yahoo.com, it's a spam-only account :-)
Use <same-name>@monlynx.de instead !
From: D Yuniskis on
Hi Tim,

Tim Wescott wrote:
> I pontificated by saying that a complete RTOS should have both binary
> and counting semaphores, and someone called me on it by asking just what
> a "complete" RTOS is.

Depends on how complete you define "complete" to be! :>

An OS is intended to manage the hardware to provide a
scaffolding on which the developer can drape his application.
MS's idea of an OS includes a GUI, file system, drivers, spyware,
etc.

I see the basic services that an *embedded* OS should support
to include:
- memory management
- CPU management
- time management
- communications

The exact details and "richness" of the various services varies
with the complexity of the programming model, targeted applications
and hardware platform.

To skip ahead to your final comment: "No, an OS doesn't need
to include *drivers*. Just like it doesn't need to include
*applications*!" (though some do -- on either or both counts)

Memory management can vary in complexity from *nothing*
(user handles all of his own memory management staticly)
through simple (static buffer pools) and complex (dynamic
memory management). Single shared address spaces vs.
multiple (often *protected*) address spaces. Memory
region attributes vs. no "coloring".

CPU management allows the application(s) to share the CPU
in some "equitable" fashion (the application defines
"equitable"). How isolated individual tasks/processes/threads
are determines the depth of services the developer will
likely need in that environment. E.g., can anyone start
a task? Can anyone *kill* a task? Can one task manipulate
another task's *state*? What sorts of synchronization
primitives do you provide? etc.

Time management is one of the few items whose role *in* an
OS I vassalate about. Ideally, time can be handled outside
the OS -- just like drivers can be "outside" the OS. But,
it is *so* scrumptious that it really wants to be a core
service -- so that other services can exploit it (more later).
This includes being able to measure elapsed time, create
reasonably accurate delays and, optionally, maintain a
time-of-day clock (though this can be easily externalized).

Communications can be an issue depending on the programming
model chosen for the OS. I.e., if each process/task/etc.
has a separate *protected* address space, then how do processes
exchange information? I.e., the OS needs to play a mediating
role. In flat, unprotected address space models, this might
be as simple as relying on a mutex or a monitor governing
a shared memory region/object.

How do you support IPC? *Do* you support RPC? What is the
mailbox/port model used? Can you handle out-of-band data?
Is data *typed* or *untyped*? etc.

For real-time systems, communications can quickly be *the*
bottleneck -- especially if a system is poorly designed or
partitioned (leading to unnecessary communications).

> I realized that my definition of a "complete" RTOS is pretty fuzzy --
> mostly a mismash of every feature that I've ever wanted to use in an
> RTOS, with none of the features that I didn't want to use. This is
> ironic, because I also made a snide comment about RTOS vendors being
> self-centered.

I think many so-called RTOS's are little more than MTOS's.
Some might be fast/slick MTOS's but MTOS's nonetheless.
(writing an MTOS is a weekend task) RTOS's have higher
standards to meet (no, not "just fast"... an RTOS can
be *slow* as long as it is *deterministic*)

> I know what the minimum set of features I want in an RTOS -- basically a
> prioritizing scheduler with deterministic performance, that allows tasks
> to be started under the programmer's control from software entities
> outside of the task. This gives you all the tools you need to fire off
> tasks from ISRs or other tasks, to block on resources, pass messages, etc.

Often, implementations are crippled in silly ways -- "You can only
use *these* routines/services from ISR context", etc. These are
bugs waiting to happen. :<

> But what is a "complete" RTOS then? And if there is one, does anyone
> want it? Is a "complete" RTOS just like a CISC instruction set, wasting
> code space on features that one may never use, just so a vendor can crow
> about it being "all there"?

You can, theoretically, build the OS as a library of routines/services
and only link in the ones that are needed (since most embedded
systems are "completely defined" at deployment). But, if the
implementor heavily integrated things, then you tend to get
stuck with a lot that you may or may not need (or, you have
different versions of the OS that you deploy in different
circumstances)

> And do you think my "minimum necessary" RTOS really includes everything
> you need? Or do you think that it's just not functional until you can
> pass messages and have Bertie Bott's Every Flavor Flag and Ethernet and
> USB and a hard drive and cotton candy on a stick?

I rarely use the *exact* same OS twice. There is usually room
to tweek things to better "fit" the application. Remember,
we tend (C.A.*E*) to design things that have specific, well
defined responsibilities. So, you *know* what services you
need from the OS and don't have to include things "in case
they *might* be needed".

I have found, however, that I *really* like working in a
rich environment. It presents lots of different approaches
to particular design issues that are just too "expensive"
to implement, otherwise. And, *consistency* is a HUGE win!
I.e., being able to access all services in a similar fashion.
And, pushing off *into* the service things that would just be
tedious and "cluttering" to do otherwise (e.g., letting services
"wait" for resources that *I* need instead of me having to
explicitly spin-wait for those)

E.g., in a protected memory space environment, I can "map"
a file into my address space instead of having to literally
*copy* it into RAM. Of course, if I *want* to use RAM to
copy the file (or parts thereof), I can also do that. But,
I am free to trade time for space AT RUN TIME instead of
being *compelled* to go one way or the other.

Likewise, being able to "share" code segments safely (so
task A doesn't munge some aspect of a shared library
that corrupts task B's execution therefrom).

I think once you get exposed to a variety of "facilities",
you are better able to figure out which you *really* need
in any particular OS when faced with a set of application
requirements.

Lately, I am experimenting with naming schemes for objects
so that tasks can deal with them at more abstract levels
(vs. hard-coding things).