Embedded Ada on an AVR Microcontroller: Introduction
Where I begin to explore using Ada on an Arduino Uno.
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:
- What is Ada as it relates to microcontrollers?
- Is there value to using Ada on a microcontroller as compared to C?
- 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
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:
- Download the archive and unzip it.
- Copy it to a preferred executable location
- 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.
Rolf’s information was very good. I did need to make some specific changes in the Makefile to have it work with my setup:
- 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.)
- Once in avrada_examples/delays, run alr update. This ran without issues.
- 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!
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.