I have a number of years of experience in C++ development, and I'm about to become a full time embedded programmer.

But, as I draw closer to my start day, I'm becoming more nervous; it appears people have vastly different definitions of what embedded development means: from something similar to desktop C++ development to something like an electronic engineer.

What should I know about embedded development before I start How can I make good use of my time to prepare for the challenges ahead?

This question appears to be off-topic. The users who voted to close gave this specific reason:

"Questions seeking career or education advice are off topic on Programmers. They are only meaningful to the asker and do not generate lasting value for the broader programming community. Furthermore, in most cases, any answer is going to be a subjective opinion that may not take into account all the nuances of a (your) particular circumstance." – DougM, Bart van Ingen Schenau

it will depend on what level on the software stack you will want to focus on. Deeply embedded (ie close to the metal) is very different to application embedded (ie almost like PC level development). Please give more details.
–
tehnyitAug 1 '11 at 8:42

6 Answers
6

I wouldn't worry about it too much. People in the embedded world understand that somebody entering it for the first time will have a bit of a learning curve.

In general, the big thing to keep in mind is that, compared to a desktop system, the system is much more limited. You will probably have a lot less RAM, a much less powerful CPU, almost certainly no disk swap space, and most likely either no GUI or a very limited one. You may not even have an operating system.

Also, the code/build/test cycle can be really long, as in 5-10 minutes, and you may not have things like a runtime debugger on the device (e.g. no gdb, etc.). So rather than making little tweaks to see what happens, it's usually more productive to write a lot of code at a time, code very carefully, and add lots of printf-type logging to see what's going on at runtime. Depending on the device and its ports, you'll often want to send your logs to a serial port and pick them up using a terminal program on your desktop build machine.

The details of those limitations and what you do to compensate can vary a lot, as can how you build the executables and put them onto the device for testing. You'll have to find out about all that once you get on the job. Here are a few examples...

On a couple of Linux-based ARM cell phone projects, I would simply build and test on a desktop, cross-compile for ARM, and transfer the executable to the device for final testing. Depending on the test hardware, the transfer could be done over a serial link, using an MMC or SD flash card, or (when I was really lucky) using Ethernet and an NFS export from my desktop development box.

On another Linux/ARM tablet project, the above applied, but the system was powerful enough some executables could actually be built on the device itself.

One digital camera project I worked on was deployed using Hitachi and Fujitsu 16-bit microcontrollers. That required really tight coding, and I wrote it all in "embedded C++", which limits the language features to prevent code bloat.

8-bit 8051 microcontrollers are still very common. They're used for all kinds of crazy things, like the automatic door openers on subway cars, and there's probably one in my coffee maker :-) But it's a really constrained environment and requires special skills and compilers.

Update... I forgot to mention...

Quality must be a priority for an embedded system to succeed. Often, you can't do field updates to shipped product ("Please insert this CD-ROM into your coffee maker."). And even if you can, it can be crazy-expensive - for instance, hundreds of thousands to millions of dollars per carrier to update a cell phone's firmware.

Also, all the "wisdom" about premature optimization goes out the window. If you have specific performance requirements, and defer meeting them, you may find you've painted yourself into a corner design-wise, and have to rip a lot of things out and start over. It's much better to write each component to meet its performance goals initially, and make sure it continues to meet them throughout the development process.

Very good answer. I'll add a couple more thoughts. You sometimes need to check the efficiency of the techniques used. Some ways of implementing algorithms will consume more flash space, some will consume too much processing power. At some point you will meet hardware, and you need to define and analyze the needs of those interfaces carefully. Avoid fancier C++ options to maintain efficiency, like multiple inheritance, STL, etc. Using C-like techniques can often be more efficient. You'll sometimes need to optimize in order to reclaim hundreds of bytes to add a bugfix. Good luck.
–
MattGJan 30 '12 at 23:16

Embedded is a whole range of work, from SCADA systems that are actually bigger and more complex than any desktop programming, to tiny controllers that do simplest tasks, done in 1 kilobyte of EEPROM, 16 bytes(!) of RAM and 6 IO pins total. And the tasks for the developer are just as varied - embedded is both a factory floor control system and a blinking light on a bicycle lamp.

You can't learn all of embedded, it's impossible. While not as widely recognized, embedded is just as "wide" as classic programming. Learn the architectures you will need, the languages you will use, get a clue of what can do what - limits of given families of microcontrollers, some single-board computers, specifics of Embedded Linux and so on. Do many toy projects. But primarily learn what is your task and focus on it because there is no way you can learn everything.

There's more to your toolchain than you realised in the desktop world. You are responsible for all sorts of setup things which are specific to your system, which (because of the relatively well-defined desktop platforms out there) can be done for you behind the scenes when you are on a desktop.

Error handling is important - if something fails, you have to figure out a reasonable thing to do with it and fail gracefully in many cases. In the most extreme cases, you (and your hardware design colleagues) have to figure out ways that things can fail and your system can still get its job done (think jet-engine controller... rebooting may not be an option!)

You'll have to work with hardware designers - as early as possible in the design process is best - you'll learn a lot and in the fullness of time be able to feed useful things in which will make your software life easier in the end.

Develop some hardware skills early (like using a voltmeter and oscilloscope) - you'll inevitably have to debug some comms interface and tools like that make it very easy to see when you've got the baud rate wrong, or the voltages are upside down etc.

You convinced your future employer that you can do the job, otherwise you would not have gotten in. They know that nobody can just jump in and do everything perfect the first time - there is always a lot to learn.

So this is what you need to do, have an open mind, learn all you can, and do a good job everyday.