Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

hardware errors, do C and Forth need different things in hardware?

83 views
Skip to first unread message

Jeff Fox

unread,
May 19, 2006, 3:06:45 PM5/19/06
to
Most software that came from mainframes and minis was
written from the perspective that an OS and hardware
circuits are needed to prevent unpredictably hostile or
buggy programs from wrecking everything. Where I
work in embedded Forth software the cooperative nature
of programs and any OS needed has a different set of
problems. Often when I talk to people who have the C
idea about hardware/software there is confusion about
terms like hardware errors, error trapping, and error
handling. I will address this and other topics at SVFIG
tomorrow. So let me ask about embedded Forth:

Which of the following 10 conditions should be considered
hardware errors? For those that are errors, how should the
hardware trap them and what should it do to assist with a
solution?

1. begin again \ forever

2. begin ?key until \ no key pressed

3. begin 255 p@ 8 and until \ port bit always false

4. data rom-address !

5. : demo 2 0 / ;
demo

6. : demo 8123 @ ; \ only 32K byes of memory 0-8000
demo

7. : demo blah recurse ; \ no return stack manipulation in blah
demo \ and with no tail recursion
optimization

8. the difference between the number of items pushed
to a stack by a program and the number of items poped
back from the stack is greater than the size of the stack.

9. a program pops from a stack more items than it pushed
to the stack.

10. hardware that will go to sleep when reading ports and
waiting for a neighbor to write is in a sleep state
and neighbors are also a sleep trying to read.

Anton Ertl

unread,
May 19, 2006, 3:30:02 PM5/19/06
to
"Jeff Fox" <f...@ultratechnology.com> writes:
>Which of the following 10 conditions should be considered
>hardware errors?

Most look like software errors. Some can be detected by hardware or
software, and then it's usually convenient if the hardware detects it
and informs the software of the problem.

> For those that are errors, how should the
>hardware trap them and what should it do to assist with a
>solution?

Typically record all the circumstances of the error in order to make
debugging easier.

>1. begin again \ forever

A hardware watchdog timer can detect this.

>2. begin ?key until \ no key pressed

That's bad programming, but usually not an error. Other tasks will
get their turn, and the task containing this nonsense does what it is
supposed to do.

>3. begin 255 p@ 8 and until \ port bit always false

Like 1, a hardware watchdog timer can be used to catch this.

>4. data rom-address !

A kind of MMU can detect this.

>5. : demo 2 0 / ;
> demo

Some architectures detect this in hardware (e.g., i386), some need
software for it (e.g., PPC).

>6. : demo 8123 @ ; \ only 32K byes of memory 0-8000
> demo

Also detectable by MMU.

>7. : demo blah recurse ; \ no return stack manipulation in blah
> demo \ and with no tail recursion
>optimization

So we get a return stack overflow. Can also be detected in hardware.
If the stack is implemented in memory, by an MMU.

>8. the difference between the number of items pushed
> to a stack by a program and the number of items poped
> back from the stack is greater than the size of the stack.

So there is either a stack overflow or an underflow. Like 7.

>9. a program pops from a stack more items than it pushed
> to the stack.

That is normal. Most Forth programs consume some values from the
stack.

>10. hardware that will go to sleep when reading ports and
> waiting for a neighbor to write is in a sleep state
> and neighbors are also a sleep trying to read.

A hardware deadlock? I would assume that such blocking hardware has
some timeout mechanism built-in. If not, a hardware watchdog timer
can help.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.complang.tuwien.ac.at/forth/ansforth/forth200x.html

Message has been deleted

bria...@rogers.com

unread,
May 19, 2006, 11:06:40 PM5/19/06
to

A Man Crying Alone In The Wilderness wrote:
> Anton Ertl wrote:
> > "Jeff Fox" <f...@ultratechnology.com> writes:
> > > <SNIP>

> > >10. hardware that will go to sleep when reading ports and
> > > waiting for a neighbor to write is in a sleep state
> > > and neighbors are also a sleep trying to read.
> >
> > A hardware deadlock? I would assume that such blocking hardware has
> > some timeout mechanism built-in. If not, a hardware watchdog timer
> > can help.
> >
>
> With development of my most current VLIW SMP MPP model ( from Mr.
> Moores 25X thoery), simple, I suggest not permitting a blocking or
> sleep feature for the diagonal enhanced processors. ( maybe a throttle
> is OK, none or all, but havn't thought much of SUPER SCALABLE POWER
> CONSERVATION, <insert your observation knowledge here> ).
>
> OH MY GOD! WHAT CAN WE DO TO STOP *** SOFT PARTICLE ERRORS *** FROM
> CORRUPTING A SEA OF PROCESSORS! ( WORKING DEEP IN GOVERNEMNT AI LEGAL
> ASSISTANCE PROBLEM ... )
>
> Oh, ya, maybe, simple red, yellow, green quad verification of cores,
> but I said that already, hmm, to Washington, about eight years ago!
>
> more,
>


Is it just me or does this text sound a lot like Ractor?

Is this a 'bot?

Brian Fox

Message has been deleted

rickman

unread,
May 20, 2006, 8:54:24 AM5/20/06
to
Anton Ertl wrote:
> "Jeff Fox" <f...@ultratechnology.com> writes:
> >Which of the following 10 conditions should be considered
> >hardware errors?
>
> Most look like software errors. Some can be detected by hardware or
> software, and then it's usually convenient if the hardware detects it
> and informs the software of the problem.

I think timers are not always the best solution...


> > For those that are errors, how should the
> >hardware trap them and what should it do to assist with a
> >solution?
>
> Typically record all the circumstances of the error in order to make
> debugging easier.
>
> >1. begin again \ forever
>
> A hardware watchdog timer can detect this.

Exactly what is the timer going to detect? Running in a loop is normal
operation. I would expect software to detect this type of construct
and not allow it.


> >2. begin ?key until \ no key pressed
>
> That's bad programming, but usually not an error. Other tasks will
> get their turn, and the task containing this nonsense does what it is
> supposed to do.

I don't agree that this is bad programming. How else do you wait for
keyboard input or any other external event?


> >3. begin 255 p@ 8 and until \ port bit always false
>
> Like 1, a hardware watchdog timer can be used to catch this.

I don't understand the error. Why would the port bit always be false?
Is this the wrong bit to check? Is the hardware stuck or a hardware
error? I also don't see how to easily check this with a timer. What
are the start and stop conditions for the timer?


> >4. data rom-address !
>
> A kind of MMU can detect this.
>
> >5. : demo 2 0 / ;
> > demo
>
> Some architectures detect this in hardware (e.g., i386), some need
> software for it (e.g., PPC).
>
> >6. : demo 8123 @ ; \ only 32K byes of memory 0-8000
> > demo
>
> Also detectable by MMU.

I believe the main reason this sort of mistake happens is when
addresses are calculated as in arrays and the index is not checked
against the size of the array. But it can also happen when address and
data are mixed such as incorrect stack handling... but that never
happens, right?


> >7. : demo blah recurse ; \ no return stack manipulation in blah
> > demo \ and with no tail recursion
> >optimization
>
> So we get a return stack overflow. Can also be detected in hardware.
> If the stack is implemented in memory, by an MMU.

I can't imagine a stack machine without stack checking for over and
underflow. I would expect that to be the most common error, but then
there are other ways to use a stack, right?


> >8. the difference between the number of items pushed
> > to a stack by a program and the number of items poped
> > back from the stack is greater than the size of the stack.
>
> So there is either a stack overflow or an underflow. Like 7.

Why would the difference matter. Wouldn't you get an overflow if you
pushed more things on the stack at any time; same with underflow?


> >9. a program pops from a stack more items than it pushed
> > to the stack.
>
> That is normal. Most Forth programs consume some values from the
> stack.
>
> >10. hardware that will go to sleep when reading ports and
> > waiting for a neighbor to write is in a sleep state
> > and neighbors are also a sleep trying to read.
>
> A hardware deadlock? I would assume that such blocking hardware has
> some timeout mechanism built-in. If not, a hardware watchdog timer
> can help.

I don't think you need a timer. What would you be timing??? If both
CPUs go to sleep waiting on one another, it could be normal if they are
also waiting on other conditions or you can just detect the mutual wait
in hardware. No need for a timer either way.

Message has been deleted

ben yates

unread,
May 20, 2006, 9:34:28 AM5/20/06
to
On Fri, 19 May 2006 12:06:45 -0700, Jeff Fox wrote:

> Most software that came from mainframes and minis was
> written from the perspective that an OS and hardware
> circuits are needed to prevent unpredictably hostile or
> buggy programs from wrecking everything. Where I
> work in embedded Forth software the cooperative nature
> of programs and any OS needed has a different set of
> problems. Often when I talk to people who have the C
> idea about hardware/software there is confusion about
> terms like hardware errors, error trapping, and error
> handling. I will address this and other topics at SVFIG
> tomorrow. So let me ask about embedded Forth:
>
> Which of the following 10 conditions should be considered
> hardware errors? For those that are errors, how should the
> hardware trap them and what should it do to assist with a
> solution?
>
> 1. begin again \ forever

Software error. But have you _ever_ used such a loop in your programming?
I have - usually at end of program to keep the screen current. Usually
when debugging.

>
> 2. begin ?key until \ no key pressed

User error - press a key! :) Not a software or hardware error.

>
> 3. begin 255 p@ 8 and until \ port bit always false

Either a bug (wrong port $) or an unsatisfied condition. Not an error.
Perhaps the software _could_ be more robust.

>
> 4. data rom-address !

Not an error, perhaps. Was used in some instances for bank-switching.

>
> 5. : demo 2 0 / ;
> demo

Here, a hardware trap of div by 0 is nice, I admit... but I don't agree
that it has to be a NMI.

>
> 6. : demo 8123 @ ; \ only 32K byes of memory 0-8000
> demo

Depends on the architecture as to what happens, it may "wrap" by design.
Or your system may have ROM above this, see previous answer to #4.

>
> 7. : demo blah recurse ; \ no return stack manipulation in blah
> demo \ and with no tail recursion
> optimization

software error.

>
> 8. the difference between the number of items pushed
> to a stack by a program and the number of items poped back from the
> stack is greater than the size of the stack.

software error, with perhaps hardware stack checking.

>
> 9. a program pops from a stack more items than it pushed
> to the stack.

Same as #8, stack underflow.

>
> 10. hardware that will go to sleep when reading ports and
> waiting for a neighbor to write is in a sleep state and neighbors are
> also a sleep trying to read.

Application design issue.

Message has been deleted

Coos Haak

unread,
May 20, 2006, 1:03:17 PM5/20/06
to
Op Sat, 20 May 2006 09:34:28 -0400 schreef ben yates:

> On Fri, 19 May 2006 12:06:45 -0700, Jeff Fox wrote:
>

<snip>


>> 1. begin again \ forever
>
> Software error. But have you _ever_ used such a loop in your programming?
> I have - usually at end of program to keep the screen current. Usually
> when debugging.
>

Normal use in embedded processing. At reset, the watchdog timer will start
counting and when an overflow occurs, it resets the system.
The user task between begin and again must therefore regularly reset the
watchdog timer before a reset could interrupt its task. Only when the task
is someway halted, the WDT can reset the system and the process can resume
normally.

--
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html

Jeff Fox

unread,
May 20, 2006, 2:32:22 PM5/20/06
to
My point was that I could list ten advantages that we have
in Forth where we can write simpler, easier to understand,
easier to compile, easier to run, and faster code on
simpler cheaper and easier to understand hardware and
that they would likely just look like bugs to C programmers.

These are ways Forth can beat C because C wants to
insist that one needs mainframe hardware and software.
That's the problem it was designed to sovle, to write
Unix as the software traffic cop for the hardware traffic
cop for hostile C programs.

But when you show the advantages that define cooperative
Forth software and that distinguish it from C those things
may not be visible at all from inside of the set of rules that
apply to C/Unix and the mainframe world of hostile programs.
Forth looks like a bug, an error in design, in that enviroment.

But back to the examples listed as things from embedded
Forth. There are no bugs, just simple code that does what
it says.

Not hidden complications, no hidden software, no hidden
hardware adding problems. If you think they are bugs,
they become bugs. They are bugs in C, and in C Forth
thus becomes a bug.

The list is ordered from most simple and obvious to the
most useful and most powerful Forth features that C
programmers can easily confuse with bugs. I have
explained most of them many times and people
probably knew exactly what I would say about each one.

People were suppose to be able to see that they get
more useful, and more powerful by number and that after
the first nine were not bugs one was suppose to be able
to guess that the last one was the most important non-bug.

The first reads BEGIN AGAIN. All Forth programmers are
suppose to be able to read that. It is suppose to be simple.
It does not imply hidden background tasks or watchdogs.
Thinking it is dozens of times more complicated than it
is misses the power of Forth and is an error. It isn't C.

It reminds me of a test I saw on the web to read some code
and count the number of paths through the code. I got a
low score. It looked like three at first, then I saw two more.
But I missed twenty hidden paths that could be trigged
by different combinations of data triggering different error
trapping hardware mechanisms and throwing different
exceptions. Once you are convinced something is a
bug, and you make it so in the hardware and software
it is a bug. It is how 'good' software in Forth is invisible
in C and why Forth looks like bugs there.

What makes Forth fundamentally different than C and
gives it some fundamental advantages over C is that
it can do things with much less overhead than C. That
is because in C the idea is that software is bad and
an OS and hardware traps are needed to protect
everything from bad software. Bugs are planned, and
the whole picture is all about the planning for bugs.

Forth is about planning for good code where the bugs
don't happen. If you say BEGIN AGAIN damn it, you
mean BEGIN AGAIN not twenty other possible
meanings based on C insisting that it is one of twenty
different bugs that need extra hardware and software
to be handled properly.

You can say, ok, this is perfectly sound mathematically and
prove it. You can show exactly how many possible paths
there are through good code. You can handle every possible
'error condition' in a program without having any hardware
error conditions. Hardware error conditions are about
software design errors or hardware/software design errors
and wether bugs should be designed in. Bugs can often be
traced back to conceptual problems of people who introduce
errors intentionally as an essential part of their concept of
data processing.

