Blogs

Skills For Embedded Systems Software Developers

Steve BranamAugust 9, 2022

Contents:


Introduction

This is a question I've gotten a few times: what skills do I need in order to work as a professional embedded systems software developer? I've listed a number of them below, with some recommended resources.

If you're interested in doing this work, you're going to need to be able to do these things. These are real skills that real employers need developers to have to work on real jobs. This is a practical, vocationally-driven list.

Is it a lot of stuff? Yes. Embedded systems software development is not for the faint of heart. It's complicated, with many subtleties and pitfalls. It takes patience, persistence, and a high tolerance for failure. You need to be driven to do it if you want to be successful.

This article is available in PDF format for easy printing

This list if for all age and experience levels, from high school students (or younger!), through college students and experienced workers well into their careers (or older!). It applies across all backgrounds, from non-technical to technical, including career-changers shifting over to embedded systems from other types of software or technical fields, or from non-technical work.

This list can never be complete, because the technology and the industry are forever changing. This is merely a 2022 snapshot, based on the things I've been exposed to in my own work and study.

The good news is that every skill you already have or you develop becomes part of the background knowledge that helps you learn new skills as needed. The most important skill you can develop is the ability to learn new skills. That builds versatility to keep you relevant and marketable in the jobs marketplace for a long, sustainable career.

Let's look at some questions you might have.

Do I Need To Be An Expert In Everything?

No. You need to have at least a general familiarity with these skills, a reasonable level of competency in many of them, and a high level of expertise in some of them. The exact mix of competencies will vary over your career with different jobs, different companies, and different projects.

Treat this as a checklist of terms and topics that you need to learn. Some are quick, some are long and deep, entire fields of study on their own. Some are used every day, some only occasionally.

Expect employers to ask you about them in job interviews. They will want you to know more than just buzzwords. They might ask you how they work, where they would be appropriate to use, what tradeoffs there might be among various options, how you would implement them.

At a minimum you should go through some web pages and videos on each one; there's probably a Wikipedia page on it. As you gain familiarity and experience, you'll see which ones require deeper study.

Anything you already know on this list is a head start. But you can also start from nothing.

How Much Time Do I need?

It might be feasible to get an entry-level job after about 6 months of focused work on this list, depending on your background, spending 5-40 hours a week. A more realistic expectation is that you'll need 1 to 2 years.

The most important thing you can do is practice doing things hands-on. Get some hardware soon and learn how to play with it, then play with it. A lot. That's a real skill-builder, doing the kind of things you'll actually do on a real job.

You can take a time-budgeting approach, based on 8-hour workdays (broken up into whatever your personal schedule allows). In broad strokes:

  • 1-2 hours for each line item to get some initial information.
  • 1-2 hours for each item to setup for hands-on work (installing/setting up and learning to use the tools and techniques for doing the hands-on work).
  • 4-16 hours for each item to do some initial hands-on work.
  • 4-16 hours for selected items to get more in-depth information.
  • 4-16 hours for those items to do more in-depth hands-on work.

This model is like a lab-based college course where you spend some time studying and some time doing, ensuring that you do some of both for every topic. There will be some topics that you find need more cycles of 4-16 hours of study and 4-16 hours of hands-on. There will also be some that need longer initial study, especially if they are very new to you.

A few topics are more on the theoretical side, so direct hands-on work is less practical. But there's always a way that you can incorporate them into other hands-on work, working with some code or hardware that exercises some of the related concepts, tools, and techniques.

Do I need A College Degree?

Many employers require a college degree. But not all, and many accept related experience in lieu of a degree. The challenge there is how to get that experience. That narrows down the field of employers willing to take a chance on you. But it doesn't shut you out completely.

If you have a college degree in a technical field, that can increase your chances of getting a job. Even a degree in a non-technical field can be helpful, because that's generally considered an indication of your intelligence and ability to focus on complex work.

By doing the hands-on work here, you'll build a version of the experience that employers are looking for. Not all of them will accept that, but some will. Create a portfolio of your work showing what you've done, starting from the first baby steps up to the most sophisticated things. Being able to document your work and present it to others is itself an important skill.

Why Is The List So Big?

Embedded systems comprise a wide range. They run in every type of environment, from the most benign sitting on a table in your house to the most harsh in terms of temperature, pressure, and vibration, subject to all kinds of external forces, from deep under the sea, to buried underground, to high in the sky moving at hundreds of miles an hour, to outer space.

They often have limited resources in terms of CPU power, memory, and electrical power. They may interact with a wide variety of external sensors and actuators. They may have tight timing requirements, in the milliseconds range, where failure to meet a processing deadline means system failure, with potentially catastrophic consequences.

They may have very high safety and reliability requirements, where people's lives and property depend on them. They may be controlling very dangerous things, with high energies involved and the potential for explosions and crashes (not software crashes, but physical crashes like cars, planes, rockets, trains, ships, and heavy equipment).

