Languages for embedded

I'm new to coding embedded software. It's been something of a baptism of fire; I was handed a nice quad-TigerSHARC board and asked to make it work in an environment it was never designed for (it was meant to be inside a PC - instead I've created an environment for it electrically identical to the one it would see inside the PC, but inside something else entirely) and it's actually starting to do stuff.

My coding experience is mostly C++; I'm using VDSP++ ver 4.0 (the version supported by the board manufacturer's libraries) and my code is essentially C++ with a careful lack of classes and templates such that it will compile as C, if you see what I mean. I've no doubt a hardened C coder would want to change a lot of my code, much as I find my keyboard fingers twitching when reading their code.

There are some old-school embedded coders at my workplace who mumble about how C++ is not really a real-time language and that C is better for such applications. I can certainly understand not using something with automatic garbage collection (you never know for sure when everything will pause for the memory to be cleaned up, as I understand it), but why avoid C++? Is there something about the classes and templates that makes it unsuitable for embedded software? What affects the decision to use a given language for embedded coding? I'd be grateful to hear about reasons for/against other languages besides C and C++.

While I'm here, is there any embedded lisp out there? I'm a secret lisper.

'Chops

Reply to
moschops
Loading thread data ...

Don't know, but if there is embedded Prolog I'd be delighted to see it. Of course, both Lisp and Prolog require a garbage collector.