This one issue, of whether software is fundamentally
good and cooperative or fundamentally hostile and
uncooperative seems to distinguish the mutually exclusive
'everything needs to be like mainframes' and 'everything
does not need to be like mainframes' mentalities.

Hostile and uncooperative software looks buggy and inefficient
from the point of view of 'good' Forth software. And what is
'good' simple cooperative software in Forth looks like bugs
from the hardware and OS are all about the hostile and
uncooperative nature of programs point of view. They
are mutually exclusive sets.

It was test to see if you could distinguish ten things that
define embedded Forth and show that give it some advantages
over C software or if those things looked like errors like they
would to a C programmer.

If the power of the last few items not being errors at all is apparent
to someone then Forth is visible to them as something other than
a bug.

John Passaniti

unread,
May 20, 2006, 10:29:54 PM5/20/06
to
Jeff Fox wrote:
> These are ways Forth can beat C because C wants to
> insist that one needs mainframe hardware and software.
> That's the problem it was designed to sovle, to write
> Unix as the software traffic cop for the hardware traffic
> cop for hostile C programs.

C doesn't insist on anything.

Back a couple years ago, you wrote one of your typically leading
messages asking about the executable size of a simple "Hello World"
program in C. I happened to be working with a C compiler for
microcontroller at the time (ImageCraft's HC08), and so I compiled some
code to see the size. The result was around a couple hundred bytes,
assuming one used puts to display the string instead of the overkill
printf that's in most canonical examples. A minimal printf shot the
size to about 1800 bytes. And in either case, that was the *entire*
code, including startup and the vector to allow the processor to run the
program. There was no OS on the target. This was code that talked to
the bare metal.

Your reply at the time was "nice."

I really get tired of your apples-to-oranges comparisons. When talking
about Forth, you have both feet planted firmly in the embedded systems
space. You talk about systems that aren't general purpose, but are
designed to be specific in what they do. And the company you now work
for sells chips that are designed for specific functions, not for
general-purpose computing.

So that's where you start, but for some reason the second you begin
talking about C, you move the discussion somewhere else entirely. It
doesn't matter that the vast array of micros being used in embedded
systems don't have any operating system on the target. It doesn't
matter that the majority of these are programmed in C with code that
talks to the bare metal. It doesn't matter that the size of many of
these systems doesn't even allow for a minimal operating system. It
doesn't matter that for years, magazines that target the embedded
systems community have talked about commonly-used techniques in C for
using various models of cooperative multitasking (round robin task
lists, message passing, a variety of state machine models, etc.).

None of that (and much more) matters to you. To you, C programmers have
a "mindset" that forces them to require an operating system on the
target, and write code that is far above the bare metal.

The problem is that you know better-- you have to know better-- but if
you talked about C programmers who target embedded systems then your
rants wouldn't work.

The thing is, you're right when you're talking outside the embedded
systems space. C programmers writing code for general-purpose systems
do expect an operating system to both provide services and to abstract
away the underlying machine for portability. But that's not C for
embedded systems-- supposedly what you're talking about.

> The first reads BEGIN AGAIN. All Forth programmers are
> suppose to be able to read that. It is suppose to be simple.
> It does not imply hidden background tasks or watchdogs.
> Thinking it is dozens of times more complicated than it
> is misses the power of Forth and is an error. It isn't C.

do {
} while(1);

I don't see a bug there. I don't see a hidden background task.

> What makes Forth fundamentally different than C and
> gives it some fundamental advantages over C is that
> it can do things with much less overhead than C. That
> is because in C the idea is that software is bad and
> an OS and hardware traps are needed to protect
> everything from bad software. Bugs are planned, and
> the whole picture is all about the planning for bugs.

Give a concrete example. I will code in C, and then show you the
assembly code generated. You won't see anything in the assembly code
that is unexpected, no reliance on an OS, no hardware traps needed to
protect anything.

Jeff Fox

unread,
May 21, 2006, 12:06:34 AM5/21/06
to
Finally, I do think that despite all the years that some
people never understood that the kind of software
that Chuck Moore was talking about when he said
'good software' was cooperative correct simple and
eligant programs doing exactly what they are suppose
to do and avoiding many errors that other people
cannot see how to avoid.

Context, again, this is about why it is hard to explain
what simple Forth software is and what simple Forth
hardware is to people who are thinking C software
and C hardware. This isn't about 'you' doing something
else and calling that Forth, whoever 'you' are.

This thread is about whether these traditional embedded
Forth sorts of things that I described earliker are easily
mistaken for bugs in C view or might look like they might
need or want the sort of complications that this code avoids.

> 1. begin again \ forever

Every Forth programmer is suppose to be able to read that.
It is simple. There is no confusion about what it says.
It does not specify an error condition and to consider it an
error would be introduce a real error. I would expect that
most programmers in traditional Forth have done it many
times.

> 2. begin ?key until \ no key pressed

Another non-error. Misinterpretting it as an error that needs
hidden background tasks or watchdog timers or interrupts
is sort of the opposite of this simple straightforward code
that does what it says, says what it does and is the
sort of thing that gives Forth an advantage.

> 3. begin 255 p@ 8 and until \ port bit always false

Just like 2, except waiting on an event that might or might
not be a key press. But it does what it says and says
what it does, ad it is clear and simple.

> 4. data rom-address !

Traditional embedded style Forth has always made this sort
of thing easy. Maybe on this project when I wrote to ROM it
gets decoded as io output. Maybe the comment will read,
"turn on the panel light" and it won't be an error at all
either in software or hardware. Writing to ROM could be
something to give us an advantage over hardware or
software that make the real problem harder to solve.

If it confuses solutions for bugs it will introduce REAL bugs.

> 5. : demo 2 0 / ;
> demo

It is unlikely to define demo that way, but division by zero is
'undefined.' So we get to do what we want since we got to
define what / does with 0. And since that is what our code
says we want to do here, we assume that the action that
we want to have associated with division by zero will take
place and that no error is going to happen here.

Throwing an error that we didn't want would be a bug.

> 6. : demo 8123 @ ; \ only 32K byes of memory 0-8000
> demo

Oh, yes, little by little they get more powerful. If we only have
a 15-bit memory space we may be using higher bits for
io and addresses might wrap. That is the way simple fast
and cheap devices will work and the way simple fast software
can take advantage of it and outperform software that has
to follow all a mainframe OS policeman's rules.

This is very typical sort of Forth that can win. We don't think
it should be disqualified because winning code would be
considered a bug or must be dissallowed.

> 7. : demo blah recurse ; \ no return stack manipulation in blah

> demo \ no tail recursion optimization

So it is just a special case of 8. 8 is more general and more
powerful. And as I have explained many times. If you can
use fewer transistors to make a faster lower power circuit
eliminates the possibility of certain states from happening
it may be a big advantage. Avoiding errors is very different
than trapping them and dealing with them at rurntime.

Faster simpler cleaner stacks that can't produce overflow
error states are an advantage and software that can take
advantage of them can avoid dealing with errors that other
hardware and software designs require.

> 8. the difference between the number of items pushed
> to a stack by a program and the number of items poped
> back from the stack is greater than the size of the stack.

But if the number pushed is greater than the number poped
by more than the size of the stack it will overflow right? No,
not if it wraps. By wrapping it will always hold the
maximum amount and will not create an overflow error
nor will an overflow error recovery be required just because
more items were pushed that poped.

We have been doing this for half the history of Forth and
we have reported the power that it offers in simplifying things
speeding things and eliminating error states. We do it
all the time and we explain the advantages over and over.

Consider that you want to write the shortest, fastest and
lower power consuming code that you can to do xyz.
We have been talking about that goal. And after you write
the inner loop of your app you realize that it has a balanced
stack, exactly the same number of DUPs as DROPs. So
you ask yourself, in this embedded Forth what will happen
if I remove the final DROP in the loop?

And you conclude that there is nothing wrong with it, no
error happen, no error condition will be trapped, and you
can leave an extra item on the stack in this inner loop
as long as it doesn't matter. As long as when you leave
the loop you consider the stack empty and you can
treat it like an infinite stack until you declare it empty.

You know the code is smaller, faster, and uses less power.
You know it is not an error and that nothing needs to be
trapped or considered an error. You know that having
smaller, cheaper, faster, and simpler hardware and
software is an advantage. You know that it has an
advantage over using stacks that have to follow all
the rules that C requires for stack use and stack
error handling.

> 9. a program pops from a stack more items than it pushed
> to the stack.

These non-bugs are getting more powerful. The ability to
keep taking the same items off the stack again and again
without generating an error is something that can be
exploited. Since stacks are faster than memory here
and can deliver a repeating pattern faster than reading
it from memory or dealing with hardware stack underflow
trapping it is another win. It is another form of freedom
to beat hardware and software that has to work the
way mainframes work.

And people are suppose to figure out the pattern of the quiz
by now. Nine non-bugs each getting more useful and a
more important example of what distinguishes where
traditional cooperative Forth has gone in the last twenty
years and things that give it an advantage are suppose to
suggest that the biggest non-error is the last.

> 10. hardware that will go to sleep when reading ports and
> waiting for a neighbor to write is in a sleep state
> and neighbors are also a sleep trying to read.

If any of the others were confused for errors it is likely
that this one would be too. This characterized everything
we are doing. If you confuse it with an error you will have
trouble understanding what we do and what advantages
we get by doing it the way we do it. Since it is a bit of a
trick question because we haven't released all the
hardware and software details of what we are doing I
gave everyone more than nine hints.

Understanding how something like this could be a very
powerful thing and how it isn't a bug will be key to further
understanding of what we are doing. So far I haven't seen
people thinking about traditional Forth design techniques
or newbies have much trouble with the concepts. But
those who picture this stuff working like a tiny linear mainframe
running hostile programs instead of a sea of tiny cooperating
Forth programs on a sea of tiny processors have trouble
with the basics.

I talked about this stuff at SVFIG today and people seemed to
understand my points. I didn't get any arguments that Forth
is really a bug. They did laugh a bit about how some of these
traditional ideas are easily confused with bugs by some.

Jeff Fox

unread,
May 21, 2006, 12:20:16 AM5/21/06
to
rickman wrote:
> I think timers are not always the best solution...

If we wanted a timer we could have a timer task or a timer node
or a timer group, or use a timer circuit, but we would not have
an interrupt driven timer. Different paradigm.

> Exactly what is the timer going to detect? Running in a loop is normal
> operation. I would expect software to detect this type of construct
> and not allow it.

Yes, a normal operation. As are all the others where we are.

> I don't agree that this is bad programming. How else do you wait for
> keyboard input or any other external event?

My point is that some see it that way. I don't.

I say it's Forth. He says it's a bug.
I say it's good. He says it's bad.

My point is that we seem to be using different definitions and terms.

What we were refering to as 'good software' he calls bad programming.

It makes you wonder sometimes who does and who doesn't understand
what you write or say.

On a port handshake lockup,

> I don't think you need a timer. What would you be timing??? If both
> CPUs go to sleep waiting on one another, it could be normal if they are
> also waiting on other conditions or you can just detect the mutual wait
> in hardware. No need for a timer either way.

As you say, a timer on the circuit itself would be one option. If it
was
an error there might be several ways of handling it without a timer. Or
sometimes it might not be an error or problem at all.

Jeff Fox

unread,
May 21, 2006, 12:29:48 AM5/21/06
to
ben yates wrote:
> > 1. begin again \ forever
>
> Software error. But have you _ever_ used such a loop in your programming?

Thousands of times. Maybe I wanted to halt a program as simply and
completely at some spot for debugging. Maybe I wanted to see only
a single address frozen on the address bus. Maybe I wanted to see
exactly how much power was being drawn by the processor when it
was doing exactly what I told it to do.

jump $ is very basic idea.

> I have - usually at end of program to keep the screen current. Usually
> when debugging.

Sure, in fact it might be the only way to end some program!

> > 2. begin ?key until \ no key pressed
>
> User error - press a key! :) Not a software or hardware error.

;-) I will, I will. But I haven't yet and I want it to wait for me.

> Not an error.
> Perhaps the software _could_ be more robust.

Sure. But I only asked about 'hardware errors' that needed trapping.

> Not an error, perhaps. Was used in some instances for bank-switching.

> Here, a hardware trap of div by 0 is nice, I admit... but I don't agree


> that it has to be a NMI.

> Depends on the architecture as to what happens, it may "wrap" by design.


> Or your system may have ROM above this, see previous answer to #4.

7, 8, 9, and 10 also depend on the architecture ( and view) and as I
have explained they cause no error conditions for us.

> Application design issue.

Indeed it could be a software error. If we are running someone
else's hostile software we might have a problem with it. If we
use cooperative software there are ways to assist with
application design issues.

Jeff Fox

unread,
May 21, 2006, 12:35:16 AM5/21/06
to
Coos Haak wrote:
> >> 1. begin again \ forever
>
> Normal use in embedded processing. At reset, the watchdog timer will start
> counting and when an overflow occurs, it resets the system.
> The user task between begin and again must therefore regularly reset the
> watchdog timer before a reset could interrupt its task. Only when the task
> is someway halted, the WDT can reset the system and the process can resume
> normally.

That might be a normal thing to do, if you have a watchdog timer
and your application needs to occasionally restart itself for some
reason.
If you new all that when you wrote the BEGIN AGAIN you probably would
not have written the comment that said \ FOREVER

If you as the programmer wrote and intended FOREVER and didn't know
about a watchdog timer programmed by someone else that is going to
reset the system under you now have a bug.

If you as the programmer did know that BEGIN AGAIN was going to
wait for the watchdog the comment should have said
\ wait here for the watchdog timer to reset the system

But that is just a case of bad commenting not of a hardware error.
The code says BEGIN AGAIN \ FOREVER and if it doesn't there is
a hardware error that needs to be fixed.

Jeff Fox

