Dynamic Languages on Embedded

At ThingForward, we’re looking at embedded programming from a multilingual perspective, inspired by and with the background of multiple years of web development. Programming for embedded is truly different: Very close to the hardware, with very limited capabilities, with no operating system or very slim OS functionality. If you want to use dynamic languages on small devices, where could you look?

C and C++

First, let’s look at some features of C with regards to embedded programming. Its code is of course compiled and thus quite compact - Constrained devices often come with very limited amount of flash memory, where program code can reside, so having smaller code (in terms of compiled code size) equals to using a smaller (and cheaper) MCU. Most recent programming languages have dynamic memory management. That is, if you need memory, say 1KB for a buffer to process a HTTP Request, you allocate it, use it and later deallocate it. Many languages come with garbage collection, so you don’t even need to deallocate, it’s automatically done for you.
This is not the case with C. Developers have to make sure to free everything they’d malloc’d Embedded firmware in C can even go further. If the embedded development framework or OS does not come with a library for dynamic allocation of memory, the developer is left with a static memory model. This means that all memory that is needed has to be statically allocated at compile time in arrays, structs and so on. Which has cons but also pros, since you cannot run out of memory :)

C as a programming language can be hard - many frameworks for embedded now rely on C++. Examples of this are the Arduino Development Framework, or ARM mbed OS. Coding with these is more fun, since C++ can offer a lot of abstractions which make code look cleaner. Though C++ also comes with a cost. Features such as inheritance with virtual function need internal function tables, which need additional memory, and dynamic memory can be challenging in embedded environments. As MCUs grow in capabilities regarding processing power and memory, using C++ with a well-tested RTOS is a good choice.

Scripting for IoT?

Quite a few of the well-known web development languages are scripting languages: PHP, Python, Ruby, Javascript. Where Javascript may run on the server side as well as in browsers, the others run on servers, where code is hidden to the outside world (well, in most cases ;) Thus, runtimes on the server side may choose to optimize or precompile the code, which leads to multiple „universes“ of optimized toolchains (i.e. Rubinius as a byte code compiler for Ruby code). What about embedded devices, are they capable enough to run scripting languages? Yes, some of them are! We’re not going in detail here, but we have two upcoming blog posts that will tell you all you need to know. For now let’s briefly look at two scripting languages for embedded: MicroPython and JerryScript, a lightweight javascript engine.

MicroPython

MicroPython is essentially “python for embedded“, a stripped-down version of Python’s standard library that is able to run on devices with at least 256k of code space and 16k of RAM. This limits the number of microcontrollers that can be used for running MicroPython, typically 32bit MCUs with ARM-Cortex M or Espressif Systems’ ESP8266/ESP32. The MicroPython firmware is coded in C and includes the compiler and runtime. It also has the well-known REPL-Shell (for read, evaluate, print - loop), so that you can dynamically type in python commands to be executed. But most important are the built-in libraries and the functionality it supports out-of-the box. First, it’s a subset of Python 3, so you cannot expect to have the full extent of functions available as on your desktop or server installation of python. Many regular libraries have „micro“-replacements, which offer a subset of functionality (which makes sense for embedded devices). The ability to handle json data is really nice for exchanging data with other devices and services. Some libraries are specific to MicroPython, especially where they make sense for embedded boards. One example of this is „machine“, a library to deal with GPIO, interrupts and sleep mode. Vendors such as Zerynth offer additional libraries on top of that, for example regarding (industrial) sensors, cloud backends or protocols such as MQTT.

Javascript

Interestingly, the idea of javascript for embedded has been around for quite some time. There are several implementations and approaches, such as Espruino, Node.js for Embedded, MongooseOS or JerryScript. What Javascript “owns“ (in a way) even more than Python is the idea of internet-scale distribution and communication: Support for JSON, Networking protocols such as HTTP and WebSockets and more. We’d like to take a closer look at JerryScript. As stated on their website, JerryScript is suitable for constrained devices with 64k RAM and 200k code space. It is programmed in C, and offers a C API for combining C and JS code on a device. That means that it can be combined with existing firmware code to make parts of it more dynamic. What’s really interesting are development environments that run on top of this Javascript/JerryScript foundation. One example of this is IoT.js, which offers additional modules such as HTTP and thus makes programming device communication easier. This “Javascript for Embedded“ space looks a bit more fragmented than that for Python, but active development is a good indicator for progress as well.

Conclusion

We think that as of now, most professional development on constrained devices will be done with C or C++, as the tooling support is great and the knowledge about building robust firmware is widespread. With IoT, more demands are coming up: Connectivity, device intercommunication, dynamic device behaviour just to name a few. And that’s where in our opinion a look at other languages and development frameworks can be helpful, because they already ship with these modern features.

We’re looking forward to our next blog post, where we look at Zerynth and their Python-based solutions for embedded development. Stay tuned!

Your ThingForward team

Next: Getting started with Python on Embedded - and Zerynth