They may have to run for months or years without failing. They may have to sip power a tiny bit at a time from a single small battery over that period. Once deployed, they may be inaccessible for maintenance, reset, or repair.

Failure doesn't just mean a product that does poorly in the marketplace. It can mean death, injury, destruction. It can mean ruining people's lives.

These requirements can set a very high bar. You have to know a lot in order to be able to meet them. You won't use every skill on every project, but they all form the background knowledge against which engineering decisions are made.

Do I Really Need All These Things?

Yes and no. Because embedded systems development is a huge field, it has many specialties and subspecialties. For any given project, you'll only need a limited subset of these skills.

The problem is that you don't know which subset you'll need ahead of time to get a job. By covering a wide range, you'll be prepared to use the specific set of skills called for in any given job. If a job requires something not on the list, you'll have been exposed to things that have enough similarities that you can pick it up more easily.

Also, this isn't just about your first job. A fact of life in modern industry is that you will change jobs at some point. It could be involuntary or voluntary. You might get laid off ("made redundant"), or you might decide on your own you want a change, for any number of reasons.

There's a risk that you spend your career in one tiny corner of the field, never getting exposed to the other parts. Then when it's time to change, you're not prepared. If all you know is that one small portion, you'll be limited in the companies and projects you can apply to. Worse, if the technology you've been working with has become obsolete, there may be no such jobs.

You have to actively explore a wide range of topics to be prepared for job change. Make that an ongoing process, always learning about new things so that you stay up to date and versatile. Continue to grow with the field.


The Skills

I consider this an absolute minimum baseline that covers a broad range of embedded systems development. If you expect to get a job as an embedded systems developer, employers will expect you to have at least initial competency in these. Some companies and projects will have other specific requirements.

I've identified a few items as older technology that you are unlikely to see in new systems, but you might run into on older systems. You might also see software or hardware that emulates them.

I've also listed a few things as "nice-to-have". These are not necessarily a minimum requirement to meet general employer expectations, but are nice to have in addition.

Software

  • Programming languages
    • C: currently the primary embedded systems programming language.
      • MISRA (Motor Industry Software Reliability Association) C subset.
    • Assembly language: at least a reading ability. This tends to be used much less frequently in modern development, but there are still small modules written in assembly, and there are times in a debugger when you need to read disassembled code or step through code at machine instruction level.
    • C++: nice-to-have, growing in popularity for embedded systems development.
    • Python: nice-to-have for general tools and support for development.
  • Numbers
    • Numeric type representations
    • Bit manipulation
    • Binary and hexadecimal numeracy
  • DSA (Data Structures and Algorithms)
    • Analysis of algorithms (Big-O notation for time and memory complexity)
    • Basic storage structures
      • Lists
      • Queues
      • Stacks
      • Trees (of various types)
      • Hash tables
      • Graphs (of various types)
    • Basic algorithms
      • List traversal
      • Tree traversal/search
        • DFS (Depth First Search)
        • BFS (Breadth First Search)
  • OOP (Object-Oriented Programming): no matter what language you use, OOP principles are helpful in software architecture, design, and coding. C++ provides direct support for OOP, but many OOP principles can also be applied in C.
  • Design patterns
  • Memory management
    • Static
    • Stack
    • Dynamic (heap): this may be completely prohibited in an embedded system, or limited to only initialization allocation with no freeing.
  • Data communications
    • OSI (Open Systems Interconnect) model
    • Protocol stacks
      • TCP/IP (Transmission Control Protocol/Internet Protocol)
    • Security and integrity
      • TLS (Transport Layer Security)
      • CRC-32 (Cyclic Redundancy Check)
      • Fletcher 32 checksum
    • Communications technologies: this list evolves rapidly, so it's hard to know them all; pick a few and learn about them to prepare for others. You'll need to learn about both hardware capabilities and software protocol stacks.
      • Serial
      • USB
      • Ethernet
      • WiFi
      • Bluetooth
      • Zigbee
      • Cellular
  • Security
    • Basic cryptography
      • Symmetric cryptography
      • Asymmetric cryptography
      • PKC (Public Key Cryptography)
      • Cryptographic hashing
    • Encryption/decryption
    • Authentication
    • Digital signatures
  • Embedded system behavior and support
    • Bootloader
    • FSM (Finite State Machine) event-driven/reactive
    • Feedback loops
    • Classic control theory
    • PID (Proportional/Integral/Differential) control. This involves summing small differences at a time and calculating small differences at a time, the very fundamental of applied calculus integration and differentiation.
    • Flash filesystems
    • BSP (Board Support Package)
    • CLI (Command Line Interface)
    • GUI (Graphical User Interface)
    • DMA (Direct Memory Access)
    • Switch debounce
  • Runtime models
    • Bare metal superloop
    • Interrupts
    • Concurrency
      • Critical sections
    • RTOS (Real-Time Operating System)
      • Threads/tasks
      • Concurrency mechanisms
        • Semaphore
        • Mutex
        • Event flag
        • Message queue
      • Specific commercial and open-source RTOS's and their internals and support tools. Like communications technologies, pick a couple to learn about in detail. Understand their configuration and build systems, driver model, thread/task model, concurrency mechanisms, differentiation between kernel and userspace and other privilege and security models, system libraries, BSP's, etc.
        • FreeRTOS
        • ThreadX
        • QNX
        • Micrium OS
        • embOS
        • VxWorks
        • Zephyr
        • Embedded Linux
  • Signal processing
    • Sampling and quantization
    • Digital audio
    • Digital video

