Check it out on GitHub

threeboard simulator user manual and design


Debugging embedded firmware is generally difficult and slow, as target hardware limitations usually prevent meaningful logging or the ability to connect a debugger and use real-time software breakpoints. Developing embedded firmware without access to a simulator means all firmware needs to be flashed and run on the target hardware, which becomes cumbersome.

For these reasons, the threeboard project includes a fully functional terminal-based threeboard simulator for Linux and macOS, built on top of the simavr project. The simulator enables running and debugging of the threeboard AVR firmware on the same x86 platform used for development, which greatly improves development speed and makes debugging far easier and more accessible. Most importantly, the firmware being simulated is the same firmware binary that runs on physical hardware: no simulator-specific code paths exist in the firmware, although UART-based logging is disabled when building for physical hardware.


The simulator runs a terminal-based graphical emulator of the threeboard hardware, designed to look as similar as possible to the actual threeboard hardware, with the LEDs and key switches laid out almost identically.

Other simulator features include:


The simulator is effectively a wrapper around simavr, an exceptionally good AVR simulator that supports lots of features of many AVR microcontrollers, and is easy to configure with new MCUs and features. Simavr does most of the difficult work of simulating the firmware: given the threeboard firmware binary file, simavr parses it, determines the properties of the MCU being simulated based on headers in the binary, and can execute the instructions one cycle at a time. It supports interrupts and timing, and has full support for the atmega32u4’s USB controller.

Events are issued and handled in simavr using IOCTL calls. These allow a way of triggering arbitrary functionality and message passing within simavr, which enables its configurability.

The simulator is comprised of several interoperating modules which emulate the properties of different hardware components on the threeboard. Modules are needed for external components (EEPROMs and UART) and for emulating a USB host machine to send keypress information.

The UI module is responsible for translating the state of the simulator into a visualisation of the result of that state on the threeboard’s hardware, in particular its LEDs. It’s a purely text-based user interface implemented using ncurses. The static outlines and frames of the UI are drawn once, and the dynamic components are redrawn at a rate of 200Hz.

The USB host component is far from a standards-compliant host implementation. It contains the least amount of logic required to make the threeboard firmware believe it is communicating with a real USB host. It simply polls the USB controller in firmware by triggering USB general interrupts which cause the firmware to periodically send its HID state over USB.