mJS is a new approach to embedded scripting and developing for IoT

A new approach to embedded scripting and developing for IoT with mJS

How can you develop without a standard library or glue code?

Person programming on a laptop on a building
Image credits : 

Image from Unsplash.com, Creative Commons Zero 


Subscribe now

Get the highlights in your inbox every week.

In my previous article, I talked about IoT (Internet of Things) and connecting physical objects ("things") to the internet. I've discussed how Mongoose OS, an open source operating system for IoT, makes programming microcontrollers in JavaScript easy for both newbies and professional developers.

You may have wondered why is it JavaScript and how a JavaScript engine fits into the limited memory on a microcontroller. There are many projects out there that aim to put scripting on microcontrollers, and that includes other JavaScript projects, including Duktape, Espruino, Jerryscript, MuJS, and V7. There are also other scripting languages, such as  MicroPython and Lua.

One common thing these projects share is an attempt to implement the entire language specification together with the complete standard library. There are pros and cons. The pros are obvious, but what are the cons?

The cons

First, none of the popular scripting languages have been designed for the embedded environment in the first place. They drag along some obscure constructs that take precious space but have very little practical usage in the embedded context.

Second, to export a hardware-specific functionality into the scripting environment (such as a certain sensor API or a certain LCD display API) you'll need to write a glue code. And you'll need to maintain that glue code, which takes up precious space and increases overall complexity.

To address these issues a new JavaScript engine was introduced.


mJS is a part of Mongoose OS and takes a radically different approach:

  1. It does not implement the entire language, but a limited subset.
  2. It has no standard library.
  3. It has no glue code.

These features make mJS fit into ~25K of flash space and less than 1K of RAM. That is hard to beat. But how can you develop without a standard library and without any glue code? The mJS's answer is by having an ability to call C SDK (Software Developers Kit) functions directly.

How to call C SDK functions directly

Foreign Function Interface (FFI) has the ability to load and call C functions directly. To do these steps, mJS has to know two things: an address of the C function and a signature of the C function. Then it marshals JavaScript arguments into C values, puts them to where the ABI (Application Binary Interface) demands—for example, on the CPU stack—and jumps to the function's address. Practically, it looks like this:

let f = ffi('int gpio_write(int, int)');   f(2, 1);   

This snippet loads a C SDK function gpio_write(int pin, int value) and calls it, setting GPIO pin 2 to the high-voltage level. That's all. Need other functionality from the SDK or a third-party library? Just load it on demand. You can even do things like:

let malloc = ffi('void *malloc(int)');   let mem = malloc(10);

Not saying that you should, but you can. Also, you can marshal C callbacks:

let Timer = {     set: ffi('void timer(int, void (*)(int, userdata), userdata)') };  Timer.set(100, function(time) {     print('Time now: ', time); }, true);

Do you need an embedding API? No, you don't. You don't need any glue code either. And also you don't need a standard library.

See how mJS is used in our Mongoose OS example firmware. And you can use it with any C/C++ software, such as with specific firmware. For a more in-depth introduction, see the mJS GitHub repo for the embedding example.

Ask questions on our developer forum or send us a message.


About the author

Sergey Lyubka, Cesanta Co-Founder & CTO
Sergey Lyubka - Sergey Lyubka is CTO and Co-Founder of Cesanta. Together with his team, he aims to bring all products online by developing innovative Internet of Things technologies. He believes that if we want to get to 20 billion+ connected devices by 2020, then IoT connectivity needs to be made simple, secure and scalable. Through Mongoose OS he realises this vision. Before starting Cesanta, Sergey already developed one of the most popular embedded web servers - Mongoose. He ensured that it grew for a...