AdaCore: Build Software that Matters
I Stock 1987307560
Sep 05, 2024

Getting Started with Renode: Simulating an Ada STM32F429disco Blinky Firmware.

I recently watched the talks from the 28th Ada-Europe International Conference on Reliable Software Technologies (AEiC 2024), which was held in Barcelona last June.

One talk that stood out was HiRTOS: a Multicore RTOS Written in SPARK Ada by J. German Rivera. In his presentation, he mentioned running HiRTOS on Renode, an open-source simulation and virtual development framework for complex embedded systems .

Like many, I’ve primarily dabbled with QEMU, but my curiosity led me to explore an intriguing talk by Sean Cross, Renode: Easy CI for your Weird Hardware. He showcased just how easy and powerful Renode is for configuring and simulating complex embedded hardware. The Renode team even assembled a complete graphical simulation—including vector tables, timers, framebuffer, and firmware—within an hour, all while attending a conference talk!

After watching the presentation (at 1.5x speed), I was eager to try something hands-on with Renode. However, after some searching, I found that up-to-date, straightforward guides on using Renode without diving into the source code or extensive documentation took a lot of work.

I previously ported the Ada Driver Library for the Capstone projects I mentor, creating a reproducible Alire build chain for the STM32F429 discovery dev board. With this setup, I quickly built an STM32F429 blinky app firmware directly using Alire. Armed with a coffee and some outdated videos, I took on the challenge of loading and running the firmware ELF in Renode.

Before diving into the details, If you're eager to jump straight into the action, the Renode files needed for this simulation are available in the Renode folder of the stm32_blinky_demo repository. You can simply clone the repo and follow the README.md to build the firmware using Alire and launch it on Renode.

For those who want to dig deeper, the following sections will walk you through the content and setup of the Renode files needed to develop a successful simulation.

The Ada Code

This is your typical "Hello World" for embedded systems, cross-compiled for the ARM Cortex-M4 using the embedded-stm32f429discovery Ada runtime available in Alire:

with Ada.Real_Time; use Ada.Real_Time;
with STM32.Board; use STM32.Board;

procedure STM32_Blinky_Demo is
  Period : constant Time_Span := Milliseconds (1000);
  Next_Release : Time := Clock;
begin
  Initialize_LEDs;
  loop
     Next_Release := Next_Release + Period;
     Toggle_LEDs (All_LEDs);
     delay until Next_Release;
  end loop;
end STM32_Blinky_Demo;

This simple program toggles all LEDs on the STM32F429 discovery board every second. To obtain the ELF binary, just run

$ alr build

Setting Up the Renode Hardware Configuration

Renode is written in C# and can be extended primarily to add new hardware peripherals or configure more complex simulation scenarios. However, Renode also provides its hardware description language and scripting language. The `.repl` (REnode PLatform) files define your hardware configuration. Many existing device descriptions for various development boards and CPUs are included in the Renode distribution, typically found in the platforms/boards and platforms/cpus directories within your Renode installation.

Let’s set up our stm32f429_custom.repl file step by step. A .repl file can include other hardware configurations, so we’ll start by incorporating the STM32 ARM device used on the STM32F429 discovery board, which Renode already provides:

using "platforms/cpus/stm32f429.repl" 

After thoroughly searching the Renode distribution, I found no pre-configured GPIO Port G connected to an LED. Since our Ada firmware relies on this connection, we'll first need to enhance our custom Renode hardware description by setting up the GPIO Port G:

gpioPortG: GPIOPort.STM32_GPIOPort @ sysbus <0x40021800, +0x400> numberOfAFs: 16 [0-15] -> exti@[0-15] 

In this snippet:

  • sysbus is the central object where you typically connect components in Renode. It’s also the object you interact with in the Renode console to inspect and manipulate everything tied to your simulated system.
  • <0x40021800, +0x400> indicates that the GPIO Port is memory-mapped at address 0x40021800 with a memory range of 0x400. This mapping corresponds directly to the device datasheet, making verifying it easy.
  • numberOfAFs: 16 line shows that this GPIO port supports 16 alternate functions.
  • [0-15] -> exti@[0-15] line maps each of the GPIO pins (0-15) to the corresponding external interrupt lines (exti), allowing the GPIO pins to trigger interrupts.

This setup defines how the GPIO Port interacts with the system bus, mapping it into the simulated system’s memory space.

Adding the LED Configuration

Now, let’s add the LED configuration: UserLED: Miscellaneous.LED @ gpioPortG gpioPortG:    13 -> UserLED@0 

In this snippet:

  • UserLED: Miscellaneous.LED @ gpioPortG defines an LED connected to gpioPortG, our previously configured GPIO port.
  • gpioPortG: 13 -> UserLED@0 maps pin 13 of gpioPortG to the UserLED. The @0 is an internal identifier for the UserLED instance, allowing Renode to distinguish between multiple instances of LEDs if needed. Pin 13 on the GPIO port, specified in our Ada firmware if you follow the code definition of All_LEDs, will control this particular instance of the UserLED.

This configuration ensures that activating pin 13 of gpioPortG in your simulation will trigger the UserLED, simulating the behavior of an actual LED connected to that pin on your hardware.

Moving to the Renode Simulation Script

We can now move on to the simulation script .resc (REnode SCript) using our previous hardware setup.

Renode offers a powerful interactive console where you can create, manipulate, and inspect your simulation or its various components. You can interact with your simulation directly, making real-time adjustments, or script these interactions for automation. This is where our stm32f429_startup.resc file comes into play.

Let’s walk through setting up the simulation instructions step by step:

Start by creating a new machine named stm32f429_custom:

mach create "stm32f429_custom" 

Next, load the custom platform description for the STM32F429 discovery board:

machine LoadPlatformDescription @/path/to/stm32_blinky_demo/renode/stm32f429_custom.repl 

Now, load the ELF firmware for the blinky application:

sysbus LoadELF @/path/to/stm32_blinky_demo/bin/stm32_blinky_demo 

To monitor the state changes of the UserLED, set up logging:

logLevel -1 gpioPortG.UserLED 

Finally, start the machine:

start 

Running the Script

As said, these previous instructions are part of the `stm32f429_startup.resc` script file. To actually run the simulation, start the Renode console:$ renode --console

Run the script by including it in the console

include @/path/to/stm32_blinky_demo/renode/stm32f429_startup.resc

If everything goes as planned, you should see the LED state changes being logged at one-second intervals:

... [NOISY] stm32f429_custom/gpioPortG.UserLED: LED state changed to False

... [NOISY] stm32f429_custom/gpioPortG.UserLED: LED state changed to True

Closing Remarks

This process takes you from setting up your simulation environment to running and observing the behavior of your STM32F429 firmware, all within Renode.

I hope you found this crash course on running Ada code over Renode helpful and that you enjoy watching your LED blink in the virtual world!

Author

Olivier Henley

Portrait 2

The author, Olivier Henley, is a UX Engineer at AdaCore. His role is exploring new markets through technical stories. Prior to joining AdaCore, Olivier was a consultant software engineer for Autodesk. Prior to that, Olivier worked on AAA game titles such as For Honor and Rainbow Six Siege in addition to many R&D gaming endeavors at Ubisoft Montreal. Olivier graduated from the Electrical Engineering program at Polytechnique Montreal. He is a co-author of patent US8884949B1, describing the invention of a novel temporal filter implicating NI technology. An Ada advocate, Olivier actively curates GitHub’s Awesome-Ada list

Blog_

Latest Blog Posts