unread,
May 21, 2006, 12:50:55 AM5/21/06
to
Anton Ertl wrote:
> >9. a program pops from a stack more items than it pushed
> > to the stack.

Ok. I know I have explained how it should not be seen as an error
in what we do and how we have considered it normal for a very long
time.

> That is normal. Most Forth programs consume some values from the
> stack.

We agree. But I am pretty sure it is only because you read the
question backwards and so got the correct answer.

To check my hypothesis I tried gForth to see if it sees and error.

Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRENTY; for details type 'license'
Type 'bye' to exit
ok
: demo compiled
1 2 3 compiled
drop drop drop drop compiled
; ok
: test compiled
demo compiled
." this is not an error!" compiled
; ok
test this is not an error!
*the terminal*:10: Stack underflow
test
^^^^
Backtrace:
ok

Anton Ertl

unread,
May 21, 2006, 2:34:42 AM5/21/06
to
"Jeff Fox" <f...@ultratechnology.com> writes:
>Anton Ertl wrote:
>> >9. a program pops from a stack more items than it pushed
>> > to the stack.
...

>> That is normal. Most Forth programs consume some values from the
>> stack.
>
>We agree.

After reading your other comments (hey, I'm reading your comments for
a change!), I doubt it, for this item.

>But I am pretty sure it is only because you read the
>question backwards and so got the correct answer.

Maybe you were not clear enough in your question (and that's not
limited to this item).

>To check my hypothesis I tried gForth to see if it sees and error.
>
>Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.
>Gforth comes with ABSOLUTELY NO WARRENTY; for details type 'license'
>Type 'bye' to exit
> ok
>: demo compiled
> 1 2 3 compiled
> drop drop drop drop compiled
>; ok
>: test compiled
> demo compiled
> ." this is not an error!" compiled
>; ok
>test this is not an error!
>*the terminal*:10: Stack underflow

: demo 1 2 3 drop drop drop drop ; ok
: test demo ." this is not an error!" ; ok
1 test this is not an error! ok

New standard: http://www.forth200x.org/forth200x.html
EuroForth 2006: http://www.complang.tuwien.ac.at/anton/euroforth2006/

Jeff Fox

unread,
May 21, 2006, 10:42:45 AM5/21/06
to
Anton Ertl wrote:
> After reading your other comments (hey, I'm reading your comments for
> a change!), I doubt it, for this item.
>
> >But I am pretty sure it is only because you read the
> >question backwards and so got the correct answer.
>
> Maybe you were not clear enough in your question (and that's not
> limited to this item).

The simplest explaination would be that people who don't read
the comments are the one who don't understand them. They
might seem a lot clearer to you if you read them. It certainly
provides a simple explanation for your confusion about the
most basic terms we use.

We say good, you think bad. We say Forth you say bad programming.
We say good means cooperative, simple and free. You say good means
safely hostle, complicated and restricted. We say Forth you say
bad C. You say C we say bad Forth.

I read your definition of terms. You igore ours because it makes
a distinction between a C approach and a Forth approach. This
is what we define as what defines Forth and lets it win over C.
You cannot accept this and would rather ingore the tradition
that Forth isn't C.

You ignore what people say about traditional Forth and how it
works and only pay attention to a mix of C and a little Forth-like
behavior on top. And you argue with what people who do
traditional Forth say, or you ignore it because they don't
think like C programmers.

> >*the terminal*:10: Stack underflow
>
> : demo 1 2 3 drop drop drop drop ; ok
> : test demo ." this is not an error!" ; ok

except gforth insists that it is an error.

> 1 test this is not an error! ok

I tried it again. gForth still throws an error.
the program lies about it not being an error in gforth
then crashes out an error message saying
Stack underflow just as I expected, confirmed and
posted. I find it odd that you posted that it doesn't.

Your comments about waiting for characters being a bug
sounds to me like you are just thinking in Unix and
trying to map some Forth into that world.

But thanks again for demonstrating my point that it
is easy for some people to confuse everything about
the design of cooperative Forth programs, what we
call good software for bugs in their world of hostile
programs. So I suppose I should also thank you
for not reading the comments that explain why we
call Forth good so that you could provide an example
of how some people might confuse each thing for a
bug.

Bernd Paysan

unread,
May 21, 2006, 3:02:31 PM5/21/06
to
Jeff Fox wrote:
>> 1 test this is not an error! ok
>
> I tried it again. gForth still throws an error.
> the program lies about it not being an error in gforth
> then crashes out an error message saying
> Stack underflow just as I expected, confirmed and
> posted. I find it odd that you posted that it doesn't.

It probably depends on the plattform. We can only ensure that it behaves
like it should on plattforms that supports propper mmap() functionality. I
have no problem getting the errors I like to see on Linux, but won't
guarantee that it works fine on Windows or DOS.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/

Jeff Fox

unread,
May 21, 2006, 3:59:01 PM5/21/06
to
I wondered if he had just fixed the bug in another version
and that the one I download from the web would throw
a stack underflow error in a situation that is not an
error in the kind of embedded Forth that I had been talking
about.

Whenever someone says to me that a bug isn't their
bug because it is in the OS that they called I am inclined
to point out to them that they chose to call that OS in that
way and that if they did that they should accept that it IS
their bug.

But ok. If it worked in Linux gForth then maybe Anton
getting one right was not a mistake on his part like I
assumed.

John Passaniti

unread,
May 21, 2006, 4:10:37 PM5/21/06
to
Jeff Fox wrote:
> This thread is about whether these traditional embedded
> Forth sorts of things that I described earliker are easily
> mistaken for bugs in C view or might look like they might
> need or want the sort of complications that this code avoids.

This thread is actually about both your poor communication skills and
your inability to have a discussion without creating a straw-man. This
thread is how you discuss Forth in a embedded systems context, but
refuse to talk about C in the same context. And this thread is about a
fundamental intellectual dishonesty on your part, coupled with more
logical fallacies than I have time to look up the Latin names for.

Let's dive into your latest stream of context-free nonsense:

>> 1. begin again \ forever
>
> Every Forth programmer is suppose to be able to read that.
> It is simple. There is no confusion about what it says.
> It does not specify an error condition and to consider it an
> error would be introduce a real error. I would expect that
> most programmers in traditional Forth have done it many
> times.

It is impossible to say if this is an error or not because you didn't
provide any context. If the statement prior to begin turns on the x-ray
generator aimed at the patient's head, it is a very serious error. If
the statement prior to begin was a message on the front panel saying
"please cycle power to complete firmware update" then it isn't an error.

So what's the context? You don't say.

>> 2. begin ?key until \ no key pressed
>
> Another non-error. Misinterpretting it as an error that needs
> hidden background tasks or watchdog timers or interrupts
> is sort of the opposite of this simple straightforward code
> that does what it says, says what it does and is the
> sort of thing that gives Forth an advantage.

It is impossible to say if this is an error or not because you didn't
provide any context. Is ?key detecting a keystroke on a console's
keypad? If so, it's not an error since you're waiting on human input.
Is ?key tied to a serial port giving status on a fly-by-wire plane's
flaps? If so, it could be a very serious error.

>> 3. begin 255 p@ 8 and until \ port bit always false
>
> Just like 2, except waiting on an event that might or might
> not be a key press. But it does what it says and says
> what it does, ad it is clear and simple.

Yet again, it is impossible to say if this is an error or not because
you didn't provide any context. Does the port bit go false when the
battery level in the child's toy sitting on a shelf drops below a
threshold? Or does the port bit go false when the hardware driving the
cardiac stimulator fails? I think there is a difference there, but you
refuse to provide any context.

>> 4. data rom-address !
>
> Traditional embedded style Forth has always made this sort
> of thing easy. Maybe on this project when I wrote to ROM it
> gets decoded as io output. Maybe the comment will read,
> "turn on the panel light" and it won't be an error at all
> either in software or hardware. Writing to ROM could be
> something to give us an advantage over hardware or
> software that make the real problem harder to solve.

C doesn't care if you write to ROM addresses. You're free to do that:

*((char*) rom_address) = 42;

What the underlying hardware does is a matter of how you have the
address lines hooked up. I have certainly designed systems (programmed
in C) that write to ROM addresses to drive front panel LEDs, to shift
out data to a '595, to address write-only hardware, to tickle external
watchdogs, and probably other examples I can't recall. There is no
error there, and the technique is well-known in the embedded systems world.

However, as always, context matters. If there is no hardware there but
just a ROM, then the statement is clearly an error. But you don't
provide the context, so the question is meaningless.

>> 5. : demo 2 0 / ;
>> demo
>
> It is unlikely to define demo that way, but division by zero is
> 'undefined.' So we get to do what we want since we got to
> define what / does with 0. And since that is what our code
> says we want to do here, we assume that the action that
> we want to have associated with division by zero will take
> place and that no error is going to happen here.

On the majority of embedded systems I've programmed in C over the past
20-something years, division is implemented as a library routine.
That's either because (like on the Z80) there is no division
instruction, or because (like on the 8051 and HC08 family) there is a
divide instruction, but it is of limited precision. And as such, I've
had complete control over handling of division by zero, and could make
it do whatever I like. No C compiler I have ever used has prevented me
from compiling the code (although many will issue a warning, which is
appropriate and can always be disabled).

So while C code running on a general purpose processor with a general
purpose operating system may indeed throw an exception, I thought we
were talking about embedded systems here. So again, context matters,
but you don't offer it.

>> 6. : demo 8123 @ ; \ only 32K byes of memory 0-8000
>> demo
>
> Oh, yes, little by little they get more powerful. If we only have
> a 15-bit memory space we may be using higher bits for
> io and addresses might wrap. That is the way simple fast
> and cheap devices will work and the way simple fast software
> can take advantage of it and outperform software that has
> to follow all a mainframe OS policeman's rules.

There are currently two embedded systems in the world (both incidentally
written in C) where I have exploited this modulo addressing, and it
isn't an error-- it's part of the hardware and software design. C (of
course) had no problem with it.

But here we go again, what is the context? Are you describing a system
where this is part of the design and thus not an error? Or are you
describing an unintentional addressing past the limit of addressability?
You don't say (of course), so the example is meaningless.

>> 7. : demo blah recurse ; \ no return stack manipulation in blah
>> demo \ no tail recursion optimization

C would also allow this:

void demo(void) {
blah();
demo();
}

There may be some C compilers that attempt to do the obvious tail
recursion optimization, but none of the microcontroller C compilers I
have do, and gcc (with the default level of optimization) doesn't
either. So C will let you code this without complaint.

So again, since we don't have C complaining at all about this, so we
need to switch the discussion to the processor the code runs on. On
microcontrollers with constrained hardware stacks (6502, HC05, some 8051
derivatives), this code would fill the stack endlessly with the return
address of demo. It wouldn't be an error, and the processor would
happily execute the code forever. I can't see how that would be useful,
but if the programmer who wrote it had a reason for it, C is happy to
comply and the underlying hardware will faithfully execute it.

But what's the context? What processor are we talking about? What
real-world technique is this performing? Tell us the processor, show us
a real-world application the technique (not trivial "demo"), and your
example might make sense. Until then, it's meaningless because there is
no context.

>> 8. the difference between the number of items pushed
>> to a stack by a program and the number of items poped
>> back from the stack is greater than the size of the stack.

In most (but certainly not all) C compilers, a function call is composed
of the following steps:

1. Arguments are passed on a stack.
2. The function is called and returns.
3. The stack is adjusted to remove the arguments pushed.

In this case, the calling convention doesn't allow for your scenario,
since the stack is cleaned up after the return of the function. But
many C compilers also offer alternate calling conventions, typically to
interface to code from other languages. Specifically, many offer the
calling convention usually used by Pascal:

1. Arguments are pushed on a stack.
2. The function is called.
3. The function is responsible for popping off the arguments.
4. The function returns.

This would allow for your scenario, although the function called
couldn't be C (since the compiler would adjust the stack). You could
call a Forth word from C like this, or you could call a C function
compiled with the standard calling convention. In any case, this is
something that C doesn't have any comment on. This is more the domain
of the code generated by the compiler and the linker. But it can
certainly be done if there is a reason to do so.

So again, we have to talk about the hardware, not C. And again, you
aren't providing context. Is the system designer exploiting some
element of the processor's design, or is this a bug? You don't give
specifics, so again, your example is meaningless.

>> 9. a program pops from a stack more items than it pushed
>> to the stack.

C certainly allows this:

#include <stdarg.h>

void example(int x, ...) {
va_list arg;
va_start(args, x);
printf("arg 1 = %d\n", x);
printf("arg 2 = %d\n", va_arg(args, int));
printf("arg 3 = %d\n", va_arg(args, int));
va_end(args);
}

... later in the code...

example(1);

Here I've defined function example that will consume three arguments,
but I've only passed one argument to it. What will the two arguments
be? It depends entirely on the context of the system. In one platform
I've used, the third argument would be the return address of the caller.
In other cases, it would be garbage.

But in any case, C certainly allows this, and it isn't an error. It
might be useful in some kind of profiling application, or it might be
helpful in some other way. C doesn't care, and assumes you know what
you're doing.

So what's the context? What processor are we talking about? You don't
say, making your arguments meaningless.

>> 10. hardware that will go to sleep when reading ports and
>> waiting for a neighbor to write is in a sleep state
>> and neighbors are also a sleep trying to read.

This doesn't involve C at all. The compiler will let you generate code
that allows you to access a port. It doesn't impose any restrictions on
what happens to the larger system when you access those ports. In fact,
although it isn't used for communication, many microcontrollers have
ports or memory locations that when written to put the processor into a
sleep mode, waiting for some event to occur. C is completely agnostic
about this and doesn't consider it an error in the least.

I just had a funny idea. There are a number of C compilers out there
(lcc, vbcc, gcc) for which you can write back-end code generators to
target any system you like. Based on what little technical data has
been released on IntellaSys's chips, it doesn't sound difficult to come
up with a C compiler back-end that generates code for IntellaSys's
chips. What would Jeff say when C code targeting his company's chips
does exactly what he claims it can't do? (Answer: He would come up
with some other equally idiotic argument as a distraction.)

