Make with Ada: Redux

The end of Make with Ada is upon us. I wanted to take a moment to summarize my experience.

I had no previous experience with Ada. I'd heard whispers of Ada in the context of “a language built for reliability, mainly used in defense applications”. I heard about Make with Ada and AdaCore when [Fabien Chouteau (https://github.com/Fabien-Chouteau) was a guest on [Embedded.fm (http://embedded.fm/episodes/158). I was really impressed with Fabien and after recalling a [previous challenge (http://www.ganssle.com/rants/ada.htm) by Jack Ganssle (am I intellectually lazy?); I decided that I should attempt something.

My Ada Development Environment

I was able to reuse much of my existing GCC (C, C++) programming / debugging workflow. I used GNAT GPL 2016 as my Ada compiler. Being part of the GNU Compiler Collection allowed me to get up to speed quickly. The GNAT compiler flags are quite unlike gcc; but it really helped that I was already proficient in binutils (gas, linker, &c) and it was easy to reuse startup code written in C.

My debug tap for this project was my ST-Linkv2 + OpenOCD. It's all of 20 USD and has proven to be fast and reliable supporting SWD and JTAG on my ARM projects. The OpenOCD GDB server is getting quite good, but I didn't need it all that much as it turns out.

I chose to develop my project using the Nordic Semiconductor nRF51822 SoC. It's an inexpensive Cortex-M0 part w/ integrated 2.4GHz Radio. It opens several wireless options for IoT projects (BLE, nRF24L01, Ant (via the xx422 part). I used a custom development board based on [my previous open source hardware design (https://github.com/nocko/nRF51-devel).

All in all, the barrier to entry for embedded Ada development was very small. If you're already an embedded software engineer then you likely won't need any additional equipment.

My Ada Experience

I found Ada to be delightful.

Ada allows for describing intention in a way that is not possible in C. Since the compiler knows a lot more about what's going on in my brain it's quite a bit better a flagging problems in my design (rather than catching typos ala C compilers).

I was able to become productive in Ada in about 8 hrs (starting from zero experience). I'd estimate that I spent on the order of 30hrs. in total on Ada including:

Full disclosure: I am not a genius. I've been programming C (off and on) for twenty years. I've implemented similar beacons on the same SoC using C and correcting for differing feature sets:

Developing the beacon in Ada (a language I don't know well) took roughly the same time as the similar functionality in C and I have more confidence in the Ada code

For me it came down to a few factors:

I've done a fair amount of work in Python, so I found the block notation and indentation to be comfortable immediately. Unlike Python, Ada retains semicolons as statement delimiters makes me all warm and fuzzy.

In C, I've acquired the bad habit of writing code and interface at the same time in .c files and back-filling header files when my compiler complains. I could have always done this better in C, but the context switch to Ada allowed me to see the advantage clearly.

I've run external linters and static analysis tools in my VCS commit hooks for ages, but there are 90 ways to write C and a thousand tools... having the compiler express strong opinions and enforce them at compile time saved me time. From syntax checking to style checking; I didn't find my self needing to spend time search out good tooling to start writing decent code. I imagine that when working on a team, it's easier to agree on (and enforce) a list of compiler flags than a whole ecosystem of tools.

It's a part of the GCC. This is perhaps a downside for some embedded engineers... but I enjoy working with GCC. It's consistent, available on nearly every platform, well maintained, and free. With GNAT, I only needed to add a single tool to my development ecosystem to get started on Ada.

Once I convinced GNAT of my intentions on with some pretty intense compiler flags (-gnatg -gnatp -gnatn2 -gnatwa -gnatQ -gnatw.X); my software tended to Just Work™.

My Make with Ada Project: Bluetooth Beacons

Have I met my project goals? As expressed in my Make with Ada project application: “... I want to play with the 2.4GHz radio. Initial low hanging fruit is iBeacon, followed by Eddystone-EID”

I did implement iBeacon. It runs and broadcasts compliant packets. It's not production quality code, but an interesting proof of concept. Much of the Eddystone standard could be implement by changing changing the single record and/or updating it dynamically at runtime.

Eddystone-EID was too much a reach given my time constraints. EID would require implementing a few cryptography modes (CMAC,CTR) or the nRF51 ECB peripheral. I thought briefly about linking against my existing nRF51 crypto library... but if there are 200 lines of Ada and 1000 lines of C is it still making with Ada?

I landed a new client with an extremely aggressive timeline a few weeks after I joined Make with Ada. Ultimately I couldn't dedicate more than the initial 30hrs; but I am excited to do more.

Ada: My Next Steps

  1. Remove my peripheral drivers from the nRF51 ZFP RTS and move the RTS upstream to AdaCore's Embedded Runtimes repo.

  2. Figure out how to contribute the peripheral drivers to the AdaCore Ada Drivers Library

I spent a few hours on this and intended it to be a capstone for my Make with Ada project. Alas, I am still a novice Ada engineer and it's non-obvious how a non-STM32 part could be ported to the HAL (without significant API changes). I thought of a few ideas, but feared striking off on my own and the chances of wasted effort are high. I look forward to talking it through with the AdaCore developers. I believe they could put me on the right path.

  1. Pitch Ada to my Clients

I enjoyed my time working with Ada. It's obvious to me that there are significant advantages of starting new projects in Ada. I'd love to land some work where my client and I could both enjoy the benefits of Ada. Want to hire me?

  1. Investigate Ada Tasking as an alternative cooperative multitasking RTOS.

It's a little pie-in-the-sky; but I think an Ada tasking based Bluetooth low-energy stack for the nRF52 (Cortex-M4 part) would have many appealing qualities and my be formally provable (Spark?). Working with opaque binary blob stacks feels terrible as an engineer.

Ada: Final Thoughts

I've had a lot of fun with Ada. It's hard to believe that this really useful language just hasn't gained traction outside of some traditional silos. I am a convert, but it seem clear that market demands will keep me writing C for a while. I am motivated to change my embedded work to Ada where possible and take a few Ada lessons with me back to C.

Special thanks to Lambourg Jérôme for svd2ada. Svd2ada made writing my peripheral drivers trivially easy. What a great tool.

Thanks also to the #ada community on Freenode for not judging a newbie outsider too harshly.