which object orient language is most suitable for embedded programming?

Sheesh, did, I really write that rant, that episode must have played on my mind more than I thought....

Reply to
Paul Taylor
Loading thread data ...

Well, perhaps, but do I really need the system to allocate anything at run time if it can just as easily be done at compile time ?. It just adds complexity for no additional value and stuff `under the hood' which a) I may have no control over and b) is probably not visible in terms of its operation.

Such views are probably not fashionable, but OO seems to have so much associated hype and scope for intellectual self abuse, you have to question everything. This begs the next question, why do we bother with OO based design at all ?.

Chris

Reply to
Chris Quayle

As I've said elsewhere, the basic ideas are a useful addition to the toolkit for producing modular, maintainable, readable code.

But the baggage it brings with it is not. (See elsewhere re hook/line/sinker ;).) Taken as a complete package, it's a retrograde step.

Steve

formatting link

Reply to
Steve at fivetrees

My one-phrase definition of OO would be: OO is abstract data types with inheritance.

Both can be coded in C and assembler, but not necessarily prettily. There's an awful lot of code, particularly in the embedded space, that is essentially procedural and algorithmic, and doesn't get a lot of milage from OO techniques, which (along with modular programming) are largely ways to mitigate the complexity of programming in the large. The interesting middle ground (where this discussion is probably coming from) is the increasing number of embedded systems with enough grunt to be able support languages that use at least the basic higher order abstract types: strings, arrays and collections of various sorts, to simplify the code, even if they don't necessarily need to do much object design or encapsulation themselves.

My still-favourite discussion of Object Oriented design and programming is Bertrand Meyer's "Object Oriented Software Construction", now (or nearly) at it's third revision. That uses Eiffel as the language of demonstration. As far as I know, Eiffel is still the only language that deals systematically with the curly edge-cases (name clashes etc) of multiple inheritance (it has keywords that allow disambiguation by re-naming parent methods, for example). Eiffel itself is a very nice language, and does get some use in larger embedded systems (on the scale of laser printers and up), although its reliance on garbage collection keeps it out of the really small ones for now.

Ada still gets some milage as a heavy-duty OO+modular embedded systems language, but it's syntax is a bit different from the norm.

Modula3 has Java's single-inheritance bottleneck, but is otherwise nice. It suffers mostly from a paucity of implementations (and by being overtaken by Java).

Fortran has objects, now, but I doubt that it's getting much use in embedded work.

I think that there are OO frameworks available for forth, too...

Any embedded system large enough to need an interpreted control or configuration language will find that several of the contenders for that spot are object-oriented, these days: lua, scheme, tcl, python...

Cheers,

--
Andrew
Reply to
Andrew Reilly

I agree, and always allocate statically at the top level when I can. However, there are situations where allocation a la "new" can be a helpful simplification.

The only down side is that you need to add error checking code (in case the new fails) and/or you may not be certain at link time that you have sufficient RAM.

I assume that your worried about hidden complexity rather than added complexity to your application. It's a valid concern, but once its working I've never encountered any issues with that part of the run-time.

It took me quite a bit of effort to get the hang of OO, but once it clicked, I have never wanted to go back. Perhaps the largest barrier to my understanding was not knowing what OO was for. Once I understood that its primary strength is as a tool for code reuse by its decoupling facilities, the pieces fell together nicely.

Robert C. Martin's "Principle" papers are invaluable for those seeking the details. These can be found at

formatting link
Some of the titles include:

o "The Open Closed Principle" o "The Dependency Inversion Principle" o "The Interface Segregation Principle" o "The Liskov Substitution Principle"

and others. Highly recommended.

--
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."
The Eagles, "Already Gone"

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

A typical situation in which you would use dynamic allocations during startup but no more allocations at run time, is when you have a single program that must be installed into wildly different environments, but the environment does not vary much during actual execution.

A single binary can be distributed to all sites and the allocations are done at each site for that particular environment. If the allocations fail during initialisation, it would be immediately obvious to the person installing the system and the parameters could be changed or more hardware installed. By avoiding dynamic allocations during actual execution will also eliminate the _possibility_ for obscure errors due to dynamic memory fragmentation perhaps a few months or few years after startup.

Sure, this could be done by changing compile constants, but this would require compiling a new version for each site. This would be a logistics nightmare.

Paul

Reply to
Paul Keinanen

Scuse the top post, but

formatting link
pretty much sums up the lot.

Reply to
The Real Andy

But vtables are used with single inheritance as well.

How does your manual approach protect against adding another method to your super class that you forgot to define in the sub class?

--
Paul
Reply to
Paul Black

Allocating memory at startup like this is fair enough, but I'd still be inclined to use specifically written code to deal with it, rather than malloc. Of course, it depends on the size of the program and the complexity - if you only have a few different types of data to allocate, then specific routines are appropriate, but if you have lots, then a general purpose routine is more sensible. You at least avoid the three problems with dynamic allocation - fragmentation (no freeing means no fragmentation), unpredictable run time (your startup is normally deterministic), and unpredictable failures (either you've got enough memory at startup, or you haven't).

Reply to
David Brown

It's not excused, nor is it excusable.

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

That's possible, and provides better data hiding, but will cost you in run-time size and speed (unless you're program-at-once optimisations are spectacular). On a small micro, turning the index into an address for the struct is far from insignificant, especially if you don't have a fast multiplier, and it adds to the function call overhead you need for every single access. Using a header-defined struct along with static inline access functions will boil down to normal direct global memory read/writes for simple variable member access, while your hiding system would mean the same access would involve function calls, address calculations, and indirect accesses. Even with C++, you have to try hard to get that sort of overhead.

The idea of hiding internal data is good, of course - but it's not worth that price. C (and C++) are poor languages for proper data abstraction (off-hand, I can't think of any languages that can give you proper hiding of internal data without any overhead).

I mean you have to have functions called "file_open" and "uart_open" instead of "file.open" and "uart.open", since you don't have any sort of scoping for global names.

Reply to
David Brown

There are a number of reasons why C++ is so bad (although it can still be a useful language, and is still the best choice for some types of code). It makes a few too many compromises to squeeze OO into C, with the result that some of the syntax is astoundingly horrible. Some template-heavy code is more reminiscent of APL than any legible language. Add multiple inheritance (a "feature" that very few OO experts would recommend), inconsistent overloading, "friends", mixtures of implementation and interface in the headers, and all of C's problems, and you have a language which makes it easy to produce unmaintainable disasters. This is made worse by most "teach yourself c++" books and courses being terrible (they are mostly backwards, trying to get you to write C code first and tag OO classes on afterwards). Well-written C++ code can be very good, but badly written C++ code (the majority, as far as I can see) is far worse than badly written C code.

Reply to
David Brown

What's wrong with writing your own startups? I do that regularly, in C projects. It's a matter of getting the code you want for your application, right from the start - I have different requirements at different times, depending on whether code is running from flash, or from ram, or some mixture. I write my startups in C - there is no assembly after setting up the stack pointer and jumping to the C code. Even the zeroing of the BSS is done in C.

They pay money to get code working on the target - startup routines and linker scripts are often part of that.

I don't know what compiler and target you are using, but I've not seen anything like that myself. I would think that at most, such code is using pre-processor defines, so that only the required code is actually compiled.

Then use your compiler switches to add the support later. If your compiler doesn't let you choose the features that easily, switch compiler.

You might find pointers in ram for some particular targets that have non-uniform memory (perhaps for an AVR, for example). But in general, vtables will be in rom.

Reply to
David Brown

... snip ...

You can do much better if you ban recursive calls to main. Then the initial call in main can be to an init operation, and from then on the code loaded is dependant on what is actually needed, assuming fine modularization of the run time library.

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

... snip ...

I found no sign of those at that URL.

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

The OO systems view is not the problem - have been applying it to designs since the early 90's. One book that helped get me started on OO was "Data Structures, An Advanced Approach Using C", by Jeffrey Esakov & Tom Weiss. My copy is dated 1989. ABE books probably have it. There were quite a few others, but I think that was probably the most significant in terms of change in thinking. Looking qat it now, it all seems so obvious, but had quite a profound effect at the time.

What would be ideal would be a slightly enhanced C, with more formalised support and syntax for typedef struct enum etc. ie: the typedef really does create a new abstract type. The existing typedef, function pointer and module scope stuff can provide enough abstraction and data hiding capability, but it can be hard work. It takes quite a bit more time and effort to program C in an OO way. Still, I keep coming back to C++, as there is a need and I really have tried to like it. Every time I take a fresh look though, it still isn't a good fit for small to medium sized embedded projects. To cover the range of embedded work, the ideal C++ compiler would be built up from a basic core, with plugins for the more complex features. For example, the basic core might have C with classes, then plugins add stuff like constructors, destructors etc. Each plugin adds a bit of syntax, but the the basic core is stripped down to the bare minimum, so it's usable in, for example, 8051 class systems..

There's still quite a bit of resistance towards OO in the industry, especially in the smaller companies who always seem to be under pressure in terms of timescales and budget. Many programmers still view OO design as being overcomplicated and it can be difficult to convince management of the benefits in terms of readability, maintenance, reuse etc. Some programmers blindly view such design as 'cryptic and over complicated' which doesn't help. Typical comments being: "excessive use of pointers" :-)...

Chris

Reply to
ChrisQuayle

The unspeakable chasing the inedible perhaps :-).. Anyway, the Wiki link sums it up quite well IMHO...

Chris

Reply to
ChrisQuayle

Ban recursive calls to main? Does that imply that people sometimes write code that *does* recursively call main ?!?

There are some things that may need to be done before main - on larger systems, you might have to set up chip selects or initialise SDRAM before anything else. These sorts of tasks can be handled by a boot loader of some sort, but can just as well be done by some pre-main C code that sets up memory, and perhaps copies the software from slow flash into fast sdram, initialises .bss and .data, and any other very low-level hardware. Then comes main(), and a series of initXXX() calls to bring up the rest of the system.

Reply to
David Brown

Object-Mentor's web-site has changed since the last time I was there. They seem to use quite a bit of java scripting that doesn't work on my ancient Mozilla browser. However, Google found the PDFs searching by name.

For your convenience:

formatting link
formatting link
formatting link
formatting link

--
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."
The Eagles, "Already Gone"

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

Slightly OT, but familiarity with "placement new" is often overlooked and essential in embedded system work. It allows full control over many aspects of object lifetime.

--
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."
The Eagles, "Already Gone"

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

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.