> I talked about this stuff at SVFIG today and people seemed to
> understand my points. I didn't get any arguments that Forth
> is really a bug. They did laugh a bit about how some of these
> traditional ideas are easily confused with bugs by some.

This is like President Bush going to speak in front of friendly neocon
groups. Just as I wouldn't expect tough questions from the neocons to
the President, you aren't likely to be challenged on your claims in a
Forth user group. But if you were instead to stand in front of a bunch
of C programmers who actually do embedded systems work (not the
straw-men you're inventing who don't), I'm sure the result would be far
different.

You would be primarily asked about context, and you would be told that
your argument makes no sense because it lacks context. You start off
talking about embedded systems, but then shift the context to general
purpose systems running general purpose operating systems when it suits
your argument. That's intellectual dishonesty coupled with logical
fallacy. And oddly, you wear both as a badge of honor.

So in summary, none of the examples you provided are errors to this
embedded systems programmer. They aren't errors because your discussion
lacks specificity and context, and they aren't errors because they are
actual techniques I have used in C in my embedded systems work.

Here's a radical idea, Jeff. Before you invent straw-men for your next
nonsensical argument, feel free to pass your questions to me first. As
a embedded systems programmer who uses C, I can point out the idiotic
nonsense sooner so you won't embarrass yourself too much. And gosh, you
might actually learn about what real-world embedded systems programmers
do and think-- something I assume would be useful in your role at
IntellaSys.

Marcel Hendrix

unread,
May 21, 2006, 6:19:01 PM5/21/06
to
Bernd Paysan <bernd....@gmx.de> writes Re: hardware errors, do C and Forth need different things in hardware?
[..]

> It probably depends on the plattform. We can only ensure that it behaves
> like it should on plattforms that supports propper mmap() functionality.
[..]

0.6.2 is the current release, according to http://www.jwdt.com/~paysan/gforth.html.

( gforth-fast.exe )


Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.

Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit


: demo 1 2 3 drop drop drop drop ; ok

: test demo ." this is not an error!" ; ok


1 test this is not an error! ok

( gforth-itc.exe )


Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.

Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit


: demo 1 2 3 drop drop drop drop ; ok

: test demo ." this is not an error!" ; ok


1 test this is not an error! ok

( gforth-ditc.exe )


Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.

Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit


: demo 1 2 3 drop drop drop drop ; ok

: test demo ." this is not an error!" ; ok


1 test this is not an error! ok

-marcel

Jeff Fox

unread,
May 21, 2006, 6:40:34 PM5/21/06
to
Great! Sometimes it is very useful to know that I was wrong.
Thanks.

John

unread,
May 21, 2006, 6:49:15 PM5/21/06
to
Anton Ertl wrote:
> "Jeff Fox" <f...@ultratechnology.com> writes:
>>To check my hypothesis I tried gForth to see if it sees and error.
>>
>>Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.
>>Gforth comes with ABSOLUTELY NO WARRENTY; for details type 'license'
>>Type 'bye' to exit
>>ok
>>: demo compiled
>>1 2 3 compiled
>>drop drop drop drop compiled
>>; ok
>>: test compiled
>>demo compiled
>>." this is not an error!" compiled
>>; ok
>>test this is not an error!
>>*the terminal*:10: Stack underflow
>
>
> : demo 1 2 3 drop drop drop drop ; ok
> : test demo ." this is not an error!" ; ok
> 1 test this is not an error! ok
>
> - anton

Apples and oranges: Anton (and Marcel) put a "1" on the stack before executing "test" and Jeff did not.

Jeff Fox

unread,
May 21, 2006, 7:40:20 PM5/21/06
to
I have the impression that people would prefer that I don't
try to respond to your posts and focus on answering
their questions. But unless someone asks again that
I not bother I will try.

John Passaniti wrote:
> C doesn't insist on anything.

Only on C being C.

> Back a couple years ago, you wrote one of your typically leading
> messages asking about the executable size of a simple "Hello World"
> program in C. I happened to be working with a C compiler for
> microcontroller at the time (ImageCraft's HC08), and so I compiled some
> code to see the size. The result was around a couple hundred bytes,
> assuming one used puts to display the string instead of the overkill
> printf that's in most canonical examples. A minimal printf shot the
> size to about 1800 bytes. And in either case, that was the *entire*
> code, including startup and the vector to allow the processor to run the
> program. There was no OS on the target. This was code that talked to
> the bare metal.
>
> Your reply at the time was "nice."

It was nice. I hadn't thought of that kind of simplified definition of
a 'hello world program.' So I did the same sort of thing that you
had talked about in this embedded C style hello world. One version
was only about a hundred times smaller than yours, and the
other was only a couple of dozen times smaller.

I didn't want an apples to organges comparison since I had at
first been talking about a traditional hello world display to a video
terminal. So when you wanted to compare that to a simplfied
version I wrote a simplfied version too for comparison that
would be more fair and got the same kind of results.

> I really get tired of your apples-to-oranges comparisons. When talking
> about Forth, you have both feet planted firmly in the embedded systems
> space. You talk about systems that aren't general purpose, but are
> designed to be specific in what they do. And the company you now work
> for sells chips that are designed for specific functions, not for
> general-purpose computing.

General-purpose is a meaningless buzzword. There is no such thing.
Realtime embedded processing is general purpose realtime embedded
processing. Mainframe batch processing is general purpose limited
mainframe batch processing. Typical desktop processing is general
purpose toy desktop computer processing. But the 'general' purpose
is simply the kind of processing that is going on.

General purpose processing on PC has a different meaning that it
did twentyyears ago. It has a different meaning than general purpose
dsp processing, general purpose symbol processing, general purpose
floating point number crunching, or general purpose io response
programs. They are all general purpose and all limited and all
different.

All chips are designed for specific purposes. There is no such thing
as a general purpose chip. It is a meaningless argument. There is
no general purpose hardware, there is no general purpose language.
There have not even been many efforts to even try to invent a
general purpose language and those failed terribly.

All human natural languages are different and express different ideas.
These different languages express the differences between cultures.
All programming languages are different and express different ideas.
These different languages express the differences between cultures.
Attempts to translate often result in things being lost in translation
because there is no such thing as a general purpose language
that it can express everything in every other language. Everyone
knows that cultural things get lost in translation.

> So that's where you start, but for some reason the second you begin
> talking about C, you move the discussion somewhere else entirely. It
> doesn't matter that the vast array of micros being used in embedded
> systems don't have any operating system on the target. It doesn't
> matter that the majority of these are programmed in C with code that
> talks to the bare metal. It doesn't matter that the size of many of
> these systems doesn't even allow for a minimal operating system. It
> doesn't matter that for years, magazines that target the embedded
> systems community have talked about commonly-used techniques in C for
> using various models of cooperative multitasking (round robin task
> lists, message passing, a variety of state machine models, etc.).

Sometimes two languages use the same words, like good, like multitask,
like OS, to mean very different things because they assume a different
context. Since most of the confusion I encounter comes from people
assuming a C context instead of Forth context and trying to translate
the terms they hear there is confusion. Sometimes I address the
source of that confusion and look at how some terms mean different
things.

Any idiot can try to cause confusion by purposely taking things
out of one context and putting them in another where what was
true now becomes false. And any good sophist will try to convince
others that the original statements that were true in their original
context are somehow now really false.

> None of that (and much more) matters to you. To you, C programmers have
> a "mindset" that forces them to require an operating system on the
> target, and write code that is far above the bare metal.

Not quite. But they expect a lot more bare metal if they are thinking
C.
That has been the point of this thread in my mind. I know it your mind
it is a thread talking about how you feel personally about me.

I say the C mindset expects hardware that resembles and works
like mainframes or minis, hardware designed to deal with that set
of restricted problems. I say it is not general purpose hardware.
It is C purpose hardware. C expects and demands C purpose hardware.

Forth expects less. It can live with more, it can easily run on C
purpose
hardware because it is more 'general purpose' than C. And Forth
purpose
hardware needs less than C purpose hardware because it expects
cooperative software not hostile software, the biggest problem one has
to deal with in C purpose hardware and software.

Does general purpose mean hostile? If that is all someone thinks there
is then the answer is yes, all software is hostile therefore general
purpose
means dealing with hostile software. If that is how one defines
'general
purpose' then yes.

But I maintain that 'general purpose' must include all cases, not just
the problems that come along with minicomputers and mainframes
running multiuser or batch programs using one of the popular
mainframe OS. That's a special case of computing if ever there
was one.

> The problem is that you know better-- you have to know better-- but if
> you talked about C programmers who target embedded systems then your
> rants wouldn't work.

The problem you have is that you don't like my definition that general
purpose must include Forth and that if it intentionally excludes Forth
it is a specialized form of computing, not general purpose. The
problem
that you have is that I don't accept that C means general purpose. It
doesn't.

> The thing is, you're right when you're talking outside the embedded
> systems space. C programmers writing code for general-purpose systems
> do expect an operating system to both provide services and to abstract
> away the underlying machine for portability. But that's not C for
> embedded systems-- supposedly what you're talking about.

That's not general purpose. That's C OS purpose and it is really very
specialize as it has to deal with a long list of problems that just
don't
exist in many other forms of computing that really need to be
covered by the term general purpose.

> do {
> } while(1);
>
> I don't see a bug there. I don't see a hidden background task.

Good. I don't either. But I only see a code snippet not the whole
application or system just like the example I gave.

And since in that context it is what it is, it is clearly not a bug.
If that is a bug then C is a bug. Likewise if BEGIN AGAIN
is a bug that must not be allowed then Forth is a bug.

> > What makes Forth fundamentally different than C and
> > gives it some fundamental advantages over C is that
> > it can do things with much less overhead than C. That
> > is because in C the idea is that software is bad and
> > an OS and hardware traps are needed to protect
> > everything from bad software. Bugs are planned, and
> > the whole picture is all about the planning for bugs.
>
> Give a concrete example. I will code in C, and then show you the
> assembly code generated. You won't see anything in the assembly code
> that is unexpected, no reliance on an OS, no hardware traps needed to
> protect anything.

If I wrote an example of code that needed no hardware traps and had
no reliance on an OS then I would expect you to be able to make a
copy of it, fairly closely in some other enviroment. It might or might
not be as small and clean and that mostly depends on the program
and the hardware. I expect that you could copy something.

Of course if I add real world constraints you will lose. If I choose
the problem, if I choose the target, if I choose the contraints
then confounding C is easy. Without knowing the odds, the
target, and the problem to be solved claiming that one language
can do whatever another language can do is absurd.

I must admit it would be fun to go somewhere where I could
put my money where my mouth is and take a lot of money
from a troublesome fool. But it would be too easy, too unfair,
and no one would learn anything that they don't already know.

I would love to take you up on that, but I think that no one would
learn
anything because they know you would fail. And I don't think you
would learn anything because I would expect you to just sluff it off
and come back the next day denying that it ever happened, denying
that you have ever been wrong about any of this stuff, and going
back to more personal complaints about me.

And it wouldn't be fair anyway to expect you to write code for free
since you are a professional. You would be giving me a huge advantage
if I choose the weapons and the place of the engagement and that
would be very fair either. I would be willing to give you lots of
advantages and lots of odds, headstart, relaxed requriements
for you etc., but it would still be a sucker bet.

And I know that people don't want to see me respond to your
personal stuff, or try to make this about you like you want to
make it about me. So we really shouldn't try the programming
challange.

But thanks for the questions that let me clarify my positiion
about things like, C programmers are so arrogant that they
tell you C is general purpose. Maybe they all think that
they are generals.

Jeff Fox

unread,
May 21, 2006, 8:20:13 PM5/21/06
to
The context of each question was clearly stated as whether it
should be catagorically considered a bug needing hardware
to trap and fix without any other context.

All code when put into the wrong context will be wrong. That
was not the question.

The questions were all like this, "Does the follow Forth code
do what the comment says or it is a bug that *always* needs fixing
in *every* possible case, maybe even needing hardware traps?"

BEGIN AGAIN \ forever

If
that means 'forever' or until power is cycled or reset is pressed
and that *could* be valid code
then it should *NOT* be catagorically considered a bug
and it should *NOT* be disallowed either by the compiler
or by the hardware.

If
it is simply a bug in *all* cases
then the software or hardware should prevent it
or fix it.

As far as I got you got the answers right whenever
you left the questions in the orginal context.

Jerry Avins

unread,
May 21, 2006, 9:58:04 PM5/21/06
to
John wrote:

For a program to pop more than it pushes is an error. Anton and Marcel
showed that for a word, it is not. Jeff's straw-man assertion was too
strong, and he was corrected. If not for history, I'd have done it myself.

Jerry
--
Engineering is the art of making what you want from things you can get.
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

John Passaniti

unread,
May 21, 2006, 10:52:32 PM5/21/06
to
Jeff Fox wrote:
> The questions were all like this, "Does the follow Forth code
> do what the comment says or it is a bug that *always* needs fixing
> in *every* possible case, maybe even needing hardware traps?"

Given that criteria, *none* of the examples you posted are categorically
*always* considered errors to a C programmer, since I can easily show at
least one case (usually taken from my past and current experience) where
they are not considered errors. So your entire argument fails right
there. You're making grandiose claims about C programmers and "C think"
and here I am providing a counterexample.

Again, you talk about Forth in an embedded systems context, but when you
talk about C, you refuse to do the same. You compare apples to oranges,
which of course is nothing new to you. You've been delighting
comp.lang.forth with your fruit-salad nonsense for years.

> BEGIN AGAIN \ forever
>
> If
> that means 'forever' or until power is cycled or reset is pressed
> and that *could* be valid code
> then it should *NOT* be catagorically considered a bug
> and it should *NOT* be disallowed either by the compiler
> or by the hardware.

It isn't disallowed by C. Any functioning C compiler will generate code
that does exactly what it says. The equivalent C code is either:

while (1)
;

Or...

do {
} while (1);

Format as you like, the compiler doesn't care.

Okay, dispensing with the question of C, let's move next to the
hardware. Code this in a C compiler for any of the microprocessors I
typically use (Z80-family, 6502-family, 8051, HC08, ColdFire, ARM, and
probably others), and they will gladly allow that code to run until the
end of time or the next power cycle, which ever comes first.

So if it isn't disallowed by C, and isn't disallowed by the hardware...
what exactly is your point again?

> If
> it is simply a bug in *all* cases
> then the software or hardware should prevent it
> or fix it.

There are two cases to consider:

Your code is clearly a bug in *some* cases, but since C (like Forth)
can't tell if this is a bug or the actual intent of the programmer, C
will faithfully compile the code to do what the programmer wants-- just
like Forth. C puts absolutely no barrier to the programmer here and
does what the programmer wrote. And since we're talking about embedded
systems here and not general purpose computing, we typically don't have
any operating system on the target that could possibly complain either.

So we turn to hardware. Here again, the code may certainly be a bug in
*some* cases, but the microprocessor can't know that. So on smaller
microprocessors, the decision is to simply ignore the issue-- processors
like the Z80-family, 6502-family, 8051-family, and many others typically
don't have any kind of watchdog in the system at all. If the specific
application calls for a watchdog (for example safety-critical systems),
it is added externally and thus becomes a decision by the system
designer. In processors that that have integrated watchdogs, I have yet
to see any microprocessor or microcontroller where the programmer
couldn't disable it if they knew it wasn't necessary.

> As far as I got you got the answers right whenever
> you left the questions in the orginal context.

You didn't provide the context for each example, except possibly in your
own head. I wish you would be honest about that, but for some reason
you feel the need to lie. You wrote a message that was intentionally
ambiguous and vague so that you could make another one of your grandiose
points that went nowhere when held up to the light of day.

It must be a Zen thing-- I guess you're always trying to find balance.
For every worthwhile insight you provide comp.lang.forth, you feel the
need to balance it with bullshit straw-men arguments that don't make any
sense. But don't worry Jeff, I'm sure you can issue more speeches in
front of audiences who won't question you. Must do wonders for your ego.

Jeff Fox

unread,
May 22, 2006, 6:14:17 PM5/22/06
to
I did a few futher tests and found it is actually a bit more
compliated. Some Forths will allow one to drop items
from the stack and it apparently just resets the stack
pointer to the bottom of the stack each time and causes
no error.

Some Forths will allow the error to happen and won't
throw out of a program when it happens. They may
report a stack underflow when they get to the command line
: demo drop ." ok " ;
: test demo cr ." still running " ;
: it test cr ." no errors " ;

doesn't display an error message until it hits the command line.

: demo 10 0 do drop loop ;

does the same thing in displaying a message when it hits
the command line in swiftforth.

: demo 1000000 0 do drop loop ;

crashes the environment

My assertion, was that it has not been an error for us for
fifteen years. My assertion was that it was seen as an
error by some despite the fact that we see it as a nice
exploitable feature. My assertion was that the way it
was implemented in some Forth it would cause a crash.

I was right about all that, so I don't see how anyone
should see that my valid demonstration of how 'some'
people do see it as an error is a straw man. Jerry
has repeated that he see it as an error.

But we don't think it has to be an error. We agree that
if you see it as an error, and implement it as an error
then it IS an error for you. I won't go so far as to say
that it was an error by you if you implemented it that way.
I would say it is an error by you if you still think that
it *has* to be an error.

The whole point was to ask if some people see errors
where other people don't. The answer is yes. And
even in ANS Forth it seems it has a lot to do with the
implementation.

Dropping something from the bottom of a stack might
or might give a warning or an error in ANS Forth it
seems. It might put a message on the command line.
It might crash the system. Or it might do nothing
except readjust the pointer to the bottom of the stack.

It is not an error where we live, and that is hard for some
people to understand. Maybe someone will be able to
communicate to some that what we do is real and does
exist and that it is different that what remember about
Forth from thirty years ago in a few ways. One of them
is that dropping garbage off the bottom of the stack
is a useful thing and not an error condition for us.

Despite this being a simple idea it is a stumbling block
for many who cling to the thirty year old practice and
even older notions. I notice that Pic processors have
a stack wrap feature. Some users like it and say it
simplifies their programming. Some users say that
it is different and that they don't like that. Some say
that they want to use C and those crazy wrapping
stacks make that difficult. The problem that people
are used to what people are used to is not unique
to us.

Bernd Paysan

unread,
May 22, 2006, 4:58:53 PM5/22/06
to
Marcel Hendrix wrote:

I don't know what Jeff wanted to see, but IMHO the critical point is when
you *not* have the 1 on the stack before you call test. The question then
is: Does Gforth catch the stack problem before it prints "this is not an
error!" or does it print this message and then realize that the stack is
empty.

The latter is the case when we don't have hardware or OS support for
detecting the empty stack when it actually happens.

jmdra...@yahoo.com

unread,
May 23, 2006, 4:55:06 PM5/23/06
to

Jeff Fox wrote:

> This thread is about whether these traditional embedded
> Forth sorts of things that I described earliker are easily
> mistaken for bugs in C view or might look like they might
> need or want the sort of complications that this code avoids.
>
> > 1. begin again \ forever
>
> Every Forth programmer is suppose to be able to read that.
> It is simple. There is no confusion about what it says.
> It does not specify an error condition and to consider it an
> error would be introduce a real error. I would expect that
> most programmers in traditional Forth have done it many
> times.

I agree. Not an error. It's an endless loop that's obviously
documented as an endless loop by the "\ forever". A bug
is when someone accidently creates an endless loop.
For example someone forgetting to increment a list
pointer.

> > 2. begin ?key until \ no key pressed
>
> Another non-error. Misinterpretting it as an error that needs
> hidden background tasks or watchdog timers or interrupts
> is sort of the opposite of this simple straightforward code
> that does what it says, says what it does and is the
> sort of thing that gives Forth an advantage.

Hmmm...ok. I'd call this a "documentation quirk".
The code is clear. Keep looping until a key is
pressed. Why didn't the comment just say that?

begin ?key until \ wait until key pressed

Anyway, if the keyboard is unplugged at this point that's
a hardware error. ;) Of course, assuming hotplugging
the keyboard is ok, it's easily fixable.

