I hear variations of this question a lot:
- “How do I get started in embedded software?”
- “What should I do first?”
- “I’ve developed some projects in Arduino – what do I do now?”
The great thing about the internet is that there are so many options available to learn any skill you can dream of. The bad thing about the internet is that there are so many options available to learn any skill you can dream of.
It’s easy to be paralyzed by the sheer number of choices.
Well-meaning people will often reply with answers like:
- “Just pick a project and start hacking.”
- “Blow some stuff up – don’t be afraid!”
- “Do an online course.”
I’ve made comments like this myself. These comments aren’t necessarily bad advice, but if you’re a beginner, you are likely to want specific recommendations for what to do next. Do exactly this, then that.
I’m going to detail one approach to learning embedded software development that will take you from beginner to intermediate level, so you can be well on your way to getting a job working in the industry. There are many ways to learn embedded software, but if you’re paralyzed by indecision, and just want someone to point the way for you, this article is for you.
- Do you want to write software that interfaces with physical systems like lights, motors, and sensors?
- Do you want to invest in skills that will provide a solid foundation for your career?
- Do you want to get a job in industries like robotics, automotive, aerospace, or medical devices?
This will be a lot of work, and will take time. You will also need to invest in some basic equipment, like a development board, and few books and online courses, that I will detail below.
Let’s get started!
What I mean by “Embedded Systems”
The line between “Embedded Systems” and “General Purpose Computers” is getting increasingly blurry.
There are two primary categories of embedded software:
Software intended for a microprocessor running a general-purpose operating system such as Linux. Such operating systems require the processor to have a Memory Management Unit (MMU) so that each software process thinks it has the entire processor to itself. There are plenty of embedded systems out there that use such powerful microprocessors. Writing code for these platforms is similar to writing applications for a desktop computer.
Software intended for a microcontroller that does not have a MMU. This type of software is often referred to as firmware. You can either write your firmware to run without an operating system at all (referred to as “bare-metal” programming), or you can use a Real-time Operating System (RTOS) that provides very basic scheduling and coordination tools that you can use to write multi-threaded applications. Don’t understand what that means yet? That’s ok.
This article will discuss learning the second category of embedded software: firmware for microcontrollers.
I’ll dive into each of these elements in more detail, but let’s look at the steps to going from beginner to ready to apply for embedded software jobs.
- Learn C
- Learn basic electronics
- Learn and do basic projects in Arduino
- Follow an introductory online course in Embedded Systems
- Follow an online course to learn FreeRTOS, a popular real-time operating system
- Now pick a project, and get to work!
- Build a portfolio
- Start applying for jobs!
Step 1: Learn C
The C programming language is the primary language of embedded systems. There are other languages in use, but C is by far the most common. You must know it and be comfortable understanding and writing code in it. Later, you can learn other languages such as C++, but for now, stick to C.
You will need to understand:
- all the basics: variables, control flow (if-else, for and while loops)
- pointers and array access
- bit-field manipulation
I recommend “Learn C the Hard Way” by Zed Shaw if you are new to C.
Once you have some experience working with C, I recommend reading Matt Stancliff’s Guide to Modern C.
Step 2: Learn basic electronics
If you’re writing software for microcontrollers, you’re going to interface with real-world hardware. You MUST get comfortable with basic electronic skills.
At a minimum, you need to understand:
- Ohm’s Law, that relates voltage, current, and resistance
- pull-up and pull-down resistors
- how to use a multimeter to measure voltage and resistance, and check connectivity of your circuits
I recommend following the “Getting Started with Electronics” e-book by Oyvind Nydal Dahl, available at https://www.build-electronic-circuits.com.
Step 3: Learn to use Arduino
Arduino is an open-source hardware platform, along with a development environment and set of libraries, to make working with embedded systems simple. Many may disagree, but I think the learning to work with an Arduino board is a wonderful way to get used to working with real hardware. Arduino abstracts away a lot of the software details that you’ll have to learn at some point.
You can skip this step if you don’t feel at all intimidated when faced with a microcontroller board, but if you have no prior experience with electronics, I definitely recommend playing around with Arduino.
I recommend following the book “Programming Arduino: Getting Started with Sketches” by Simon Monk.
Step 4: Follow an introductory online course
There are many online courses available that guide you through basic embedded systems programming.
There are two courses that I recommend following from beginning to end:
Embedded Systems - Shape The World: Microcontroller Input/Output on edX
This is a typical introductory course that hits all the major topics for a beginner.
Modern Embedded Systems Programming by Miro Savek
This course is very thorough, and shows you how embedded software development works from first principles. It’s clear that he ultimately wants to show you the advantages of his QP event-loop embedded operating system, which is an alternative to the more common real-time operating system (RTOS) paradigm.
Along the way, Miro demonstrates many fundamental concepts in embedded development:
- how a microcontroller works
- how to read a datasheet
- understanding different Integrated Development Environments
- how to debug, view, and modify registers and memory locations at runtime
- how and when to incorporate assembly language into your C programs
- how to use interrupts
- how to avoid race conditions and other nasty bugs
- how a real-time operating system (RTOS) actually works
I can’t recommend this course enough. If you study and follow along carefully, you will have a deeper understanding of embedded programming than many working programmers.
I think you will get more out of this course if you take it after a more typical introductory course on embedded systems. This course will fill in a lot of the gaps in your knowledge, covering material that a more typical course glosses over.
Step 5: Follow a course on Real-Time Operating Systems
Typical desktop applications do not have true real-time deadlines. If the computer freezes for half a second while some background task is executing, the user may find it annoying, but life goes on.
If you are writing software for an autonomous vehicle, you have no such luxury. If the software task that controls the steering or braking is delayed because the controller is parsing some large incoming command message, your vehicle may drift into oncoming traffic or slam into the back of another vehicle.
Such systems are said to have “hard real-time requirements”. There are deadlines that, if missed, can cause serious harm.
For complex firmware that has many jobs to do, but must be guaranteed to meet real-time deadlines for at least some of those jobs, a real-time operating system (RTOS) is the standard tool to use.
There are many RTOS’s available, both open-source and proprietary. FreeRTOS is a widely used open-source RTOS that is commonly found in many industries. If you learn how to use FreeRTOS, you will be well-positioned to use any other RTOS that you may come across.
I recommend the Development of Real-Time Systems course on Coursera.
Step 6: Pick a project
It’s finally time to pick a project!
By this point, you should have enough practice under your belt that you don’t feel overwhelmed when working on something for yourself.
Start simple, build something to completion, then put your code aside and do it all over again, maybe with a different programming paradigm. For example, write your code the first time with just a main loop. Note any drawbacks. Then redo it as a main loop processing background tasks, and interrupts for any real time activity. Then redo it using FreeRTOS.
Here are some project ideas:
- Build a simple robot with one of the many kits available online. For example, here’s a kit from Newark.
- Build an orientation sensor that measures its orientation coordinates in real-time and outputs them over a serial line. You can connect it to your desktop with a serial terminal and watch the numbers fly by as you hold and turn it. The ST Discovery Board is a cheap evaluation board for the STM32 line of microcontrollers, and it includes an onboard 3-axis accelerometer that you can communicate with over SPI.
- Build a simple weather station for your backyard, that measures temperature and humidity and shows the results on an LED screen. You can use an Arduino board as the base, since it comes with a great. However, skip the Arduino development tools. You can use Atmel Studio to develop programs for Arduino boards, without being limited by the Arduino toolset.
The most important thing to is to pick a simple, doable project and finish it. It’s still easy to be paralyzed by all the options out there. Just pick something!
Step 7: Build a portfolio
If your goal is to get a job as an embedded systems developer, and especially if you don’t have a degree in EE or Computer Engineering, an online portfolio is a great way to show off your skills and demonstrate that you can accomplish embedded development projects.
As you build your projects, keep careful notes on your design decisions, your development process, and your testing of the final result. Make yourself a webpage, and have a “Projects” section where you give an overview of each project and a link to a github repository of the code.
Since you are doing this to show future employers, you should only do this if you take the time to do it right. A sloppy portfolio with low-quality code can often be worse than no portfolio. If you don’t want to take the time to make this look professional, it may be better just to list your side-projects on your resume, and be prepared to talk about them in depth during your interviews.
Step 8: Start applying for jobs!
You are now in a strong position to be attractive to employers as a junior embedded software engineer. The following industries are great places to look for jobs.
- Medical Devices
- Consumer Electronics