How to become an embedded software developer?
I'd like some tips for those who want to become a good embedded software developer or want to improve in this area.
What should I need learn about hardware, software?
Which books are most recommended? Blogs?
In the end, how could I go from a beginner hobbyist to an excellent professional?
All the answers have been good so far, but I'll throw in my two cents.
Here's a repeat of some tips with a twist and some extra:
- Learn C: The fundamental language of the hardware that is still portable (too some degree). Don't just learn it, but become an expert of all it's features like volatile and why it is important for writing device drivers.
- Start out with a good development kit like Arduino, but as said before learn other architectures once you got a good feel for it. Luckily there are some Arduino compatible boards built with other processors, that way you can rewrite the same design on a different uC not mess up your whole design while getting a feel for something new.
- In the learning stage, feel free to re-invent the wheel on device drivers or other pieces of code. Don't just plop someone else's driver code down in there. There's value in re-inventing the wheel when you're learning.
- Challenge yourself to re-write your code more efficiently in terms of speed and memory usage.
- Becoming familiar with different styles of embedded systems software architectures. Start with basic interrupt driven/background loop processing, then move up to background schedulers, then real-time operating systems.
- Get good source control! I prefer Mercurial myself.
- Even sign up for some free source control hosting sites like Sourceforge.net or Bitbucket.org to host your project even if you're the only one working on it. They'll back your code up, so you don't have to worry about that occasional hard drive crash destroying everything! Using a distributed VCS comes in handy, because you can check in changes to your hard drive then upload to the host site when ready.
- Learn your tools well for whatever chip you're working on! Knowing how the compiler creates assembly is essential. You need to get a feel for how efficient the code is, because you may need to rewrite in assembly. Knowing how to use the linker file and interpreting the memory map output is also essential! How else are you going to know if that routine you just wrote is the culprit of taking up too much ROM/Flash!
- Learn new techniques and experiment with them in your designs!
- Assume nothing when debugging. Verify it!
- Learn how to program defensively to catch errors and verify assumptions (like using assert)
- Build a debugging information into your code where you can such as outputting memory consumption or profiling code with timers or using spare pins on the uC to toggle and measure interrupt latency on a O-scope.
Here are some books:
- The Pragmatic Programmer by Andrew Hunt and David Thomas - more or less required reading for any practical software development
- Practical Arduino
- Programming Embedded Systems by Michael Barr
- Embedded Systems Building Blocks by Jean Labrosse
- MicroC OS II Real Time Kernel by Jean Labrosse, great intro into RTOS's in general in there along with his OS.
- Embedded Software Primer by David Simon - good intro to embedded software
Here are some websites:
@Adam: I love that book! Pragmatic Programmer! I can't believe I forgot it!
- Remember, "There is no silver bullet", don't fall into the trap of believing that there is one tool, methodology, language or system that can solve all problems
- Become an expert in C
- Learn to get by without malloc() and POSIX
- Don't get hung up on one architecture, it's easy to become a PIC or AVR or ARM fanboy by accident
- Build stuff, debug it, make it work. Practice makes perfect
- Learn at least one source control system (SVN/git/etc) and use it
- Always be prepared to test your assumptions. The bug is usually in the thing you are assuming works
- Don't become too reliant on debuggers, they're different on every system and of varying reliability
- Think frugally. When problem solving, think about code footprint, RAM footprint and hardware cost
For books, I'd recommend digging through history. Most of today's embedded software techniques come from the bleeding edge of yesteryear.
Like anything, practice daily.
Of all the things I have learned, version control (I use subversion currently) is the most valuable thing to my productivity. We had sourcesafe by Microsoft when I started here, so I used a bad solution and then a good.
I cannot imagine my life without a source control system. I use SVN currently too. I don't know how things worked before I know SVN.
"Learn to get by without malloc" - Why? To minimize risk of stack/heap collision?
The other answers are great, but the biggest difference between a hobbyist and a professional should be a mindset about quality. So have your project go all the way, don't stop when you are 80% done with a project. Take it all the way, prove that it is working, and document it correctly.
Make sure your code is readable and maintainable.
And don't forget to have some fun as well :)
Apart from the obvious, like learning C and start with some developer board, you'll want to learn to read microcontroller datasheets.
Manufacturers add more and more features to microcontrollers, which therefore become more and more complex. The datasheet doesn't only provide electrical characteristics (which is more interesting for the electronical engineer than the software developer), but also detailed description of registers, memory maps, etc.
On first reading a datasheet may look daunting, but failing to understand them can cause a more severe headache in the debugging phase.
'Embedded' is a bit of a loaded term..
In some respects, any system dedicated to running a single application could be called an embedded system, as long as there is some hardware to be controlled. You can arguably call a 400MHz PPC604 with 2GB of RAM running a java application on top of linux an embedded system, if it happens to be controlling a process through local I/O modules. On the other hand, an arduino just running some kind of minimal network application wouldn't be much of an embedded system. But probably 'embedded' makes most people think of flash based controllers with only a few hundred bytes of RAM, no operating system to speak of, and a plethora of on-chip peripherals.
That being said, probably the two biggest hurdles non-embedded programmers usually face learning embedded systems are I/O registers and interrupts.
Interrupts may actually be the easier of the two concepts for non-embedded programmers to deal with, since the main issues with these, concurrency and event driven programming, are often encountered in mainstream applications. What makes interrupts a pain is realizing the extreme sensitivity of a system to the quality of its interrupt handling, and the intricacies of dealing with hardware to clear the interrupt condition and set up for the next one. With a GUI, a deadlock kills just the application. With an interrupt handler, a deadlock causes your entire system to lock.
I/O devices seem to be the area that cause the most difficulty. For the uninitiated, it can be quite a surprise to discover that reading this register here has an effect on that register there. Writing 1's to clear bits. Status bits that clear themselves when you read a data register, etc. There are so many possibilities with I/O hardware that there is no general rule for dealing with it, except to learn how to find and interpret device data sheets. Writing a device driver for a serial port will teach you much about low level I/O programming.
There's really no substitute for learning these things than to roll up one's sleeves, and program some straight C and/or assembly language on the bare metal. Even the aforementioned java based embedded system eventually needs a device driver for the I/O, and this means ultimately dealing with some C. Experience is the best teacher. Pick a microcontroller, be it MSP430, TMS320, AVR, ARM, PIC, 68HC11, whatever, find an eval kit, and build some systems.
Sparkfun has a number of good sub $\$$50 development boards. Also go to TI for the Stellaris family in the $\$$50 to $\$$100, also the Hawkboard which for now I would recommend before the Beagleboard for what you may want/need to learn, also TI has the MSP430 family and I would get an EZ430 and a three pack of the add-in boards for $\$$10. At Sparkfun get a Lillypad with the FTDI USB serial/power board, the Lillypad is pretty much the same as the Arduino pro mini but you need to solder for the pro mini. I am not a fan of the PIC family but you may want to get something there as a history lesson, same goes for the 8051, both families are still popular and in use, just not very efficient and have been passed over by other architectures. Absolutely learn ARM and thumb, maybe MIPS (which is a pic-32, not to be confused with the older original PIC architecture). The ARMmite Pro is a good entry level ARM board, although the Stellaris may be as well.
What you want to learn here is assembler for various platforms. C. C and assembler interaction. Different tools GCC and non-GCC. How to read a datasheet/programmers reference (and realize they all have some errors or can be misleading, never trust them, the hardware wins over documents) and how to read or use a schematic. These are not complicated schematics normally. A number of the boards are good for interfacing in projects meaning they dont have garbage on the board in the way, just direct access to the I/O pins. But that is not the best for learning. Something like a Stellaris board which is painful for projects has lots of fun stuff on board for learning embedded and learning to borrow/use drivers or write your own from datasheets. The Atmel AVR butterfly is a good board too if still available, may need to solder on your own serial port to program it or just jam some wires in the holes. What it gives you is a few peripherals you can learn to program.
Even if you end up doing embedded work that involves writing applications using SDK or API calls on linux or an RTOS (never touching hardware or reading datasheets), the above knowledge will still set you ahead of the rest.
It begins by outlining the spheres of knowledge you must develop:
Knowledge: You must know the theory involved in embedded systems. This means hardware and software. It is impossible to be a competent developer of embedded software without getting to know the hardware architecture which is working.
Skill: You need to get experience in the area. Needs practice. You can decorate all the PIC assembler mnemonics, but it is no use if you can not drive a LED with this knowledge.
Attitude: Above all, you need to attitudes that will make you grow in this area. It is a very dynamic with frequent changes and developments. You need to always be motivated (a) be self-taught, enjoy learning, "tweak" and understand how things work. Without such attitudes will give you soon. Because this area you need to be very, very persistent.
It then gives the following tips for mastering these areas (and develops them with further text, these are just the headings):
- What you need to learn hardware (at least)
- What you need to learn the software (at least)
- In addition, study operating systems
- You need a training
- Do not stop, keep learning and developing your networking!
Thanks for the link! The Google translation seems to indicate that it's a perfect fit for this question. However, we'd prefer that (1) the text is in English (we're an English-speaking community, even though many of us are at least bilingual) - Auto-translate only if you have to (2) the answer includes a summary of the article in case the link goes dead. I've edited your post to adhere to these guidelines, and given you an upvote for it!
Think twice before you become an embedded software engineer. I have had phases in my career. I have developed software the first 5 years, than move to sales/marketing, done that for 15 years, managed a 100+M$ business and now I am back to software.
When I come back to software after 15 years, I remember why I left in the first place. It is hard. It needs concentration, several hundreds of lines of code touching each other and you all need to keep it in the memory. Embedded is particularly hard.
You also need to understand yourself. If you are generally a smart guy, meticulous and patient you would make a great engineer. If you are missing any one of those you will be average at best. Think about that. If you are ultra smart and not patient, doesn't worth much because no matter how smart you are, good engineering takes patience and attention to detail.
You also need to be comfortable looking at code hours at a time without talking. I observe that people with good social skills find this unbearable.
If all this checks out, than read all those great books, do the exercises and you will make a great engineer.. Good luck
Everyone else says great things. So I'll give you general advice: read read read read read read read read!
Read every article on http://embeddedgurus.com If you don't understand something, research it. If in the explanation of those things you find something you don't understand, read some more. I'm about to head into an embedded software position and my experience is a handful of professional projects over the past few years and a lot a LOT of reading. Experience lets you try things, but reading lets you know whether the things you've tried have been done before, maybe better than you could. It introduces you to concepts that you can work with in any circumstance.
Become an expert in C Understand Timers and Serial communications. You should get your hands dirty with it. Understand RF protocols, tweak them to your requirements. Don't just blindly try out combinations of code while debugging. Code does exactly what you tell it to do. Read the user manual and data sheet and then make a change if something doesn't work. All that said and done, the only real way to become an expert is to practice. Keep building applications. Soon, it will become second nature.