> > 3. begin 255 p@ 8 and until \ port bit always false
>
> Just like 2, except waiting on an event that might or might
> not be a key press. But it does what it says and says
> what it does, ad it is clear and simple.

Another commenting quirk (to me anyway). The code is
clear. The comment isn't. Why would you expect
the port bit to ALWAYS be false if there's a chance there
might be an event when it's TRUE? I'd rather see:

begin 255 p@ 8 and until \ port bit false unless event X

Maybe "event X" is critical temperature of nuclear reactor
reached. Maybe the code after this loop is "initiate
emergency shutdown".

> > 4. data rom-address !
>
> Traditional embedded style Forth has always made this sort
> of thing easy. Maybe on this project when I wrote to ROM it
> gets decoded as io output. Maybe the comment will read,
> "turn on the panel light" and it won't be an error at all
> either in software or hardware. Writing to ROM could be
> something to give us an advantage over hardware or
> software that make the real problem harder to solve.
>
> If it confuses solutions for bugs it will introduce REAL bugs.

The first computers I programmed on used memory
mapped I/O. (TRS-80 model 4 and color computer).
"Peeking" and "Poking" ROM was legal. Admittedly
this was beyond much of what I was doing at the time.

> > 5. : demo 2 0 / ;
> > demo
>
> It is unlikely to define demo that way, but division by zero is
> 'undefined.' So we get to do what we want since we got to
> define what / does with 0. And since that is what our code
> says we want to do here, we assume that the action that
> we want to have associated with division by zero will take
> place and that no error is going to happen here.
>
> Throwing an error that we didn't want would be a bug.

Ok. I honestly never thought of that. But I think that's
dependent on:

A) defining your own CPU or
B) redefining "/" as a word rather than a primative

I tested # 5 on Pentium ColorForth (the version I have
anyway) and it locks up. I suppose I could redefine
the "/" to check and see if the divisor is 0 and take
some action other than executing the Pentium
division primative. But wouldn't that slow my code
down? Still I suppose this doesn't apply if your
talking about Forth running on a Forth chip. And
I'm guessing you're giving us another "hint" about
the new Intellasys chips. ;)

> Consider that you want to write the shortest, fastest and
> lower power consuming code that you can to do xyz.
> We have been talking about that goal. And after you write
> the inner loop of your app you realize that it has a balanced
> stack, exactly the same number of DUPs as DROPs. So
> you ask yourself, in this embedded Forth what will happen
> if I remove the final DROP in the loop?

Ok. That's pretty cool. I had to read it a few times to
understand.

> > 9. a program pops from a stack more items than it pushed
> > to the stack.
>
> These non-bugs are getting more powerful. The ability to
> keep taking the same items off the stack again and again
> without generating an error is something that can be
> exploited. Since stacks are faster than memory here
> and can deliver a repeating pattern faster than reading
> it from memory or dealing with hardware stack underflow
> trapping it is another win. It is another form of freedom
> to beat hardware and software that has to work the
> way mainframes work.

Also interesting.

> And people are suppose to figure out the pattern of the quiz
> by now. Nine non-bugs each getting more useful and a
> more important example of what distinguishes where
> traditional cooperative Forth has gone in the last twenty
> years and things that give it an advantage are suppose to
> suggest that the biggest non-error is the last.
>
> > 10. hardware that will go to sleep when reading ports and
> > waiting for a neighbor to write is in a sleep state
> > and neighbors are also a sleep trying to read.
>
> If any of the others were confused for errors it is likely
> that this one would be too. This characterized everything
> we are doing. If you confuse it with an error you will have
> trouble understanding what we do and what advantages
> we get by doing it the way we do it. Since it is a bit of a
> trick question because we haven't released all the
> hardware and software details of what we are doing I
> gave everyone more than nine hints.

Ok. Here's how I see this might work. One or more
of the sleeping processors is waiting for a signal
external to the chip? For example a digital audio
signal comes in and causes a cascade of chips
waking up in sequence?

Regards,

John M. Drake

John Passaniti

unread,
May 25, 2006, 2:14:06 AM5/25/06
to
Jeff Fox wrote:
> I have the impression that people would prefer that I don't
> try to respond to your posts and focus on answering
> their questions. But unless someone asks again that
> I not bother I will try.

I honestly don't care if you respond to me or not. You have
consistently shown in the past that you aren't interested in real
discussion where your statements are challenged, counterexamples are
provided, and your logic is examined.

>> C doesn't insist on anything.
>
> Only on C being C.

Wow, how Zen. The thing is what it is. Why not write that on some rice
paper and hang it from a cherry blossom tree?

> It was nice. I hadn't thought of that kind of simplified definition of
> a 'hello world program.' So I did the same sort of thing that you
> had talked about in this embedded C style hello world. One version
> was only about a hundred times smaller than yours, and the
> other was only a couple of dozen times smaller.

One thing that I find amusing about you is how you apply different
standards in order to win arguments. In past conversation, you have
insisted that C programmers include the size of the operating system and
any libraries in with the size of their program. And at least for
embedded systems, I fully agree, they should.

Yet you don't seem to do the same when talking about Forth. You claim
your Forth version of the "Hello World" program was a "hundred times
smaller" than the 192 bytes I gave. I'll assume that means it was 92
bytes long. Are you honestly telling me that you have a Forth compiler
that is less than 92 bytes long? Last I checked, the smallest
Forth-like language I knew of ("False") was around 1k bytes long.

Please post the source code for this Forth compiler that's 92 bytes
long. It's so short, it shouldn't take you any time to post the source.

No, unless you were lying (which with you is always a possibility),
you're probably comparing apples to oranges again. Yes Jeff, if I write
"Hello World" in assembly language for the same processor, I can get it
down to about 32 bytes, including all code needed (processor
initialization, a routine to write to the UART, and a simple loop to
output the characters). So what you're probably doing here is not
talking about Forth, but talking about cross-compiling to a different
processor that needs less initialization than the processor I'm using,
and you're probably not initializing RAM.

Wow, that's compelling.

Of course, none of this matters. Your original question was based on
your continued misunderstanding of the differences between C programmers
targeting operating systems and C programmers targeting embedded
systems. You were expecting to hear about a "Hello World" program that
was kilobytes if not megabytes long, and my statement that an embedded
version of the code (which was your question) was 192 bytes kind of
knocked your argument out of the water.

The fact you can generate less code isn't the point, since you're either
not including the size of Forth, or you're talking about coding the
equivalent in assembly language.

> I didn't want an apples to organges comparison since I had at
> first been talking about a traditional hello world display to a video
> terminal. So when you wanted to compare that to a simplfied
> version I wrote a simplfied version too for comparison that
> would be more fair and got the same kind of results.

The equivalent for writing to video (typically a block of memory) takes
slightly less code:

#include <string.h>

void main(void) {
strcpy((char*) 0x8000, "Hello World!");
}

This code assumes that video memory starts at 0x8000 in RAM. Since you
didn't specify where video memory was located, I used an address from a
system I've used in the past. Total size of this application code is
165 bytes.

If your have a different video system in mind, please provide specifics.

> General-purpose is a meaningless buzzword. There is no such thing.

More semantic games. I am clearly using "general purpose" to
differentiate between embedded systems and non-embedded systems. If you
still have a hard time understanding the difference, I suggest you read
this white paper:

http://www.intellasys.net/resources/EmbeddedProcessors.pdf

You might know the author. He doesn't seem to have a problem seeing the
difference between embedded applications (which are dedicated systems
and thus not general purpose).

> Any idiot can try to cause confusion by purposely taking things
> out of one context and putting them in another where what was
> true now becomes false.

Stop calling yourself an idiot.

> Not quite. But they expect a lot more bare metal if they are thinking
> C. That has been the point of this thread in my mind. I know it your
> mind it is a thread talking about how you feel personally about me.

