AdaCore Blog

Ada on the ESP8266

by Johannes Kliemann

The ESP8266 micro con­troller by Espres­sif Sys­tems is one of the cheap­est MCUs that sup­port WiFi. This makes it a pop­u­lar device for wire­less IoT appli­ca­tions. It is based on the con­fig­urable Ten­sil­i­ca Xten­sa archi­tec­ture that is also used in dig­i­tal sig­nal proces­sors. The main pro­gram­ming lan­guage for this con­troller is C. This is large­ly due to the fact that the lim­it­ed set of tool­chains is based on old GCC ver­sions. Except for an exper­i­men­tal cus­tom GCC 5 there was vir­tu­al­ly no com­pil­er sup­port for Ada on this platform.

Build­ing an Ada com­pil­er for Xten­sa #

Not long ago, Ada­Core pub­lished its LLVM fron­tend for GNAT. Also quite recent­ly Espres­sif updat­ed their LLVM back­end to LLVM 9 which also hap­pens to be the LLVM ver­sion of GNAT. This gave me to the idea to try out if LLVMs promise of pro­vid­ing mod­u­lar and reusable tool­chain tech­nolo­gies is true.

To test if I was able to build a cus­tom com­pil­er I cre­at­ed a fork of Ada­Cores LLVM fron­tend and switched the orig­i­nal back­end with the one pro­vid­ed by Espres­sif. After some tin­ker­ing with build options, ver­sions and include paths I was able to build a com­pil­er that was able to com­pile bina­ries for both X86 and Xten­sa. Run­ning the fol­low­ing com­mand cre­ates an object file that can be linked into an exist­ing bina­ry and exe­cut­ed on an ESP8266:

$ llvm-gnatmake -c unit.adb -cargs --target=xtensa -mcpu=esp8266

Run­ning Ada code on the tar­get #

With this com­pil­er we can cre­ate object files that will run on the 32bit Xten­sa archi­tec­ture for either the ESP8266 or the ESP32. But object files alone don’t run on the tar­get so we have to cre­ate a bina­ry first. For a pure Ada appli­ca­tion that runs on bare met­al, we would have to imple­ment a set of dri­vers from the chipset spec­i­fi­ca­tion in Ada. How­ev­er, to show that Ada code com­piled into an object file can run on this chip it is suf­fi­cient to link it against an exist­ing SDK that already con­tains all the sup­port and start­up code.

Choos­ing an SDK #

There are mul­ti­ple SDKs avail­able for the ESP8266, the ESP8266_RTOS_SDK by Espres­sif, the esp-open-sdk which focus­es on the use of only free soft­ware and the ESP8266 core for Arduino which pro­vides sup­port for the Arduino IDE. All of these bring their own tool­chain and have it inte­grat­ed into their build sys­tems. This makes it dif­fi­cult to add new lan­guages which require cus­tom compilers.

I’ve cho­sen the Arduino SDK as the Arduino envi­ron­ment allows it to include pre­built sta­t­ic libraries. To install the ESP8266 SDK for Arduino I rec­om­mend fol­low­ing the instruc­tions in the README of the project.

Run­ning it on the device #

I pre­pared a small exam­ple that prints on the ser­i­al con­sole. To com­pile it clone it into the libraries fold­er of your Arduino instal­la­tion and com­pile it there. The GNAT LLVM bina­ries have to be in the PATH envi­ron­ment. These can either be com­piled as described in the README or sim­ply down­load the pre­com­piled bina­ries. Be aware that build­ing the com­pil­er your­self might require sig­nif­i­cant amounts of RAM and take a long time.

$ cd /path/to/Arduino/libraries
$ git clone --recursive https://github.com/jklmnn/esp8266-ada-example.git
$ cd esp8266-ada-example
$ make

These steps will install the exam­ple and an Ada run­time into the Arduino libraries. The run­time is the Com­pono­lit ada-run­time which has sup­port for the ESP8266 on Arduino. It also pro­vides a log­ging facil­i­ty that prints onto the ser­i­al line.

An Arduino sketch to open the exam­ple is in the cloned repos­i­to­ry in esp8266-ada-example/esp8266-ada-example.ino When both the exam­ple and the run­time have been built this sketch can be built and flashed direct­ly from the IDE. I have test­ed this with the LiLon NodeM­CU V3 and the WeMos D1 mini boards but it should work on every board as it used the on chip ser­i­al capa­bil­i­ties. After con­nect­ing to the ser­i­al port opened by the device one should see that it prints Make with Ada!” in an end­less loop.

$ screen /dev/ttyUSB0 115200
Make with Ada!
Make with Ada!
Make with Ada!
Make with Ada!

Out­look #

This arti­cle describes a proof of con­cept to run Ada on a new plat­form using GNATs nov­el LLVM back­end. To use it pro­duc­tive­ly the Ada lan­guage needs to be sup­port­ed in the Arduino envi­ron­ment which cur­rent­ly is not the case. Fur­ther­more the cur­rent approach includes bina­ry blobs from the man­u­fac­tur­er as well as dri­vers writ­ten in C from the Arduino environment.

A more inter­est­ing, although far more chal­leng­ing, task would be an SDK pure­ly in Ada or even SPARK which would enable the cre­ation of secure embed­ded and WiFi-enabled devices.

Posted in

About Johannes Kliemann

Johannes Kliemann

Johannes Kliemann is security architect at Componolit. He specialized in industrial automation and systems architecture and is interested in formal verification, operating systems development and embedded devices.