views:

59

answers:

4

Please post the points one should keep in mind while designing or coding for lesser footprint deliverables for embedded systems.

I am not giving compiler or platform details, as I want generic information. But, any specific information on Linux based OS is also welcome.

+2  A: 

Depends on how low you want to get. I'm currently coding for fiscal printers, and there's no OS, and the main rule is no dynamic memory allocation. The funny thing is that I still convinced the crew to code fully modern C++ ;).

Actually there are a few rules we decided upon:

  • no dynamic allocation
  • hence, no STL
  • no exception handling (obvious reasons)
Kornel Kisielewicz
Every time I sit down to write some embedded code, and I try to write it in C, I wind up switching to C++. All I really use are classes for encapsulation, and templates. Inheritance is rare, and there's hardly any `virtual` stuff; usually, it's just the occasional mix-in, like a class that tracks its members with a built-in doubly-linked list. Templates are great for writing containers, even though the containers I'm writing are pathetic (i.e. unprovable for degenerate cases) by ivory-tower CS standards. Just make the maximum number of elements a template parameter.
Mike DeSimone
@Mike, Heretic.
Aiden Bell
@Aiden: Darn straight. I don't let stereotypical C++ coders' incompetence drag me down. That said, there's a lot of stuff in C99 which is very useful for embedded work and hasn't made it into C++ yet (I'm not counting C++0x because it's not even done.), so it's a tougher choice now. But I'm much happier with templates than I am with `#define`/`#include` patterns for making C containers, and writing lots of functions that look like `ClassName_MethodName(const ClassName *this, ...);` is tedious, error-prone, and creates a lot of clutter, making things harder to debug.
Mike DeSimone
Also, using RAII to manage locks in code that runs in a real-time OS is just too darn useful, and prevents a lot of bugs while making the code cleaner.
Mike DeSimone
why no exceptions (reasons not obvious)
pm100
Exceptions can add a lot of hidden baggage. There's a lot of extra info that has to be stacked so an exception can unwind things correctly. This makes functions less likely to optimize well. You can try to use them, but I wouldn't recommend it unless you have a good knowledge of how your compiler implements them at the low level, so you can minimize or eliminate their impact. For a general idea of what is involved, you might want to look at a C library that implements exception-like behavior using `setjmp()` and `longjmp()`. (The library name escapes me.)
Mike DeSimone
Another C++ feature that can add a lot of hidden baggage, and isn't that useful in embedded work, is RTTI.
Mike DeSimone
+1  A: 

There isn't a general answer, only ones specific to language/platform ... but

Small memory footprint ...

  1. Don't use Java, C#/mono, PHP, Perl, Python or anything with garbage collection
  2. Get as close to the metal as feasible, Use C
  3. Do alot of profiling to see where memory is getting allocated, if you are using dynamic allocation
  4. Ensure you prevent heap-fragmentation by allocating sensible chunks and sizes of the heap
  5. Avoid recursive functions especially those that use malloc(). Better allocating a chunk and passing a pointer around.
  6. use free() ;)
  7. Ensure your types are no bigger than required
  8. Turn on compiler optimizations

There will be more.

Aiden Bell
C++ can get as close to the metal as C, for obvious reasons. Moreover, dynamic memory allocation may not be possible, depending on the environment.
David Thornley
@David, yea but we all know C is superior in its grace.
Aiden Bell
"Common knowledge" is a sacred cow that needs to be shot on sight (like the Buddha at the side of the road). C has its advantages, but it shouldn't get a free pass. It should have to prove its worth like any other language.
Mike DeSimone
+1  A: 

for real low footprint consider doing Assembly directly.

We all know that Hello World in C or C++ is 20kb+(because of all the default libraries which get linked). In Assembly this overhead is gone. As pointed out in the comments one can reduce the standard libraries quite a bit. However, the fact remains that the code density you can get when coding assembly is much higher than a compiler will generate from a higher language. So for code where every byte matters, use assembly.

also when programming on devices with less capable processors, programming in assembly language might be your only way to do make the program fast enough for it to be realtime enough to (for instance) control machines

Toad
before everyone starts downvoting. Arm assembly is very easy to learn, and is much cleaner than X86 (which is a nightmare to program in). A lot of embedded systems (phones/handhelds/etc) use arm nowadays. There's also a lot of good resources to be found on the web.
Toad
Except that you wouldn't be doing Hello, World on an embedded device; you'd be using either memory-mapped I/O or whatever interface libraries exist (possibly written in assembler. (I'd assume the device would be what the C standard calls "free-standing" rather than "hosted".) There would be no library bloat.
David Thornley
+1 for pre-emptive discouragement of downvoting, and that you are right, assembly needn't be grim.
Aiden Bell
@david: you are assuming much from the compiler, which is not a given by the person who is asking the question. In any case, any assembly program can and will be much smaller than anything a compiler can produce
Toad
@aiden: in this crowd of mostly web-developers armed with their code-pattern books, any mention of assembler is an automatic rain of downvotes. Well, I'm prepared for it and I stand by my answer since I've done my share of assembly programming (and C and C++) so I'm confident of the validity of my answer
Toad
@reinier - I know the feeling. My fav language is C, then Python if we are getting scripty. I like pure, well thought out stuff (Like C, and Python's object model) ... all this other shit makes me cringe.
Aiden Bell
I think this needs to be pretty far down the list, right before the arcane chants and chicken bones. C is effectively portable assembler already. There should be compiler flags (like `-nostdinc`? `-mno-soft-float`?) for dropping the default libraries. Also, dropping `<stdio.h>` should save you a bunch; all the `FILE*` support eats 18k or so on an 8-bit AVR core, for example. Most folks can get by with low-level I/O (`<unistd.h>`, IIRC).
Mike DeSimone
@renier: While I'm not against assembler programming (although I intend to avoid x86), and it does have its place in embedded, your reason for avoiding C or C++ is fallacious. You say it gets big because of the default libraries, but this is exactly what doesn't happen in a free-standing environment. I would not have downvoted your first sentence, but the comparison of free-standing assembly with hosted C deserves the downvote.
David Thornley
I find assembly to be tedious, verbose, and really, really good at hiding bugs. Also, while a macro assembler lets you write macros to take care of a lot of this, there is no standard macro library, so every programmer writes their own and it is very hard for another developer to take over. I fully support using it on occasion, and have done so. But I wouldn't recommend using it for all the code unless the program is really small, say, 16K at most.
Mike DeSimone
@david: I'm just saying that because of this you already start with a disadvantage. But even if you could skip these libraries and get it to zero baggage. Compiled code is always a factor 1.5 or more bigger than direct assembly. It has to do with compilers adding (often) unnecessary register saves on the stack and because it emits standard code patterns for every language construct without seeing the grand picture and being able to shorten it. Last but not least, I've yet to see a compiler do optimal fixedpoint math, something assembly can do fine.
Toad
@david, @mike: changed the answer slightly to accommodate your comments
Toad
A: 

When faced with such constraints, it is advisable to pre-allocate memory in order to guarantee that the system will work under load. A design pattern such as "object pooling" can be used to share resources within the system.

The C language enables tight resource (i.e. memory & compute cycles) control. It should be strongly considered.

Avoid recursion as it is easy to abuse and can result in stack overflow conditions.

jldupont