Again, the counterexamples to your statement exist all around you, but
you choose to ignore them. Ignoring the fact that I know *no* embedded
systems programmers who code in C that expect anything more than the
ability of the compiler to generate code. They don't expect operating
systems. They don't expect the underlying processor will have exotic
support for multitasking. They don't expect *anything* more than what
the processor itself can do, and what the hardware connected to it is
designed for.

> I say the C mindset expects hardware that resembles and works
> like mainframes or minis, hardware designed to deal with that set
> of restricted problems. I say it is not general purpose hardware.
> It is C purpose hardware. C expects and demands C purpose hardware.

Yet you provide *zero* examples to illustrate this claim, and I can
provide endless counterexamples. You show no real-world system that
illustrates your claim because you know you can't. The moment you are
forced away from comparing apples to oranges, your argument falls flat
on it's face.

It's simple Jeff. If you make a claim, you should be able to
demonstrate that claim. And here, such a demonstration requires more
than just you saying so. It requires real world examples. You provide
none.

>> do {
>> } while(1);
>>
>> I don't see a bug there. I don't see a hidden background task.
>
> Good. I don't either. But I only see a code snippet not the whole
> application or system just like the example I gave.

Nonsense. You code example was this:

BEGIN AGAIN \ forever

Where is the "whole application or system" described?

> And since in that context it is what it is, it is clearly not a bug.
> If that is a bug then C is a bug. Likewise if BEGIN AGAIN
> is a bug that must not be allowed then Forth is a bug.

It is neither a bug in Forth or C because you didn't provide the context
of that loop. You are ambiguous so your question is meaningless. But
assuming the above loop in Forth isn't a bug then it isn't a bug in C
either. The same goes for *all* of your examples.

> Of course if I add real world constraints you will lose. If I choose
> the problem, if I choose the target, if I choose the contraints
> then confounding C is easy. Without knowing the odds, the
> target, and the problem to be solved claiming that one language
> can do whatever another language can do is absurd.

No such claim was made. You made the claim that C programmers consider
your examples bugs. They do not, at least not embedded systems C
programmers, which presumably is the larger context you're talking about.

> I must admit it would be fun to go somewhere where I could
> put my money where my mouth is and take a lot of money
> from a troublesome fool. But it would be too easy, too unfair,
> and no one would learn anything that they don't already know.

I don't quite see the point you are making. You seem to be saying that
you could come up with a set of constraints that C couldn't match. Yep,
that's absolutely true. I could come up with a set of constraints your
company's chips couldn't match (for example, I need for each processor
to be able to directly address 32 bits worth of memory-- presto, you've
lost).

What is the point you're trying to make with this idiocy? I have made
no claim that C (except in a Turing-complete sense) can do exactly what
Forth can. I thought the discussion was what C programmers supposedly
consider to be bugs, and now you're (as usual) veering off on some
argument I'm not even making.

> And it wouldn't be fair anyway to expect you to write code for free
> since you are a professional. You would be giving me a huge advantage
> if I choose the weapons and the place of the engagement and that
> would be very fair either. I would be willing to give you lots of
> advantages and lots of odds, headstart, relaxed requriements
> for you etc., but it would still be a sucker bet.

And I can do the same for you. What is the idiotic point you're trying
to make?

> And I know that people don't want to see me respond to your
> personal stuff, or try to make this about you like you want to
> make it about me. So we really shouldn't try the programming
> challange.

I'm not interested in trying to prove something I never claimed. What I
am interested in doing is taking your dumb arguments about C programmers
and providing real-world counterexamples to show you are somewhere
between wrong, mistaken, uninformed, and dishonest. And really for me,
it's the last one-- your intellectual dishonesty-- that really bothers
me. You start off talking about embedded systems, and then when talking
about C, shift the argument away from embedded systems.

> But thanks for the questions that let me clarify my positiion
> about things like, C programmers are so arrogant that they
> tell you C is general purpose. Maybe they all think that
> they are generals.

The only arrogance I see here is you presuming to speak for embedded
systems programmers who use C. What you say doesn't match my
experience, doesn't match the experience of the many engineers I've
worked with over the past 20-something years, and doesn't bear anything
in common with the tools and techniques actually used by C programmers
targeting embedded systems. It's just your usual fun-house mirror
reflection of the real world.

Here's a wild idea Jeff-- before you arrogantly presume to speak for
embedded systems programmers who use C, how about you *ask*. You might
learn something.

ast...@netcourrier.com

unread,
May 25, 2006, 6:11:20 AM5/25/06
to
John Passaniti wrote:
> Jeff Fox wrote:
> > I have the impression that people would prefer that I don't
> > try to respond to your posts and focus on answering
> > their questions. But unless someone asks again that
> > I not bother I will try.
>

Well, sometimes that's interesting for non-native speakers to learn new
bird names ;)

> > It was nice. I hadn't thought of that kind of simplified definition of
> > a 'hello world program.' So I did the same sort of thing that you
> > had talked about in this embedded C style hello world. One version
> > was only about a hundred times smaller than yours, and the
> > other was only a couple of dozen times smaller.
>
> One thing that I find amusing about you is how you apply different
> standards in order to win arguments. In past conversation, you have
> insisted that C programmers include the size of the operating system and
> any libraries in with the size of their program. And at least for
> embedded systems, I fully agree, they should.
>
> Yet you don't seem to do the same when talking about Forth. You claim
> your Forth version of the "Hello World" program was a "hundred times
> smaller" than the 192 bytes I gave. I'll assume that means it was 92
> bytes long. Are you honestly telling me that you have a Forth compiler
> that is less than 92 bytes long? Last I checked, the smallest
> Forth-like language I knew of ("False") was around 1k bytes long.
>

Are you saying that you ran genuine gcc, cpp , ld and friends on an
embedded target?

>
> Of course, none of this matters. Your original question was based on
> your continued misunderstanding of the differences between C programmers
> targeting operating systems and C programmers targeting embedded
> systems. You were expecting to hear about a "Hello World" program that
> was kilobytes if not megabytes long, and my statement that an embedded
> version of the code (which was your question) was 192 bytes kind of
> knocked your argument out of the water.
>

I think the problem here is that one talks about 'C programmers' in
general; Jeff is talking about the mainstream C programmer while John
is talking about sort of a 'savvy C programmer'. In my day work, I
often tell others what they should and should not do in order to
optimize C code for an embedded target, the others being "native" C
programmers that you usely write software for desktops (in extenso: C
is the portable assembler, the first layer of abstraction and below is
terra incognita), when my native language is assembly, so I know a
thing or two about what is below C.
And I often agree with Jeff because embedded targets become more and
more powerful so that you can program them in standard C, and often put
a stripped down Linux on it, and then have a mainstream C programmer to
program it. And often the hardware is sized and selected ("We need
MMU") with this idea that a standard C programmer is going to program
it.

> #include <string.h>
>
> void main(void) {
> strcpy((char*) 0x8000, "Hello World!");
> }
>
> This code assumes that video memory starts at 0x8000 in RAM. Since you
> didn't specify where video memory was located, I used an address from a
> system I've used in the past. Total size of this application code is
> 165 bytes.
>
> If your have a different video system in mind, please provide specifics.
>

This is ridiculous; that kind of conversation gives a bad idea about
Forth to others. Yesturday someone told be something like "The Forth
way of spending hours to optimize things to get shrink down programs
can hardly be called productive".
The point I see on this topic is that the instinctive program...
void main(void) { printf("Hello World"); }
is what happens with maintream C programmers. Of course savvy C
programmers know that puts is obviously more adequate for this. But if
you have, say, to display the date in your message, even more
programmers will use a printf, which will probably be 50% of the
program size.
If a mainstream C programmer is forced to look at the size of his/er
program, maybe he'll find out that printf is the problem. But unless
s/he doesn't look at the size of the binary, this same person will feed
numbers for typical binary sizes for suboptimal code and these figures
will be used to size the next embedded board.

> http://www.intellasys.net/resources/EmbeddedProcessors.pdf
>
> You might know the author. He doesn't seem to have a problem seeing the
> difference between embedded applications (which are dedicated systems
> and thus not general purpose).
>

Maybe one should question this distinction between embedded and desktop
apps. The fact is that there is more embedded apps than desktop apps,
and still more people are unhappy about their Winux PC than with their
MP3 player.
IMO, all these resources ready-to-be-wasted on the PC is cause of many
software non-problems.

> Again, the counterexamples to your statement exist all around you, but
> you choose to ignore them. Ignoring the fact that I know *no* embedded
> systems programmers who code in C that expect anything more than the
> ability of the compiler to generate code. They don't expect operating
> systems. They don't expect the underlying processor will have exotic
> support for multitasking. They don't expect *anything* more than what
> the processor itself can do, and what the hardware connected to it is
> designed for.
>

Well, you're a lucky man who have savvy C programmers as co-workers; my
coworkers comes from Java or Windows GUI and I have to keep an eye on
what there are doing cause once one asked me if he could use a thread
to refresh the WDT and the other was taken aback that strcat doesn't
use the garbage collector to allocate new string (or something like
that).
Now, that's an extreme example and they've learned quite well since,
but we are really surrounded by un-savvy, mainstream C programmers.

> > I say the C mindset expects hardware that resembles and works
> > like mainframes or minis, hardware designed to deal with that set
> > of restricted problems. I say it is not general purpose hardware.
> > It is C purpose hardware. C expects and demands C purpose hardware.
>
> Yet you provide *zero* examples to illustrate this claim, and I can
> provide endless counterexamples. You show no real-world system that
> illustrates your claim because you know you can't. The moment you are
> forced away from comparing apples to oranges, your argument falls flat
> on it's face.
>

I for one remember to have read that the ENTER and LEAVE instructions
of the 186 were added with the idea of C-like languages in mind.

> >> do {
> >> } while(1);
> >>
> >> I don't see a bug there. I don't see a hidden background task.
> >
> > Good. I don't either. But I only see a code snippet not the whole
> > application or system just like the example I gave.
>
> Nonsense. You code example was this:
>
> BEGIN AGAIN \ forever
>
> Where is the "whole application or system" described?
>

I know that I can fetch my old 4IM standalone 740K floppy disk, modify
it and recompile the whole thing from source to turnkey it, and I know
that it will take less time than googling for something that could do
the same for do{ }while(1);
That's my interpretation of it.

> > And since in that context it is what it is, it is clearly not a bug.
> > If that is a bug then C is a bug. Likewise if BEGIN AGAIN
> > is a bug that must not be allowed then Forth is a bug.
>
> It is neither a bug in Forth or C because you didn't provide the context
> of that loop. You are ambiguous so your question is meaningless. But
> assuming the above loop in Forth isn't a bug then it isn't a bug in C
> either. The same goes for *all* of your examples.
>

Read again the OP. The question was about if one expects or not the
hardware to detect it and flag it as a bug.
I think it is pretty obvious for a Forth programmer that the nine first
examples should not be addressed by the hardware, but from what I see
from other forums, it's not obvious to everyone.

> > And it wouldn't be fair anyway to expect you to write code for free
> > since you are a professional. You would be giving me a huge advantage
> > if I choose the weapons and the place of the engagement and that
> > would be very fair either. I would be willing to give you lots of
> > advantages and lots of odds, headstart, relaxed requriements
> > for you etc., but it would still be a sucker bet.
>
> And I can do the same for you. What is the idiotic point you're trying
> to make?
>

You two are lost in pointless arguments about nothing. The OP was kind
of a poll to
see how many people and to what degree were thinking in a similar way
as other peoples in other so-called higher level languages do.

Amicalement,
Astrobe

John Passaniti

unread,
May 25, 2006, 12:54:09 PM5/25/06
to
ast...@netcourrier.com wrote:
> Are you saying that you ran genuine gcc, cpp , ld and friends on an
> embedded target?

No.

Jeff's original message (http://tinyurl.com/o5j42) asked about the size
of executables generated from cross compilers. The question was not
constrained by the tools used, or where the tools were executed. The
question simply asked what is the total size of the executable.

Since the context of that message was embedded systems, I took a real
world microcontroller (an HC08-family part) a real world C compiler
(ImageCraft), and this "Hello World" program:

#include <stdio.h>

void main(void) {
puts("Hello World!");
}

The result was 192 bytes. The resulting code runs on the bare metal of
the microcontroller (there is no operating system) and outputs the
string to a serial port.

Jeff was apparently surprised at two things. First, that I didn't use a
wasteful "printf" where it wasn't needed (there is no formatted printing
here, so "puts" is all that's needed), and second he was apparently
thinking not of output to a serial port, but to video memory. That is
indeed key, since the vast majority of what most people would consider
embedded systems don't have video displays. Jeff was (as is often the
case) comparing apples and oranges-- when talking about Forth he talks
about embedded systems, but when he talks about C, he talks only about
non-embedded systems. He talks about systems running operating systems
with fancy processors that have MMUs and other hardware designed to
assist the operating systems.

> I think the problem here is that one talks about 'C programmers' in
> general; Jeff is talking about the mainstream C programmer while John
> is talking about sort of a 'savvy C programmer'.

No, I am talking about C programmers who target embedded systems. I
suppose there is a certain level of implicit savvy implied there. You
can't really be an embedded systems C programmer without understanding
the underlying hardware. A simple example would be that the average C
programmer who writes non-embedded code would *never* write something
like this:

#define SCID (*(volatile unsigned char*) 0x27)
#define SCIS1 (*(volatile unsigned char*) 0x24)
#define TC (1 << 6)

void putchar(char ch) {
while ((SCIS1 & TC) == 0) // wait transmitter clear
;
SCID = ch; // send character
}

This is code I recently wrote to output characters to a HC08-family
part's serial port (if you care, it's the very cute QG8). A
non-embedded C programmer would never write code like this because their
application would be sitting on top of an operating system and they
would not be writing direct to the underlying system hardware. But in
the embedded C world, we rarely have an operating system and we do
exactly what is done in Forth when talking to the bare metal.

