The ev3dev platform exposes the robot’s devices through (files in the) /dev filesystem, and devices are controlled by reading from and writing to these files. To save developers the hassle of this raw file access, ev3dev provides language bindings that abstract the file operations into neat APIs. The bindings for some languages come pre-installed with ev3dev. Therefore, if you plan to develop applications using an interpreted language such as Python, you’ll often need little more than a connection between the brick and PC. Prepare your sources on the PC, drop them onto the brick, and execute the program from the brick’s command line or its on-screen File Browser.

The use of compiled languages such as C++ require some more preparation. Denis Demidov’s C++ language bindings for ev3dev provide an API to get you started developing C++ programs for your ev3dev-based robot. While the (e.g. GNU) toolchain can be installed onto the brick easily enough, the platform’s limited hardware makes compilation painfully slow. And the compiler may simply run out of memory once your program gets sufficiently convoluted elaborate. Instead you’ll want to cross compile from your PC, using the brick only to execute the precompiled binary. Demidov also provides instructions on setting up cross compilation on Windows 10. I set up my Windows box as follows:

  • Install the Windows Subsystem for Linux (WSL). I based mine on Ubuntu 18.04.
  • From a WSL command prompt, using sudo or su to run with root privileges:
    • Ensure the list of available packages is up to date by running apt-get update.
    • Install the GNU C++ cross compiler for EV3 by running apt-get install g++-arm-linux-gnueabi.
  • Get the C++ language bindings for ev3dev, either using git clone, or by downloading the sources. You’ll need at least the ev3dev.h and ev3dev.cpp files.

Write a program to control your robot, for example to run one of Track3r‘s tank treads:

#include <ev3dev.h>

int main()
{
  // Control the large motor connected to port B
  ev3dev::large_motor m(ev3dev::OUTPUT_B);

  // Set properties for the next command we'll issue
  m.set_speed_sp(m.count_per_rot()); // Run at one rotation per second 
  m.set_time_sp(2000); // Run for two seconds
  m.set_stop_action(ev3dev::motor::stop_action_brake); // Brake when done

  // Run a command
  m.set_command(ev3dev::motor::command_run_timed);
}

When you (cross) compile your program with default settings and run it on the brick, it’ll (likely) terminate with an error because the binary was linked against a glibc version that’s newer than the one provided by ev3dev. In my case the program complained that version `GLIBC_2.27' not found, and execution of /lib/arm-linux-gnueabi/libc.so.6 told me that I have the GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version 2.24. Some options to resolve this are

Even though some people on the Interwebs warn against it, static linkage of the newer glibc is said to be the easiest, and got rid of the problem for me. So assuming your own source is named main.cpp and the language binding’s sources are in a (sub-)directory named ev3dev-lang-cpp-master, build the test program with

arm-linux-gnueabi-g++ -static -I ev3dev-lang-cpp-master ev3dev-lang-cpp-master/ev3dev.cpp main.cpp -o track3r

The resulting track3r program can be executed on the brick and runs the robot’s left tank tread for me. Note that the application terminates before the motor is done running.