Author: Tom Radcliffe
The C/C++ programming languages dominate embedded systems programming, though they have a number of disadvantages. Python, on the other hand, has many strengths that make it a great language for embedded systems. Let’s look at the pros and cons of each, and why you should consider Python for embedded programming.
C/C++ are compiled languages, while Python is an interpreted language. C/C++ have been around for ages; C was first developed in 1969, and C++ came along in 1983. Python is younger as it was created in 1989 by Guido van Rossum. Since then, it’s become one of the most popular open source programming languages. All Python releases are open source and freely usable and distributable, even for commercial projects. (If you’re looking for commercial- grade support and indemnification, distributions like ActivePython are available.)
The case for Python
Python is the most popular introductory programming language at the top computer science (CS) departments in the United States. According to a study by the Barr Group, eight of the top ten CS departments currently use Python to teach coding. Debate the merits of it if you want, but the simple fact is that the most widely understood language in the hiring pool of recent graduates is Python. It’s dramatically more likely that a recent graduate will understand how to code in Python than in C/C++.
Hobbyist developers are likely to have some experience with Python, and it’s more likely that they’ll be proficient in Python than in C/C++. Since only about 40% of computer software engineers and system analysts have computer science degrees, a lot of industry hires are coming from hobbyist backgrounds. But when it comes to embedded systems, the numbers flip pretty severely. The Barr Group study shows that over 95% of the code for embedded systems is written in C/C++. This legacy on embedded systems might be hard for Python to overcome, but its attributes and the sheer number of people coding in Python might help it overtake C/C++ in the future.
Python isn’t only the most-popular language for introductory CS programs, it’s also the fastest-growing language for embedded computing. Maybe that sounds silly when you scan the numbers again and realize it’s the fastest-growing language of the remaining 5% of embedded systems code that aren’t C/C+ +, but Python will start eating into C/C++’s monopoly even more over the next few years. Hobbyists migrating into the industry with experience programming drones, robots, or other projects frequently have an Arduino or Raspberry Pi background. They’ll likely have dealt with Python on some level in that time, and it’s also likely that they’ll have bumped up against some embedded systems programming.
While C/C++ is slow to write, error prone, and frequently unreadable, Python is known for its writability, error reduction, and readability. The importance of readability can’t be overemphasized: when you’re working in a team, readability is paramount to maintaining the code. It has to be easily decipherable unless you’re willing to shell out more time and money on debugging and quality assurance. The design reuse of Python far outclasses C/C++, and in today’s Agile environments design reuse can be the difference between staying ahead or falling behind the competition.
Embedded algorithms are getting increasingly complex. Simple control loops are being replaced by neural networks and other heavily-involved processes that have helped Python gain its foothold. There are Python libraries like Theano that will optimize Python code for these processes. While Theano is mostly written in C/C++, Python is used to interface with high-performance libraries in a human-friendly way. Python libraries are thriving—PyPI, the Python package index, has over 80,000 modules, and these massive compendiums dramatically increase the productivity of programmers by giving them the option to skip a few steps and use already-established functions in their own code.
The case for C/C++
The case for C/C++ is pretty obvious: it creates more compact and faster runtime code, and it’s already the language of choice for 95% of embedded system code, so it has a whole legacy that Python will have to overcome. When it comes to speed, however, runtime speed isn’t the only aspect of development to consider—you also have to consider development speed. While Python may be less efficient than C/C++ at runtime, during development it’s much more efficient. Interpreters read each line of code, parse it, do runtime checks and call routines in order to execute the operations in the code. This is a lot more activity than what you get from running C/C++ code, where the same line of code might be compiled into just a couple of instructions. This can lead to slower runtime speeds and higher energy consumption with Python.
Improving Python’s speed
So the main case against Python versus C/C++ is its runtime speed, but there are several ways to optimize the code so it runs more efficiently. Aside from libraries like Theano, there are optimizing extensions for Python like Cython, which is essentially Python with static typing and keywords to run math more quickly. Because Cython is statically typed, you can easily compile to C/C++ and run at C/C++ speeds.
Just-In-Time (JIT) compilers are another good way to improve Python’s runtime speed. These compilers work in parallel with Python’s interpreter to generate compiled machine instructions for code inside loops. This allows subsequent passes by the interpreter to execute faster. The PyPy JIT compiler is able to increase Python’s execution speed by nearly a factor of two. JIT compilers should only be used if there’s enough space, though, and embedded systems don’t usually have a lot of that to spare. The best optimization is to use better data structures and algorithms, but this is the hardest task in software design and implementation, so it might be best to utilize one of the tools above, depending on your skill level.
Using Python to communicate with embedded systems
Python might be at its strongest when used as a communication middleman between the user and the embedded system they’re working with. Sending messages through Python to or from an embedded system allows the user to automate testing. Python scripts can put the system into different states, set configurations, and test all sorts of real-world use cases. Python can also be used to receive embedded system data that can be stored for analysis. Programmers can then use Python to develop parameters and other methods of analyzing that data.
Currently the main debate about the merits of Python and C/C++ comes down to what’s more important to your team: development speed or runtime speed. In the future, though, it might not be up to Python programmers to make their case for its use in embedded systems, but rather for embedded systems designers to figure out how to accommodate the relentlessly increasing popularity of Python.