emBuild.org -- Embedded Software Design Resources
(This site no longer maintained). Last Updated: October 23, 2011
This site is presented by Ted Merrill (emBuildSw.com)
in the hope that it will be useful to someone. You'll find a lot
of opinions here, and i hope also you'll find some logic behind the
opinions.
See emBuildSw.org for free software
goodies from Ted Merrill including the embuild-atool
software development suite.
Linux Home Office
I use Linux exclusively for software development... here are some tips.
Embedded Software Mid-Scale
There is i suppose quite a bit of on-going development for 4 bit and 8
bit processors
with a few kbytes of memory, while on the other extreme are highly
networked 64-bit processors running Linux and making extensive use of
memory shared with other processors of various flavors. My
experience is with the mid-range of this spectrum instead of either of
those extremes, so that's what i'll
talk about.
Operating Systems
custom
Every software project winds up developing their own operating system,
even if it is only a modification and configuration of something from
someone else. Here is my rant on the subject: Why you
should design your own operating
system .
ecos
The most developed small, free, realtime type operating system is the
eCos
operating
system. It appears to be the most serious freely available
operating system for systems smaller than Linux (but large enough to
need an operating system). A great deal of effort has
been put into marking up the C source code for eCos with lots and lots
of conditional compilation directives (#if's) so that you can compile
in just the features that you need and get the smallest code possible
with reasonable effort while retaining compatibility with future
upgrades to eCos. They even have a GUI for navigating all these
configuration choices, including all of the interdependencies, which
works reasonably well. Various applications such as Berkeley
IP/TCP
stack etc. have been ported to eCos; however, the range of available
drivers is somewhat slim, which likely implies that eCos has not
captured a large market share (or else everyone is hiding their
drivers). One omission that caught
my eye
is that their mutexes (mutual exclusion resource protection primitive
operations), while supporting priority inversion safety, do not support
recursive acquistion by the same thread... you had better know what
your code is doing! They have a simulation environment where you
compile your code to run natively on a linux PC but under ecos which
runs in a semi-virtual machine implemented using e.g linux signals in
place of interrupts (uses only a single linux thread to implement the
multiple ecos threads). The simulation environment includes
support for a gui to simulate e.g. buttons and display screens, and
connection with a real ethernet port (via linux raw sockets); all of
which works pretty well and is quite useful for everything short of
counting cpu cycles. My impression of ecos was soured however when
sprintf took an exception... after stepping through the code i saw that
sprintf was built on top of their file system code and it spent
probably hundreds of instructions locking the "file" before even
attempting to do any work! In general, their code (written mostly in
C++) appears to suffer from some degree of over-generalization... very
intelligently written code, but efficiency sometimes gets overlooked. I
would question whether ecos is appropriate for a system that had a high
rate of context switches. Ecos has a paucity of embedded routines
to e.g. print the state of the system; there is no debugging shell,
although oddly their httpd package comes with some web pages of useful
system status display.
eCos has, since 2002, been distributed under a modified form of the GPL
that excludes the extension of the license to other code linked with
eCos code. eCos was actively developed by Cygnus and then Red Hat
until recently
when Red Hat pulled out of the embedded software market. Red Hat
has now announced that they are transferring ownership of the
copyrights to the Free Software Foundation while the active development
nucleus appears to have shifted to eCosCentric (www.ecoscentric.com), a
private company that claims to employ many of the original
developers. eCosCentric makes money on support, of which the most
profitable part is probably writing drivers for new hardware when
someone pays them to. The new drivers become publicly
available to everyone else thereafter for free, which increases the
general value of eCos and thus presumeably leads to new work as new
hardware enters the market; this is of benefit to those who paid for
parts of the development as well. The Red Hat page for eCos (sources.redhat.com/ecos
a.k.a. ecos.sourceware.org
)
is still alive at this writing and is a place for downloading the
software, although I would check ecoscentric first. A useful
reference and introduction is the book
Embedded Software Development with eCos by Anthony J. Massa, ISBN
0-13-035473-2 published by Prentice Hall; it is a handy reference, but
does not go beyond the obvious.
linux
The Linux operating system has become quite popular for embedded system
use due to it's excellent networking support and broad coverage of
drivers, among other reasons. Linux systems have been pared down
and compressed enough to fit (with compression) onto a 2.88 MB floppy
disk, although a more comfortable basic platform would be perhaps 4MB
of flash and 16 MB of DRAM. There has been for a few years a
major fork of Linux, with non-MMU systems experiencing somewhat more
limited support with a modified, trimmed down older version (see www.uclinux.org ) while
systems with a memory management system can use the latest and
greatest. Linux 2.6 is said (see for example linuxdevices.com/articles/AT7751365763.html
) to bring these forks together, as well as add better real time
performance.
There have been some distinct problems with realtime performance on
Linux that may take some years to be fully addressed. As a
personal example, in work I have recently done on the freely available
source code of the Elphel networked camera (see www.elphel.com ) I found that
it's low-powered processor was easily saturated when handling the Linux
TCP stack with a 100 Mbit/sec ethernet connection. This would not
have been so bad, but the non-preemptible nature of Linux 2.4 resulted
in, for example, a write of 4 MB to a TCP socket excluding all other
user-level processes for the time it took to complete -- about one
second. The solution in this case was to break the write call up
into a series of smaller ones, with some loss of performance.
This type of problem has been worked around by others by placing their
realtime code in drivers, or more effectively and radically, by running
Linux as a task under a realtime operating system (see for example www.fsmlabs.com), and by
various modifications to portions of the Linux kernel and drivers (many
of which are said to have made it into Linux 2.6). Thus, while
Linux has been successfully used on a wide variety of devices (linuxdevices.com is a good
starting point) some care should be taken in ensuring that it will be
compatible with the essential system requirements of your
project. Also, based upon my prior experience, I can say that it
is not easy to port Linux to a new bus architecture. The Linux
code dealing with bus architectures tends to be highly oriented towards
specific computer products, so even though some of these products may
use the same bus interface chips as your device, the code will be of
little help to you. To a lesser extent, this problem applies to
some drivers. If you are designing a new product that you would
like to run Linux, begin with an existing product (e.g. vendor
evaluation or demonstration board) that already runs Linux, and work
from there. Be aware that there is no officially supported kernel
level debugger for Linux, and that the kernel environment is
fundamentally different than a normal tasking environment. It is
probably not a good idea to try to make a lot of code run as a kernel
driver; instead, large amounts of code should either run at user level,
or don't use Linux at all. If you do want to write kernel
drivers, I recommend the book Linux Device Drivers from my favorite
book publisher, O'Reilly (www.oreilly.com).
Be aware that the Linux kernel is undergoing constant change, with
fairly major changes sometimes made in allegedly maintainence releases
of older kernel major versions.
Compilers
GNU Compiler Collection (GCC) -- gcc.gnu.org
:
Supports
code generation for most 32-bit processors you are likely to
run into and is entirely free. Developed by a loosely knit team
of
volunteers (largely paid by various companies that benefit in one way
or
another from the association). Some key points to be made about
GCC (and the two other packages you will need: binutils (assembler,
linker, librarian) and gdb (debugger)):
- For any particular target, there may well be a proprietary
compiler that produces somewhat tighter code than GCC, but not by a lot
(usually). Proprietary compilers may compile faster, but that is
not as big a concern.
- The documentation on gcc compiler targets is woefully
inadequate. You may find yourself scratching your head even to
know what compiler target name you want, mostly because of the plethora
of cpu variants and operating system variants. But once you
figure
out the compiler target name to use, you should be in good shape.
The documentation of target-specific options that you may pass to
the compiler is usually pretty good.
- The
installation instructions assume that you want to install
compilers (including cross-compilers) and other tools in a single
non-moving place which you specify when you build the compiler.
For version control reasons, i don't recommend this (it makes it
difficult to run different versions of the compiler for different
versions of software). If you move the compiler installation
directory to a different path, it no longer works correctly (I've heard
that this may have been fixed in recent releases... I haven't checked
yet). The
workaround for this problem is to invoke a cover program or script that
runs the compiler with -B, -I and/or -L options and well as a modified
PATH environmental variable so that the right places will be searched
for running compiler subcomponents, finding include files and finding
libraries. The embuild-atool
gccbase module has an implementation.
- Compiler bugs are rare, although I have come across a few in my
career (mostly for the arm7 thumb instruction set). Suspect your
sanity before suspecting a bug.
Response to bug reports can be very fast or glacial depending upon the
availability of volunteers.
- The gnu toolkit supports C and C++ and a few other languages
(including basic assembly language for each target). Gcc offers a fair
number of enticing extensions to the C standards; it's method of
embedded assembler language is especially powerful and handy.
Using these extensions of course makes your code non-portable.
Apart from the extensions, the standard compliance is quite good even
for the morass of C++ standards.
- It is possible to modify the compiler, though that is not for the
faint-hearted. For a good reference see gcc.gnu.org/onlinedocs/gccint/
. I once modified the compiler to emulate byte writes for an
architecture with a dram bus that did not honor the A0 line... this,
coupled with some rewriting of a few key pieces of code, made porting a
large body of software a reasonable task.
- The biggest weakness of the gnu toolset is the debugger.
Actually the debugger is quite good except for a few major flaws. The
debugging information produced by the compiler (used by gdb) is plain
wrong much of the time except when all optimizations are turned off...
in which case it sometimes happens that code will not compile. (I
suppose it would increase by a factor of ten the size of the already
large debugging information generated along with an executable, in
order
to precisely follow the lifetime of a variable; and given the tricks
that optimizers do, it would be difficult to do reasonably.) With
experience and depth of understanding of the operation of the compiler
and looking at the generated assembler code it is possible to largely
work around this problem. Others will become frustrated if they
need to use the GDB debugger very much. The command line
interface is simply used with a few simple commands, although one would
not guess this from reading the help system; the major weakness of the
command line interface is that it displays only one line of source code
at a time unless you use cumbersome commands. This problem is
avoided by using a graphical user interface cover program for gdb.
I like the DDD graphical user interface for the GDB debugger,
which does a good job of displaying C source code; displaying of
disassembled code is, like the command line version, limited to
displaying the code of one C function at a time and is annoying and
attempts barely usable. The above mentioned problems vary quite a
bit according to the cpu target.
Commercial compilers often require licenses which are enforced through
automatic mechanisms. In a larger organization, it can be
difficult to determine how many licenses to buy in order to avoid the
occasional "out of licenses" error that can e.g. bring down an
automated
build. On the other hand, each compiler has it's strengths.
Libraries
The C library of choice for small but not tiny embedded systems is
newlib (sources.redhat.com/newlib)
which is distributed under a Berkeley-style license. It was
originally developed by various volunteers and the paid staff of the
former Cygnus company, now absorbed into Red Hat; in spite of Red Hat's
subsequent abandonment of much of it's embedded system emphasis, I note
that recent updates to newlib have ocurred. Fortunately, the C
standard library is not much of a moving target. Besides being a
complete implementation, this C library is highly suited for embedded
development because it's per-thread context is kept in a single data
structure referenced via an anchor pointer; you simply need to
ensure that this pointer is updated whenever you switch context.
The library relies upon the presence of a handful of system call
functions of the traditional Unix flavor (read, write, etc.) which are
easily hacked for simple applications. There is a handy hook for
locking during malloc calls (which are an exception to the per-thread
context rule). I have had problems in the past with software
floating point support, but otherwise have been pleased. Floating
point is something best avoided as much as possible on lowly
processors. Please note that even (s)printf formatting of decimal
integers requires many cpu cycles on a lowly processor (e.g. ARM7TDMI)
due to the lack of integer division support in the processor; if you do
much of this, you wil need to rework the code to replace the standard C
divide and modulo by 10 with special fixed point algorithms.
For Linux systems, glibc (www.gnu.org/software/libc/libc.html)
is usually used.
The lwip networking library (http://savannah.nongnu.org/projects/lwip
and http://www.sics.se/~adam/lwip)
provides an IP protocol stack that works asyncronously (i.e. does not
sleep, and uses callbacks for completion), which is ideal for some
embedded system projects. It also supports a syncronous
interface. Development seems to have slacked off and there are a
lack of some of the peripheral components; for example, there is no
integerated domain name resolver.
Merge and Difference DisplayTools
I can be quite happy using a command line interface for most
software development tasks, even sometimes for running a debugger such
as gdb, and am happy with a curses-based text editor (vi), but i would
be lost without GUI tools for comparing and merging source files.
Unfortunately, there are not a lot of choices in the free software
world.
I have used xxdiff a lot ( the web site http://xxdiff.sourceforge.net is
quite helpful). xxdiff takes some getting used to but
generally does what i want, including 3 way merging of files, and
options to ignore some types of differences such as line endings.
Unfortunately, it is pretty limited with respect to directories; it
will only do a two way compare of directories, and doesn't provide any
control over whether files are shown as equal or not. For directories,
you double click on a filename to get a new, independent window for the
file.
For a completely different user interface experience, try kompare (part
of the KDE suite). It excels at letting you quickly browse
through all the differences of all the files beneath two matching
directory hierarchies. It is still pretty immature and there is
apparently no documentation for it.
Reconfigurable Hardware
Software engineers can now write hardware, thanks to Field Programmable
Gate Arrays (FPGAs). This is an exciting new avenue for
exploration. There are a number of hobbiest boards available via
the web; unfortunately I haven't tried any yet so I can't recommend
them... anyone have any experiences to share? Of course, FPGAs,
being logic circuits doing many things in parallel, have some distinct
challenges that rival the worst multi-threaded multi-processor software
systems.
I
had the opportunity to make a contribution to the (freely available)
software for the Elphel Camera (www.elphel.com),
the company of Andrey Filippov. While not the cheapest cameras,
these cameras can be reprogrammed to do what you want to do.
Andrey makes the source code for both software and FPGAs as well as the
board schematics available on his web site under the GPL license.
Here is a link to an article
that explains what he did and what you can do (there are links to more
articles on the Elphel web site).
Embedded software design magazines and websites
For keeping up with Linux (and free software) developments, there is no
substitute for reading the Linux Weekly News --
lwn.net
And of course don't forget slashdot.org
The print magazines that i used to recommend have gone by the wayside, except
for Dr. Dobb's Journal is i think still around.
Dr. Dobb's Journal -- www.ddj.com
Dr. Dobb's ("Software Tools for the Professional Programmer") has
been around since the early days of microcomputers. It covers a
range of software areas, not just embedded software, but frequently has
articles of interest to embedded software developers.
Books
O'Reilly
and Associates -- www.oreilly.com
O'Reilly sells software-related books, easily identifiable by the cute
animal pictures on the covers. Their quality is
usually
so high that it is a shock when the produce a lesser quality
book (hmmm... i've been disappointed by several of their books).
Look here first for authorative reference and tutorial works.
Software Development Methods
My friend Doug Dahlby contributed his review of current thinking
regarding software development methods in an article he contributed: Applying Agile Methods to Embedded
Systems Development (also in PDF
and DOC). Example
quote: In short, agile methods use continuous communication
(customer/manager/developer, manager/developer, and
developer/developer) to manage change, keep close traceability between
customer requirements (“stories”) and the software, deliver functional
incremental software releases with a rapid turnaround, (and) improve
(“refactor”) old code selectively and continually.
Free Software Licenses
Instead of writing software (entirely) yourself, it is prudent to see
if you can simply obtain if from someone or somewhere else. This
is is most easily done if the software is available in source code form
and is freely available, which leads us to the subject of (free)
software licenses.
Software licenses allow use of copyrighted software. It is also
possible to simply not copyright software (by not including any
copyright notice) and place it in the public domain (in particular, if
you have a notice stating that it is placed in the public
domain). A lawyer writing in the Linux Journal (http://www.linuxjournal.com/article.php?sid=6225
) claims that placing software in the public domain protects neither
the producer nor the user of the software from a variety of ills;
however, I have never heard of anyone actually finding this to be a
problem (but then again I'm not a lawyer). There are a variety of
free software licenses (see http://www.opensource.org/licenses
)
, but the most popular are Berkeley-style licenses, the GNU Public
License (GPL) and the Lesser GNU Public License (LGPL). All of
these licenses protect the producer of the software from being sued for
various imagined wrongs, and give rights to use the software to the
public; and as a necessary but sometimes unfortunate adjunct, require
that derivative works adhere to and reference the same license (thus
copying a few lines of code without giving the appropriate reference
puts one in technical violation). Such licenses are definitely a
must for large software projects with many contributors.
Beyond the afore mentioned basics, Berkely licenses often require that
credit be given to the author or author's institution in prominent
places associated with a product; this requirement is rarely adhered to
in practice. The GPL goes further in requiring that source code
for any derivative works be made available to anyone who buys software
in binary form (recursively). The definition of derivative work can
include anything linked (by a linker) and thus some people refer to GNU
license code as contaminating other code (while other people use
inter-process communication to another program to avoid being required
to reveal source code). The LPGL restricts the scope of
contamination to the original source files (and is typically used to
permit library code to be linked into closed source programs).
After reading the above, you may understand why the wheel is so often
reinvented. I you want to restrict others from seeing your source
code, you must live in a parallel universe where much of what you do is
has been reinvented by you. If you are willing to share your
source code, then you have many more options as to what software from
others that you may use (and modify), although you will still be
frustrated to some extent by the license terms (for copyrighted
material) or possible lack of legal protection (for public domain
software). Most frequently you may have to live in several
universes according to license type.
There are also software patents to (perhaps) worry about. This is
an unfortunate development in recent years. Patents in general
deny benefits to the inventor of an idea unless you happen to be the
first to have provably invented the idea. I have often been
advised never to read a patent... because knowing violation of a patent
(evidenced by having ever read the patent) carries a far stiffer
penalty than unknowing violation. You may thus find it amusing to
learn that patents are justified on the grounds of the benefits of
public dissemation of knowledge. Patents are supposed to be
issued for non-obvious inventions only. Of course, everything is
obvious given the background and motivation, so the term non-obvious
has (pardon my saying) no obvious meaning. The predictable result
is that the patent office allows very absurd things to be patented,
although of course this may not be revealed publicly for years
until a patent is actually issued. A good protection against
being sued for possible software patent infringement is to never reveal
your source code. So much for the benefits of public dissemation
of knowledge. Fortunately, software is easily changed, so a found
patent violation may be remedied in many cases by simply using a
different algorithm.
Legal
emBuild, emBuildSw and emBuild Software Design are trademarks of Ted
Merrill (for software and software design). The material on this site
is placed in the public domain (and not copyrighted). Other
trademarks and logos are the property of their owners with which they
are associated on this page. You are welcome to
beg, steal or plagiarize the material from this site and from embuildsw.org to your heart's
content except for these trademarks; you are requested to rename any
derivative works to some name not containing embuild.