This isn't an issue of "savvy" verses "average" C programmers. This is
an issue of embedded verses non-embedded C programmers. Jeff apparently
doesn't understand the difference and lumps them all together. His
arguments have some weight when talking about non-embedded C
programmers, but that's an apples to oranges comparison.

> And I often agree with Jeff because embedded targets become more and
> more powerful so that you can program them in standard C, and often put
> a stripped down Linux on it, and then have a mainstream C programmer to
> program it. And often the hardware is sized and selected ("We need
> MMU") with this idea that a standard C programmer is going to program
> it.

You often agree with Jeff because your arguments are often as fuzzy and
ill-constructed as his. Birds of a feather...

Yep, the costs of running such a system are coming down. But that is
the high end of the embedded systems world. The vast majority of it has
nothing to do with that class of hardware. The majority of processors
in the world aren't Pentiums and PowerPC and so on. It's 8-bit and
16-bit microprocessors and microcontrollers, sitting in every electronic
device you own. It's the DSPs in cell phones and it's the tiny
processors embedded in FPGAs.

> If a mainstream C programmer is forced to look at the size of his/er
> program, maybe he'll find out that printf is the problem. But unless
> s/he doesn't look at the size of the binary, this same person will feed
> numbers for typical binary sizes for suboptimal code and these figures
> will be used to size the next embedded board.

You keep putting this in the context of "mainstream" verses "savvy" and
completely missing that the issue here isn't how sophisticated the C
programmer is. The issue here is what is the platform the C programmer
is targeting. The context that surrounds the entire discussion here
isn't smart verses dumb programmers. The context is *embedded systems
programming." Jeff starts with that context when talking about Forth
and then completely ignores it when moving to discussions about C.

*THAT* is the real issue here.

> Maybe one should question this distinction between embedded and desktop
> apps. The fact is that there is more embedded apps than desktop apps,
> and still more people are unhappy about their Winux PC than with their
> MP3 player.

EXACTLY. And now your challenge is to determine if Jeff is even capable
of making that distinction! He certainly isn't in this thread. He's
treating all C programmers the same, conveniently forgetting that there
are big differences between them, depending on what kind of systems they
are writing code for.

> Well, you're a lucky man who have savvy C programmers as co-workers;

I'm not a lucky man. I'm an embedded systems programmer and so are my
co-workers. It isn't about being savvy or not. It is entirely about
the nature of the work we do. And we are far from unique in that regard.

> my
> coworkers comes from Java or Windows GUI and I have to keep an eye on
> what there are doing cause once one asked me if he could use a thread
> to refresh the WDT and the other was taken aback that strcat doesn't
> use the garbage collector to allocate new string (or something like
> that).

In other words-- they aren't embedded systems programmers!

> Now, that's an extreme example and they've learned quite well since,
> but we are really surrounded by un-savvy, mainstream C programmers.

Then you simply aren't hiring the right people. Let me guess, your HR
department advertises for "C programmers" and accepts for interviews
anyone who knows how to balance braces.

That has never been the case in any of the companies I've worked for or
know of. In order to be an embedded systems programmer, the candidate
needs to be an EE major (or equivalent). They need to know how to read
a schematic. They need to be able to be able to use tools like
oscilloscopes and logic analyzers.

When I've conducted job interviews for embedded systems programmers, I
often will give the candidate a schematic, access to the relevant
datasheets, and start asking questions. I'll ask for example for them
to look at a schematic to determine how the address space is decoded.
If they can't do that, it's unlikely we'll hire them.

That's not savvy. That's knowing the domain. If your company is hiring
C programmers who don't understand embedded systems work, then I predict
your company won't be around long. Hire the right people.

>> Nonsense. You code example was this:
>>
>> BEGIN AGAIN \ forever
>>
>> Where is the "whole application or system" described?
>>
>
> I know that I can fetch my old 4IM standalone 740K floppy disk, modify
> it and recompile the whole thing from source to turnkey it, and I know
> that it will take less time than googling for something that could do
> the same for do{ }while(1);
> That's my interpretation of it.

Your response here makes about as much sense as Jeff's. Care to
rephrase that, please?

> Read again the OP. The question was about if one expects or not the
> hardware to detect it and flag it as a bug.
> I think it is pretty obvious for a Forth programmer that the nine first
> examples should not be addressed by the hardware, but from what I see
> from other forums, it's not obvious to everyone.

It's not obvious to everyone because Jeff's message was ambiguous. As I
wrote before, if the statement prior to "BEGIN AGAIN" was to turn on the
x-ray generator aimed at the patient's head, then yep, "BEGIN AGAIN" is
a *huge* bug. But if the statement prior to the "BEGIN AGAIN" was to
print the message "firmware update completed, please reboot system" then
it most certainly isn't a bug.

Without the context of how the statements are actually being used,
Jeff's examples are meaningless. Judgment on if something is a bug
requires knowing how something is used. Jeff didn't provide that. He
provided isolated examples that were entirely context-free.

So the best anyone regardless of language could ever do is say there are
cases where Jeff's examples are bugs and cases where they aren't. And I
fail to see how that in any way illuminates *anything*.

> You two are lost in pointless arguments about nothing. The OP was kind
> of a poll to
> see how many people and to what degree were thinking in a similar way
> as other peoples in other so-called higher level languages do.

I'm in a argument about how Jeff's initial message was next to
meaningless because he didn't provide a context. And I'm in an argument
about how Jeff doesn't differentiate between embedded systems
programmers and non-embedded systems programmers when talking about C.

ast...@netcourrier.com

unread,
May 25, 2006, 7:11:55 PM5/25/06
to

John Passaniti a écrit :

> > I think the problem here is that one talks about 'C programmers' in
> > general; Jeff is talking about the mainstream C programmer while John
> > is talking about sort of a 'savvy C programmer'.
>
> No, I am talking about C programmers who target embedded systems. I
> suppose there is a certain level of implicit savvy implied there. You
> can't really be an embedded systems C programmer without understanding
> the underlying hardware.

[SNIP]


> This isn't an issue of "savvy" verses "average" C programmers. This is
> an issue of embedded verses non-embedded C programmers.

I think the snip I made is honest; Is it me or is it a contradiction?

> Yep, the costs of running such a system are coming down. But that is
> the high end of the embedded systems world. The vast majority of it has
> nothing to do with that class of hardware. The majority of processors
> in the world aren't Pentiums and PowerPC and so on. It's 8-bit and
> 16-bit microprocessors and microcontrollers, sitting in every electronic
> device you own. It's the DSPs in cell phones and it's the tiny
> processors embedded in FPGAs.
>

BTW, for these chips I really wonder what is the point of using C; I
imagine that a significant part of the code is highly tied to the chip
(writing directly to I/O ports), and I imagine that there are parts in
assembly, too. Wouldn't it be just as good to write the would thing in
assembly?

> > If a mainstream C programmer is forced to look at the size of his/er
> > program, maybe he'll find out that printf is the problem. But unless
> > s/he doesn't look at the size of the binary, this same person will feed
> > numbers for typical binary sizes for suboptimal code and these figures
> > will be used to size the next embedded board.
>
> You keep putting this in the context of "mainstream" verses "savvy" and
> completely missing that the issue here isn't how sophisticated the C
> programmer is.

Of course, it was my original attempt to explain the miscommunication.
If I was wrong above I'm wrong here too. You said above I miss the
point, and if you really think that you can just snip the parts that
draw conclusions from it.

> The issue here is what is the platform the C programmer
> is targeting. The context that surrounds the entire discussion here
> isn't smart verses dumb programmers. The context is *embedded systems
> programming." Jeff starts with that context when talking about Forth
> and then completely ignores it when moving to discussions about C.
>
> *THAT* is the real issue here.
>

All right, there are C programmers out here that do program in C really
small 8bits chip and that mostly do the same as they would in Forth,
because at this scale the language you choose doesn't really matters.
Now we can talk about medium to "high-end" (as you named it) embedded
stuff on which one can run an OS and a program in full-blown C (not
some stripped-down version).

> > Maybe one should question this distinction between embedded and desktop
> > apps. The fact is that there is more embedded apps than desktop apps,
> > and still more people are unhappy about their Winux PC than with their
> > MP3 player.
>
> EXACTLY. And now your challenge is to determine if Jeff is even capable
> of making that distinction! He certainly isn't in this thread. He's
> treating all C programmers the same, conveniently forgetting that there
> are big differences between them, depending on what kind of systems they
> are writing code for.
>

The whole point of C is portability. Wanting to sort C programmers on
the target there are writting for looks like an oxymoron, or at least
that this thread is already off the road.

> > Read again the OP. The question was about if one expects or not the
> > hardware to detect it and flag it as a bug.
> > I think it is pretty obvious for a Forth programmer that the nine first
> > examples should not be addressed by the hardware, but from what I see
> > from other forums, it's not obvious to everyone.
>
> It's not obvious to everyone because Jeff's message was ambiguous. As I
> wrote before, if the statement prior to "BEGIN AGAIN" was to turn on the
> x-ray generator aimed at the patient's head, then yep, "BEGIN AGAIN" is
> a *huge* bug.

It's ambiguous when one doesn't read all the lines:
"Which of the following 10 conditions should be considered hardware
errors?"

Amicalement,
Astrobe

John Passaniti

unread,
May 26, 2006, 4:59:41 PM5/26/06
to
ast...@netcourrier.com wrote:
>>> I think the problem here is that one talks about 'C programmers' in
>>> general; Jeff is talking about the mainstream C programmer while John
>>> is talking about sort of a 'savvy C programmer'.
>> No, I am talking about C programmers who target embedded systems. I
>> suppose there is a certain level of implicit savvy implied there. You
>> can't really be an embedded systems C programmer without understanding
>> the underlying hardware.
> [SNIP]
>> This isn't an issue of "savvy" verses "average" C programmers. This is
>> an issue of embedded verses non-embedded C programmers.
>
> I think the snip I made is honest; Is it me or is it a contradiction?

I don't understand your question. Please rephrase.

There are very savvy C programmers who know nothing about the embedded
world-- programmers who couldn't tell you a thing about the underlying
hardware, but who are very well versed in writing tight and efficient
code for the operating system they are targeting. I for example am not
one of those people. As a C programmer, I have very little savvy when
it comes to calling the APIs of Linux, Windows, Mac OS, and so on. C
programmer who understand those environments can do much better than I can.

In other words, there are different kinds of savvy. My knowing how to
write tight and efficient code exploiting the hardware of an embedded
system doesn't mean one can do the same exact thing for code targeting
an operating system-- and vice versa. Sure there may be some overlap,
but what we're really talking about here is knowledge and experience in
a specific domain, not (necessarily) some intrinsic property of the
programmer.

> BTW, for these chips I really wonder what is the point of using C; I
> imagine that a significant part of the code is highly tied to the chip
> (writing directly to I/O ports), and I imagine that there are parts in
> assembly, too. Wouldn't it be just as good to write the would thing in
> assembly?

The amount of code that writes direct to hardware obviously depends on
what the application is. I have code for embedded systems that has
minimal involvement with the underlying hardware that implements some
complex algorithms. And I have the reverse-- dirt-simple code that
spends all its time manipulating the hardware directly.

The point of using C is the same as the point of using Forth or any
other language above assembler. It lets you operate at a higher level
of abstraction, and focus more on the *what* rather than the *how*.

Consider this example, inside some function:

int a, b;
...
int whatever = blah(a, b);

Now let's talk about the target. I'll use an 8-bit microcontroller in
the HC08 family as an example. Here's the output of the C compiler for
the above function call:

lda 3,X
psha
lda 2,X
psha
lda 5,X
psha
lda 4,X
psha
jsr _blah
ais #4
tsx
lda *__r0
sta ,X
lda *__r1
sta 1,X

What you see here is the *how* and not the *what*. Even if I added
comments to the above code, it is far more verbose than the original C.
You've got the setup for the function call, and the storage of the
function's result in "whatever." And because this is a 8-bit micro, we
have to treat each half of the integers separately.

I don't know about you, but the C code is far more readable and
expresses the intent much better than the above blast of assembly. The
same would be true of Forth or any other high-level language.

The other reason to code in C (or Forth) and not drop to assembly is
that it often simply isn't necessary. The way Forth programmers talk
about C in comp.lang.forth, you would think that tons of code are
emitted for even the simplest expression. But that's not true,
especially of C compilers that target embedded systems. For example,
let's say I have a LED connected to a port that I want to turn on. I
might write this code in assembler:

bset 0,0

On a HC08 family part, that would turn bit 0 of port "A" on. Here's how
you could code that same statement in C:

// in a header file somewhere...
#define PTA *(volatile unsigned char *) 0x00
#define BIT(n) (1 << n)

// in the application code...
PTA |= BIT(0);

This is a trivial example, but the C code generates the same code as the
assembly language above. In other words, you don't always need to drop
to assembler because the compiler is smart enough to exploit the
architecture of the processor.

There are many other reasons to code in C (or Forth, or another
high-level language). One is to avoid being locked in to specific
parts. Years ago, I worked on a Z80-based system, but for a variety of
reasons, we decided to switch to the 8051. If the code was all
assembler, we wouldn't have bothered as the effort to move to a
different processor would have been too great. But since the 90% of the
code was in C and not hardware specific, it was actually almost trivial
to switch to a different processor.

> Of course, it was my original attempt to explain the miscommunication.
> If I was wrong above I'm wrong here too. You said above I miss the
> point, and if you really think that you can just snip the parts that
> draw conclusions from it.

I don't "snip the parts." I read and considered every word of what you
wrote and responded to that, not some abbreviated version. Proper
quoting technique is a matter of style, and my style is not to quote the
every last word, but enough of the original context to continue the
conversation.

> All right, there are C programmers out here that do program in C really
> small 8bits chip and that mostly do the same as they would in Forth,
> because at this scale the language you choose doesn't really matters.
> Now we can talk about medium to "high-end" (as you named it) embedded
> stuff on which one can run an OS and a program in full-blown C (not
> some stripped-down version).

Sure, although the "medium to high-end" is a minority case in the
embedded systems world. Consider the market statistics:

http://en.wikipedia.org/wiki/Microprocessor#Market_statistics

According to that source, less than 10% of all CPUs sold in the world
are 32-bits or more-- the very class of systems you're talking about.
So if your goal is to find some context where Jeff's arguments make
sense, congratulations-- you've necessarily limited your conversation to
something less than 10% of the total potential market.

Incidentally, your statement suggests you believe the C compilers I'm
talking about for embedded systems are in some way limited. They
aren't. The HC08 C compiler I use supports the full C language and all
standard libraries that make sense on the target. It's been many years
since C programmers have had to put up with compromised compilers.

> The whole point of C is portability. Wanting to sort C programmers on
> the target there are writting for looks like an oxymoron, or at least
> that this thread is already off the road.

Your first statement is wrong because you used the qualifier "whole."
But even ignoring that, the rest of the statement is making a lot of
assumptions, the biggest being that you expect the majority of code in a
embedded system to be so highly hardware specific that portability
doesn't matter. And again, that depends on the specifics of the
embedded system. So are, some aren't.

But even if portability is important, as I showed above, programming in
C (or Forth, or any other higher-level language) is also about being
able to express intent more succinctly than the verbosity of assembler.

Your comments sound typical of those of someone who doesn't really
understand the embedded systems world. As a suggestion, don't follow
Jeff here and think your assumptions hold true. Ask.

> It's ambiguous when one doesn't read all the lines:
> "Which of the following 10 conditions should be considered hardware
> errors?"

Again, there is no context there. You can't say if something is a
hardware error or not unless one understands the surrounding context
that hardware is in. Allow me to demonstrate:

My car has a light bulb that is blown. Is this a problem?

You can't answer the question without knowing *which* light bulb is
blown. If it's the light bulb behind the car's logo on the dashboard,
then no, it isn't a problem (except for the marketing department of the
car company). But if that light bulb is a headlight, it's a very big
problem.

