Embedded Ada on an AVR Microcontroller: Introduction

4 minute read

Where I begin to explore using Ada on an Arduino Uno.

Introduction

On the Adafruit site, I ran across a mention of an award as to an “Ada Crate on an AVR” microcontroller. Which I found fascinating. Ada is a language developed for larger computers and wasn’t something I would expect to fit on to the AVR-series of microcontrollers.

This led me down a path of attempting to understand:

  1. What is Ada as it relates to microcontrollers?
  2. Is there value to using Ada on a microcontroller as compared to C?
  3. How do I do so?

This post describes my journey and how to begin to develop in Ada on an Arduino Uno or AVR ATmega328P

The Award

As I stated above, the first time I had heard of using Ada on microcontroller was via this post. In the post, it described the work Rolf Ebert had done to make this happen. “AVR-Ada is one of the first, if not the first, open-source low level embedded Ada projects. Rolf, who has been leading the project since the beginning, has now adapted it to the Alire workflow. The result is a collection of crates covering the run-times, access to peripherals, and common features such as time keeping or string manipulation.”

I continued to research Ada on embedded processors and ran across this great site as to learning Ada, Learn Adacore.com. From there, I started reading Introduction to Embedded Systems Programming. While reading “Intro…”, it became clear I needed more information as to how to implement a toolchain for developing Ada on the Arduino Uno. For it is difficult to understand and use the examples shown, unless you have the ability to run them yourself.

More research led me to a couple of older pages:

Which I’ll review as I continue to develop in Ada. The most important page, I came to was Alire - Docs which was the application referenced in Rolf’s github site. By going to the section as to “How to Install on macOS”, I was able to make progress on installing a tool chain.

Installing the Tool Chain

The instructions on the site work quite well for macOS:

  1. Download the archive and unzip it.
  2. Copy it to a preferred executable location
  3. Make a change required by macOS for security (either use xattr or right-click on the application in the bin folder, and click open.).

I completed the steps above and typed alr and I was ready to go! Back to Rolf’s site, AVRAda_Examples getting started.

Getting Started

Rolf’s information was very good. I did need to make some specific changes in the Makefile to have it work with my setup:

  1. Make sure you have an Arduino Uno with a optiboot loaded. (If you’ve been using the Arduino IDE to upload to your Uno, you are good to go.)
  2. Once in avrada_examples/delays, run alr update. This ran without issues.
  3. In delays/makefile, I made the following changes:
    # line 59
    AVRDUDE_PROGRAMMER = stk500v1 -b 57600
    # to
    AVRDUDE_PROGRAMMER = arduino -b 115200
    # line 63
    AVRDUDE_PORT = /dev/ttyUSB1
    # to
    AVRDUDE_PORT = /dev/cu.usbmodem14101
    # line 81
    AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
    # to
    AVRDUDE_FLAGS = -p atmega328p -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
    

The first two changes are mandatory as you will need to customize the makefile to your specific AVR programming environment. The last change is something which should be handled properly by the makefile, however, it wasn’t working for me. My change manually sets the CPU to be the ATmega328P.

Continuing to follow the instructions, I ran make and then make blink_busy.prog. Which uploaded a 250 byte program to the Uno. (As a comparison, a similar simple C program), the C program was 176 bytes.) Success! I now have a blinking led on the Uno, courtesy of Ada!

Learning Ada

The Ada program is this:

--  get a delay by active waiting, no need for a timer or the clock

with LED;
with AVR;
with AVR.Wait;
with Avrada_Rts_Config;

procedure Blink_Busy is
   procedure Wait_1_Sec is new
     AVR.Wait.Generic_Wait_USecs (Avrada_Rts_Config.Clock_Frequency,
                                  500_000_000);
begin
   LED.Init;
   loop
      LED.Off_1;
      Wait_1_Sec;
      LED.On_1;
      Wait_1_Sec;
   end loop;
end Blink_Busy;

As one would expect, if you adjust the number 1_000_000 in AVR.Wait.Generic_Wait_USecs than you will change the time between blinks. Increase it to 2_000_000 and the time doubles and decrease to 500_000, and the time is half of the original. No surprise there. This is also known as a blocking delay as in delay(ms) in C.

All that said, there rest of the code, while clear as to what it does, isn’t clear as to why its there. I’m going back to read Introduction to Ada to learn a bit more then return to this and other posts on Ada on the AVR.

Comments powered by Talkyard.