My personal opinion is that C endures because it's so close to assembly language, but C++ is the worst-designed of the available object-oriented languages, so it is dying out everywhere, not just in embedded systems. Java and C# do the same job a lot more elegantly. There's plenty of embedded Java (no C# as far as I know).

Reply to
mc

... snip ...

First, realize that C++ (and vendor specific languages, such as C# and Java) cannot do anything that C can't do, although it may require some more programming, or libraries. After that, realize that a C implementation (of some sort) is available for almost everything, but the other languages are generally implemented.

--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

C++ can be a fine language to use for embedded systems as long as you use it right. Mostly this means being excruciatingly aware of what features of the language have what footprints, and coding accordingly.

Most of the embedded C++ work that I do uses a pretty wide swath of C++ _except_ that the C++ standard library I/O code gets avoided like the plague, as well as "catch" and "throw". Templates can either be an opportunity to manage code bloat or to cause runaway code bloat, so they must be used with discretion. Virtual functions will add the storage space for a pointer to each object of a class that uses them, and will add some function call overhead for virtuals, so they must also be used with discretion. Polymorphism, better type checking, inheritance and all of that don't cause much run-time or memory overhead unless you include that innocent-looking class that just happens to have half a megabyte of code behind it (hence the avoidance of the standard library I/O...).

--
Tim Wescott
Control systems and communications consulting
http://www.wescottdesign.com

Need to learn how to apply control theory in your embedded system?
"Applied Control Theory for Embedded Systems" by Tim Wescott
Elsevier/Newnes, http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

On Sun, 21 Oct 2007 20:53:13 +0100, moschops wrote in comp.arch.embedded:

Your secret is safe with me.

As for the C versus C++ debate, there are quite a few issues here.

Perhaps the biggest downside to C++, in the context of embedded systems, particularly smaller, resource constrained embedded systems, is that it has features that provide a much higher level of abstraction. That can mean you can inadvertently add a lot of overhead to your code.

If, inside a function, I define:

struct xyz my_xyz;

...in C, I know that a sufficient size area of memory is allocated in automatic object space (usually the hardware stack) with generally zero overhead, as the function entry prolog just adds the number of bytes in the structure to the value it uses to adjust the stack pointer which it is doing anyway.

In C++, on the other hand, even a lowly structure can have a constructor, and the definition of an instance of the structure xyz might call a construction that does any amount of work, including calling constructors of the structure's members.

If I want to know whether xyz had a constructor, and how much work it might be doing just because I want to instantiate a local object, I need to dig into its header and perhaps source code. If an object has a constructor, there is absolutely no way that I can create one without it being executed.

On the other hand, if I have a C struct xyz, and the API provides a call to initialize it such as:

SUCCESS_CODE initialize_xyz(struct xyz *xyz_ptr);

...then I have to explicitly write that code to call that function if I need that initialization, and I can skip that call if I don't need the standard or default initialization. At the very least, I can't code this function call and not realize that it has some overhead, although again I have to look at the function's source to see how much.

The other area of confusion in C++ does not merely apply to embedded systems, but it is the ease of confusing reference versus value arguments to functions.

If function f() takes an int by value, it can't modify any int value in my calling function. If f() takes an int by reference, it can modify that value, and either way my code looks the same:

void myfunc(void) { int x = get_value(); f(x); }

If f() has side effects that are the main reason for calling it, one might forget that it also modifies the value passed to it by reference.

You can't make that mistake when passing a pointer:

void myfunc(void) { int x = getvalue(); f(&x); }

The & is a dead give away. The compiler will not accept the code if I leave it out, so I must know it is there. If I need to have the value returned by getvalue() intact after calling f(), I will refer to its documentation to see if it truly modifies the value. And if so, I can change the code to:

int x = getvalue(); int y = x; f(&y);

...and know that x will still will still have its value after f() returns.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Reply to
Jack Klein

C is the worst designed prodcdural language, C++ only inherits its deffects from C. OTOH, C# and Java use pretty complex garbage collectors, not every embedded system has the capacity required for them.

C is pretty good for embedded system, C++ is much better in the reduced style mainly used in embeded systems: no RTTI, no exceptions.

And I know, I write embedded syetms and embedded OS's in C++ because they are easier to maintain and debug than C counterparts, and both have comparably small memory footprints.

Regards,

Zara

Reply to
Zara

There's Embedded Common Lisp.

formatting link

Writing DSLs in Common Lisp is quite popular since the macro facility of Common Lisp is so powerful. Naughty Dog Software wrote a DSL called GOAL (Game Oriented Assembly Lisp), which was used to generate efficient code for the MIPS processor in the Playstation. Naughty Dog Software wrote the games Crash Bandicoot and Jak and Daxter.

Petter

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Reply to
Petter Gustad

That's the key - embedded software in any language has to be aware or implementation structure. In C it's pretty easy, the basic runtime support consists of a stack, and the libraries are (or were) pretty straightforward. In C++, any operator can invoke arbitrary code, runtime support includes implicit deallocation and stack crawls and rewinding. For a few years every minor release of some compilers required a different library.

But you could take a look at "Embedded C++".

A good general rule is that you have to be prepared to write the runtime yourself. You know, LISP doesn't look so bad...

I suppose there are embedded systems that just consist of a PC in a different box, such as the ATMs that display Windows BSODs.

--
	mac the naïf
Reply to
Alex Colvin

[snip list of evil vendor-specific languages ...]

Can't ... resist ... flame ... bait ... :-)

Can C do templates/generics? Well ... I suppose you *could* re-write the same code with different types every time you needed to use the same algorithm.

In a similar way, you can also code your own polymorphisms in C using structures and function pointers. Certainly, the Linux kernel does.

I'm working on a gadget I call a wheel ;-)

Sorry ... I'm incurable :-)

--
Michael N. Moran           (h) 770 516 7918
5009 Old Field Ct.         (c) 678 521 5460
Kennesaw, GA, USA 30144    http://mnmoran.org

"So often times it happens, that we live our lives in chains
  and we never even know we have the key."
"Already Gone" by Jack Tempchin (recorded by The Eagles)

The Beatles were wrong: 1 & 1 & 1 is 1
Reply to
Michael N. Moran

It is possible to (ab)use the preprocessor to implement templates.

--

John Devereux
Reply to
John Devereux

I suppose, though I'm not sure how much type-safety you get using that method. Since you mentioned "abuse", I won't go off on a tirade about the evils of our beloved C preprocessor. :-)

--
Michael N. Moran           (h) 770 516 7918
5009 Old Field Ct.         (c) 678 521 5460
Kennesaw, GA, USA 30144    http://mnmoran.org

"So often times it happens, that we live our lives in chains
  and we never even know we have the key."
"Already Gone" by Jack Tempchin (recorded by The Eagles)

The Beatles were wrong: 1 & 1 & 1 is 1
Reply to
Michael N. Moran

No particular reason for embedded systems, same as for any system. It's not a well designed language.

Availability of compilers / development environments Complexity of problem Competence of available staff Code reuse

Ada is an excellent language for embedded work. It is tightly specified so that compilers from different vendors normally can compile code without too many problems. It has all modern constructs built in (and as stated, tightly specified) like classes, interfaces, generics, tasks, protected objects and so on.

One of the more cool features for embedded is the language built in representation clauses that give you the possibility to map variables to memory locations and structures to device-registers. And that is NOT with a vendor specific language addition. It's native Ada.

Another option is to look at model driven development, for instance using xtUML. That solution will give you portability like never before as your models shall be platform independent (without knowledge of hardware, programming language and so on). After doing your model homework you run your models through a model compiler crafted for your platform that will turn them into code in a language of your choice. If you want lisp i'm sure it could do it. Then you compile that code WITHOUT MANUAL MODIFICATION to run on your platform. For all those who still don't believe it works I can only say that it runs in aircrafts, cars, missiles and pacemakers all over the planet. Solution gets too slow, fiddle with the MC to do VHDL instead of lisp (Go ask mentor about bridgepoint or KennedyCarter about iUML)

/Leif

Reply to
Leif Holmgren

Sure it can. The first C++ compilers were in fact preprocessors that compiled down to C, so it must be possible. Do a search for 'cfront' for more info. Don't confuse 'is expressed convieniently' with 'is possible'.

--
Andrew Smallshaw
andrews@sdf.lonestar.org
Reply to
Andrew Smallshaw

While the output of the cfront compiler was intermediate "C", that doesn't mean that the templates are implemented in "C." Obviously, when the compiler (cfront) is ready to generate code for a particular template instantiation, the resulting code is expressed as "C". However, the real work of compiling templates is done by the cfront compiler itself.

--
Michael N. Moran           (h) 770 516 7918
5009 Old Field Ct.         (c) 678 521 5460
Kennesaw, GA, USA 30144    http://mnmoran.org

"So often times it happens, that we live our lives in chains
  and we never even know we have the key."
"Already Gone" by Jack Tempchin (recorded by The Eagles)

The Beatles were wrong: 1 & 1 & 1 is 1
Reply to
Michael N. Moran

I forgot to mention Movitz for x86 based system. I have Movitz running on one of my my Mini-ITX machines.

Petter

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Reply to
Petter Gustad

There is no shortage of the embedded developers; there is a shortage of the cheap embedded developers who nevertheless can do the job somehow.

Besides, the 90% of work doesn't have to be done perfect; it just has to be done.

Thus the main purpose of the embedded programming language is accommodating the development work so the wide crowds of peasants and proletarians can do it.

The dropping price of silicon made reasonable the memory footprint at the order of several hundred kilobytes; the speed/size efficiency doesn't really matter till it fits in the CPU of < $10 class.

Now look at the embedded C# dot Net. The MS definitely knows what they are doing.

Vladimir Vassilevsky DSP and Mixed Signal Design Consultant

formatting link

Reply to
Vladimir Vassilevsky

In small systems, the availability of memory is always an issue.

For this reason, using dynamically allocated memory (malloc/free style) is always a risk, especially due to the dynamic memory fragmentation issue.

If a language uses dynamic memory behind the programmer, how should the programmer be able to create usable and _reliable_ systems ?

Paul

Reply to
Paul Keinanen

Actually according to several surveys I've seen over the last few years, Java is not making much of a dent in the embedded world. C is still the primary language used for embedded systems (right, wrong or indifferent). Java is used less than C++. Most embedded folks probably don't feel comfortable with the whole VM thing.

Reply to
Marco

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.