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 a cross and embedded engineer at AdaCore. He specializes in systems architecture and security and is interested in formal verification, operating systems development and embedded devices.