Jeff's ten conditions suffer from the same lack of context.

Jeff Fox

unread,
May 27, 2006, 11:18:09 AM5/27/06
to
ast...@netcourrier.com wrote:

Give John the last word and move on. He will just
embarrase himself further anyway.

Let him post ten or twenty long posts trying to obscure and
cover up his foolish mistakes and he will make his
points for you far better than you can.

If he objects to your statement that your hello world program
that is 2K is mostly OS and GUI and says that he can write
a stripped-down bare-metal "hello world" message directly to
a port, with no visible OS or video output in 1800 bytes using
printf or 200 bytes using the techniques a saavy C programmer
uses then that is great.

Since my stripped-down bare-metal 'hello world' message
direclty to a port, with no vislble OS or video output program
was under 20 bytes I thought his 10x and 100x examples
were nice. Can't any idiot do that in under 100 bytes?

So I just thanked John for providing more 10x and 100x examples
again and moved on. I think it drove him up the wall. He has been
reminding people of his failure on that example for months now,
and that is nice too.

He didn't consider his comparing OS to no OS apples vs
organges but he did consider my comparing my no-OS
example to his no-OS example to be an apples vs
organges comparison. Of course in one of his bare-metal
stripped-down mininal no-OS "hello world" message to
a port program examples was still bigger than mine with
the OS and GUI had been. That was really funny. ;-)

But when he gets angry and calls for another example of how
he can always write 10x or 100x more code than a Forth programmer
to solve a problem it is education for the people who do learn from
all his examples of C posted to this group of how C can't compete
with Forth.

Of course it is probably unfair to C for of any of us to use John's
C code as a fair test for any comparisons. Can't most newbies
write a 'mininal stripped-down bare-metal "hello world" message
directly to a port program, with no visible OS or video output' (as
he put it) in under 100 bytes?

Even if you start a thread, let John post many posts for every
one that you post. He will just say dumber and dumber things
if you don't argue with him. Give him a chance to call other
people who use Forth names.

John Passaniti

unread,
May 28, 2006, 12:35:24 AM5/28/06
to
Jeff Fox wrote:
> Since my stripped-down bare-metal 'hello world' message
> direclty to a port, with no vislble OS or video output program
> was under 20 bytes I thought his 10x and 100x examples
> were nice. Can't any idiot do that in under 100 bytes?

Sure can. I can do it in 29 bytes for the HC08 family (including
processor configuration of the port to a standard baud rate) if I code
in assembler. But you didn't ask for that. You asked what the size was
for a C compiler and that's what I provided. So here we go again, you
comparing apples to oranges.

> So I just thanked John for providing more 10x and 100x examples
> again and moved on. I think it drove him up the wall. He has been
> reminding people of his failure on that example for months now,
> and that is nice too.

I have no idea what you're talking about. You asked for the size of a
"Hello World" program in C for an embedded system. You didn't constrain
it in any way, so I picked a processor, picked a compiler, and generated
code.

I never made a claim it was more efficient than Forth, although again,
if you're going to follow your own rules, you can't just count the size
of the code needed to write the string. You have to include the size of
the code for the Forth kernel as well, since that is your OS.

> He didn't consider his comparing OS to no OS apples vs
> organges

You didn't constrain your request. You asked for a "Hello World" for an
embedded system. That's exactly what I provided. How is your ambiguity
and vagueness my problem?

> but he did consider my comparing my no-OS
> example to his no-OS example to be an apples vs
> organges comparison.

You provided no example. Unlike me, you provided a claim and didn't
back it up with any code. I'm still waiting. Show your code and cite
the processor you're targeting. How difficult can that be?

> Of course in one of his bare-metal
> stripped-down mininal no-OS "hello world" message to
> a port program examples was still bigger than mine with
> the OS and GUI had been. That was really funny. ;-)

No, it's mostly architecture. The HC08 microcontroller I targeted is a
standard accumulator-based CPU, with all the inherent inefficiencies for
such designs. Also included was some unnecessary processor
configuration that is commonly done and RAM initialization that is
standard. Trimming that out gives a size of 58 bytes.

We're all still waiting to see the source code for your magical OS and
GUI in less than the 192 bytes I quoted. But as is always the case with
you, you'll never post it. You love to make claims and then never
substantiate them.

> But when he gets angry and calls for another example of how
> he can always write 10x or 100x more code than a Forth programmer
> to solve a problem it is education for the people who do learn from
> all his examples of C posted to this group of how C can't compete
> with Forth.

I never made a claim that C could compete with Forth in terms of size.
That is an argument of your own invention used as a diversion away from
your idiotic arguments in this thread. When you're losing an argument,
you often shift it somewhere else in a frantic attempt to win.

Why did I post a claim about the size of C code? BECAUSE YOU ASKED FOR
IT. I love the games you play. You first make a request (or more
often, a ridiculously false statement). I then post code and statistics
to answer or refute in response. Then, you get your undies in a bunch
because someone dares show how wrong you are.

> Of course it is probably unfair to C for of any of us to use John's
> C code as a fair test for any comparisons. Can't most newbies
> write a 'mininal stripped-down bare-metal "hello world" message
> directly to a port program, with no visible OS or video output' (as
> he put it) in under 100 bytes?

In C? The answer depends on the platform, but in general, no. At least
not given your standard that you must count all of the supporting code
as the total size. That includes (as my example did) processor
initialization, system startup, and the actual code that does the
printing itself.

> Even if you start a thread, let John post many posts for every
> one that you post. He will just say dumber and dumber things
> if you don't argue with him. Give him a chance to call other
> people who use Forth names.

I don't call people names without good reason, and I certainly don't
call them names because they use Forth.

Ultimately, people who read these discussions are free to judge for
themselves on who is being dumb. Google's newsgroup cache is a
wonderful historical record of it all. I have nothing to fear from such
an evaluation.

sam....@gmail.com

unread,
May 31, 2006, 3:52:51 PM5/31/06
to
rickman wrote:
> I think timers are not always the best solution...

For deadlock conditions, external hardware timers are absolutely the
best possible solution, since they're the ONLY solution that works.

The idea is this: in any normally functioning software, you
periodically "ping" the hardware timer, which causes it to reset.
Thus, the timer never reaches its threshold, so long as everything is
working good.

: PROGRAM
BEGIN do-some-work ping-timer AGAIN ;

If something goes horribly wrong inside do-some-work, it may never
return. Thus, the timer is never reset.

Once the timer reaches a critical value, it will force the CPU's
"RESET" line to be asserted, thus causing an automatic reboot of the
CPU. Note that this may not necessarily cause other hardware to be
reset!! This gives the software some ability to recover. The CPU
bootstrap can read the watchdog registers to see if it was the cause of
the restart, and if so, try to clean up as much as possible.

> I don't agree that this is bad programming. How else do you wait for
> keyboard input or any other external event?

You set a flag that tells the keyboard interrupt handler, "Hey, I'm
looking for data." You then return to the event loop of the
application (which is also responsible for pinging the watchdog timer).
When said data is acquired, that flag changes to, "Data received."
When the event loop detects this, it can process the data as required.

> I don't understand the error. Why would the port bit always be false?

Because a hardware circuit may be accidentally shorting a line to
ground. Or maybe because a software bug in configuring a chip's
registers results in a condition that cannot ever be detected.

> Is this the wrong bit to check?

That's one possibility.

> Is the hardware stuck or a hardware error?

Another possibility.

> I also don't see how to easily check this with a timer.

You cannot diagnose the *specific* problem with a watchdog. You can
only recover from accidental loops. The watchdog helps to *isolate*
the problem, but it's no soothsayer. Using your own logical
facilities, if the watchdog triggers when you *know* beyond any shadow
of a doubt that it's waiting for hardware to respond, then by
definition, the hardware didn't respond. Why? Look first at the code,
cross-reference with the hardware documentation. Refine. Recode.
Retest.

> I believe the main reason this sort of mistake happens is when
> addresses are calculated as in arrays and the index is not checked
> against the size of the array. But it can also happen when address and
> data are mixed such as incorrect stack handling... but that never
> happens, right?

Can you guarantee that it never happens? Remember that Forth allows
you to stuff data on the return stack. If you fail to balance PUSH and
POP (or >R and R>), you will almost certainly see this happen.

Another cause of this is, oddly, cosmic rays. Yes, cosmic rays. When
one cosmic ray streaks through a RAM bit, it can toggle the state of
that bit (most of those "streaking specks" on NASA photos are caused by
cosmic rays, so if they can flip the state of multiple pixels, it can
certainly do the same for RAM chips), thus leading to errors where code
reads $7FFF one day, and $FFFF another. This, in conjunction with high
RFI, is the reason why more and more high-end computers are being
equipped with ECC-protected memory.

Working in a commercial-grade, Linux dedicated hosting shop, I've seen
plenty of otherwise known-good hardware with uptimes measured in
hundreds and hundreds of days just spontaneously kernel panic for
reasons unknown. I believe that cosmic rays and stray RFI are the
cause for this. PC motherboards simply aren't designed to
mainframe-quality levels.

Mainframes often have ECC-protected memory and multiple redundant
memory paths, combined with multiple redundant CPUs that compute things
in parallel, then use a voting algorithm to select the "most likely
answer." That is, if you have 4 CPUs, and 3 say 2+2=4 and 1 says its
5, then it'll choose 4 as the final answer, then a hardware trap will
cause the faulty CPU to be shut down, and an e-mail sent to the system
administrator. IBM's higher-end mainframes even apparently have
hot-swappable CPUs.

Obviously, this kind of investment would be made unless it was
necessary, and when computers need to have an uptime measured in
decades, it suddently becomes important.

> I can't imagine a stack machine without stack checking for over and
> underflow. I would expect that to be the most common error, but then
> there are other ways to use a stack, right?

Chuck's chips don't have a stack, as such, but an array of
recirculating shift registers. Hence, stack underflow can be used to
write *patterns* into memory (perhaps most useful with spewing out
graphics).

Other architectures may lack detection because, well, because it lacks
hardware for some reason (e.g., cost, chip real-estate). Remember, the
more transistors you put on a chip, the slower it'll necessarily go
because of propegation delays. This is especially true when you're
inserting such logic smack in the middle of the CPU's most critical
data path: address register -> (fault detection logic if it exists) ->
memory -> data bus.

> I don't think you need a timer. What would you be timing??? If both

Regular pings. A heartbeat.

> CPUs go to sleep waiting on one another, it could be normal if they are
> also waiting on other conditions or you can just detect the mutual wait
> in hardware. No need for a timer either way.

Maybe, maybe not. You can't tell this from the problem as stated, as
there hasn't been enough information provided.

rickman

unread,
Jun 1, 2006, 11:44:59 AM6/1/06
to
I am curious, what was your purpose in starting this thread?

Jeff Fox wrote:
> rickman wrote:
> > I think timers are not always the best solution...
>

> If we wanted a timer we could have a timer task or a timer node
> or a timer group, or use a timer circuit, but we would not have
> an interrupt driven timer. Different paradigm.
>
> > Exactly what is the timer going to detect? Running in a loop is normal
> > operation. I would expect software to detect this type of construct
> > and not allow it.
>
> Yes, a normal operation. As are all the others where we are.


>
> > I don't agree that this is bad programming. How else do you wait for
> > keyboard input or any other external event?
>

> My point is that some see it that way. I don't.
>
> I say it's Forth. He says it's a bug.
> I say it's good. He says it's bad.
>
> My point is that we seem to be using different definitions and terms.
>
> What we were refering to as 'good software' he calls bad programming.
>
> It makes you wonder sometimes who does and who doesn't understand
> what you write or say.
>
> On a port handshake lockup,


>
> > I don't think you need a timer. What would you be timing??? If both

> > CPUs go to sleep waiting on one another, it could be normal if they are
> > also waiting on other conditions or you can just detect the mutual wait
> > in hardware. No need for a timer either way.
>

> As you say, a timer on the circuit itself would be one option. If it
> was
> an error there might be several ways of handling it without a timer. Or
> sometimes it might not be an error or problem at all.

0 new messages