Over the past few years, the number of programming languages used for embedded development has started to balloon. Developers have available to them languages such as Assembly, C, C++, Python, MicroPython, Java, and Rust. (There are even tools available that can be used to model applications and generate the code for developers). For new projects, what programming language should embedded developers be using? This post will explore several recommendations for selecting the correct programming language for embedded developers.
Recommendation #1 – Avoid Dead or Dying Languages
Over time, programming languages fall out of popularity; it’s inevitable. New methods for doing things are invented. New languages are invented to solve the programming problems of the day. The once commonly used languages fade away and are replaced by something new. An exciting tool I like to track language popularity is the TIOBE Index. The TIOBE Index has been following the popularity of programming languages across the software industry since 2002. I mention this because it’s all languages, not just embedded languages.
Examining the index, it’s interesting to see the rankings of different languages that are used in embedded systems:
- Python (#1)
- C (#2)
- Java (#3)
- C++ (#4)
- Assembly (#8)
- Matlab (#16)
- Rust (#26)
- Labview (#41)
Note that assembly languages are the 8th most popular programming languages globally! However, how many people do you know who actively write applications in assembly language? For the most part, assembly languages are dead. Sure, we occasionally write assembly to optimize some function, but we aren’t day-in-and-day-out writing assembly language. So make sure that you are selecting a language that isn’t already dead or in the process of fading away.
Recommendation #2 – Select Object-Oriented Languages
Nearly every system today can be described in a data-driven, object-oriented architecture. I believe that many embedded systems naturally fall into this design paradigm, and there is no need to torture our designs to get them there. However, selecting a programming language that supports object-oriented programming concepts is critical to building scalable and reusable software systems.
When we look at our list of programming languages for embedded systems, we’ll notice a slight problem with our top five languages; C and assembly are not object-oriented languages! I would argue that is one reason why we should consider both to be dead or dying languages. They don’t provide the modern toolset that developers need to implement a modern software architecture. In addition, these languages require a lot of extra work to get capabilities that are naturally built into other languages.
Recommendation #3 – Use Standardized Languages Only
Someone who is building a commercial product that must be maintained and updated over the years should not be rolling the dice with a language that is not standardized unless they can afford the technical debt associated with constantly upgrading their software. Before a language is standardized, like Rust, the specification for the language is in flux. It’s continually changing as the language evolves and the best ways to do things are identified. This means that you might use one compiler and get result A, then use another compiler and get result B. Same language, different results, all because the language is not standardized!
As exciting as a new language can be, it makes sense to use a standardized language for most businesses. I would argue that it makes sense to use a language with standards and actively update those standards to evolve the language and its capabilities. Another reason why I feel C is dead is that its standards change so slowly, and the improvements made are more like bug fixes than feature additions.
Languages like C++ are a good option. C++ has a well-defined standard, and the standard is updated every three years. As a result, developers are provided with new techniques and features to improve their software, making the language live. It also provides a consistent standard so that teams don’t have to take on the technical debt of change if they don’t want to. Instead, they keep using the standard version that they adopted.
Recommendation #4 – Balance the Languages Run-time Weight
We might decide from the previous recommendations that Python, Java, and C++ are the embedded languages of choice. Perhaps we should all run out right now and start to convert our applications to Python; However, so far, we have not yet discussed the whole story. A critical consideration for teams is the run-time weight of their language.
If you were to examine C/C++, you’d discover that the code size required to run a C application is well under one kilobyte. The overhead to run the code is also negligible to non-existent. C/C++ has a light run-time weight. If you were to examine Python or MicroPython, you’d discover that this is not the case. The MicroPython interpreter generally builds to between 300 – 400 kilobytes! The overhead to run the interpreter is relatively light, but the weight of the interpreter is quite high.
A heavy-weighted run-time may not be a big deal if the cost for memory is considered cheap or not of significant concern. In these circumstances, using a language like MicroPython can come with many advantages. For example, nearly everyone knows Python or can learn it quite quickly. In addition, it’s adaptable and has more coding standards than one could ever dream about. Upgrading application code can also be as quick as updating a few scripting modules.
In either case, teams should carefully consider the overhead associated with the language they choose. For example, python, Java, Labview, and others may have a higher run-time cost than other languages.
Recommendation #5 – Use the Language that is Right for You
At the end of the day, you, the team, need to decide what features and language best fit your needs. For example, if the entire industry is moving to Python, but assembly language makes more sense because you provide hand-optimized libraries, then choose assembly language. On the other hand, if you have a bunch of legacy code written in C and want to continue to leverage that already existing asset, then use C. (Or wrap your C code and use C++!).
Don’t let the language fads of our day convince you to change. Instead, use what makes sense and consider the recommendations that we’ve discussed in this article.
Embedded developers and teams do have a rich choice of programming languages that they can use to develop their embedded software. The languages they choose will depend on the type of software they write, the needs of their company, and the technical debt they incur in maintaining their code. When selecting a language to use, the recommendations in this article should provide some additional thoughts to consider. C/C++, particularly C++, can be a great default when in doubt.
Jacob Beningo is an embedded software consultant who works with clients in more than a dozen countries. He has published many blogs to count embedded software architecture, processes, and development techniques. He holds three degrees, including a Master of Engineering from the University of Michigan. Feel free to contact him at [email protected], at his website www.beningo.com, and sign-up for his monthly Embedded Bytes Newsletter.