Hardware

  • Basic electronics
    • Basic circuit theory
    • Discrete components
    • IC's (Integrated Circuits)
    • Memory
      • Volatile memory: memory that loses it contents when powered off.
      • NVM (Non-Volatile Memory): memory that retains its contents when powered off, possibly via the use of battery-backup.
      • RAM (Random Access Memory): in normal usage refers to read/write memory, typically volatile, but may also be non-volatile with battery backup.
        • DRAM (Dynamic RAM)
        • SRAM (Static RAM)
      • ROM (Read-Only Memory): non-volatile memory. Plain ROM is mask-programmed (i.e. is programmed by the memory cell mask used during chip manufacturing).
        • PROM (Programmable ROM): one-time programmable by burning fuse bits.
        • EPROM (Erasable Programmable ROM): erasable by exposure to ultraviolet light through window in top of package to allow reprogramming.
        • EEPROM (Electrically-Erasable Programmable ROM): in-circuit erasable by programming signal.
      • Flash: fast, high-density EEPROM.
    • Buses
      • Multiplexing
    • Measurement and test
      • DMM (Digital Multi-Meter)
      • Logic analyzer
      • Protocol analyzer (i.e. communications data/packet capture)
      • Oscilloscope
    • Sensors
      • Switches of a variety of types
      • Light sensor
      • Temperature/humidity/barometric sensor
      • Accelerometer
      • Audio sensor (i.e. microphone)
      • RTC (Real-Time Clock)
      • Hall-effect sensor
    • LED's and displays
    • Motors and actuators
      • Basic motors
      • Stepper motor
      • Servo motor
      • H-bridge
    • Breadboarding
    • Soldering and board assembly
  • CPU (Central Processing Unit) architecture
    • ALU (Arithmetic Logic Unit)
    • System clock
    • Registers
    • Memory access
    • Buses
      • Address
      • Data
    • Caches
      • Instruction
      • Data
    • Instruction fetch/decode/execution cycle
    • Harvard vs. von Neumann architecture
  • MCU (Microcontroller) architecture
    • CPU
    • RAM
    • ROM
    • Flash
    • Peripherals
      • GPIO
      • UART
      • SPI
      • I2C
      • ADC
      • DAC
      • PWM
  • Communications modems and hardware
  • Debug interfaces
    • JTAG
    • SWD
  • Board architecture
    • Power supply and distribution
    • Signal distribution
    • Measurement and test points

Software Development Tools And Processes

  • Toolchains
    • Compilers
    • Linkers
    • Program loaders/flash programmers
    • Debuggers
  • Build systems
    • make
    • CMake
  • IDE (Integrated Development Environment): for embedded systems, these typically combine all the above tools to allow you to write code, build executable images, load them on the target device (i.e. flash the program on the target), and run it via debugger.
  • SCM (Source Control Management) systems
    • Git
  • Diagramming and modeling
    • UML (Unified Modeling Language)
  • Test systems
    • Unit Testing: running small portions of code in standalone tests off-target (i.e. on your development system, not on the target hardware). My preferred method is Test-Driven Development (TDD), in which you create the unit tests and the code being tested at the same time; see Acceptance Tests vs. TDD for more information.
    • HIL (Hardware In the Loop): running code on-target (i.e. on the target hardware, or some version of it, such as a development kit), but simulating external hardware behavior and electrical interactions with test hardware in the system sense/decide/act feedback loop.

Resources

I have several posts that outline resources and study recommendations. Where this post is the skills-based perspective, those are the resource-based perspective, the yin to this yang.

For a really great interactive way to learn assembly language, see Compiler Explorer. You can enter in C or C++ code (and other languages), select which compiler you want (such as ARM GCC for ARM-core targets), then instantly see the resulting assembly code generated from the source. Armed with a reference manual for the target CPU architecture, you can see how high-level language constructs translate to assembly language.

You can use a similar method with a debugger running your code on the target, where you look at simultaneous source code and assembly language views as you step through the code at either level. Then you can also observe register effects.



To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Please login (on the right) if you already have an account on this platform.

Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: