Running a program as a service

Run a program in the background using `systemd`

This is a guide for running a program as a service on Bela. This can be useful when you want other processes to run alongisde the main Bela program, for instance to run a daemon that you can communicate with from your Bela program. Any program run this way will not be able to access Bela’s audio, analog and digital I/Os while another Bela program is running.

Table of contents

  1. Introduction
    1. Pre-requisites and naming conventions
  2. Creating a service file
  3. Controlling the service
  4. Running at boot

Introduction

The operating system on your Bela is a customised version of a Debian Linux distribution. Debian uses systemd to run services in the background at various times, for instance at boot, when a peripheral is connected or at regular time intervals. In this document we explain how to create a systemd service, how to manually start and stop it, how to access its logs and how to set it to start automatically on boot.

Tip

Running regular Bela projects on boot is also done using systemd, but in a more complex way than what is explained here. To run Bela projects on boot, you do not need to follow the instructions below and you can simply use the Bela IDE's 'Run on boot' menu, instead. See here for more information.

Pre-requisites and naming conventions

The instructions below assume that you already have a working program on your board that you want to run in the background. The executable file will be located somewhere on your Bela’s file system, we use the following placeholder text below, which you will have to replace with the actual values for your system:

  • EXEC_DIR is the absolute path to the folder containing your executable file
  • EXEC_NAME is the name of the executable file

For example, if you have a Bela project in your IDE called O2O, its full path will be /root/Bela/projects/O2O/O2O, so EXEC_DIR will be /root/Bela/projects/O2O and EXEC_NAME will be O2O.

Creating a service file

The first step is to create a systemd service file. Service files are contained in /lib/systemd/system/ and define some variables used by systemd do determine how to run a program within a service, when to start it, whether to restart it in case of crash, etc. A detailed description of all the options available is beyond the scope of this document, but you can read more about it here.

Create a file in /lib/systemd/system/EXEC_NAME.service on your Bela with this content (replace any placeholder text entries as appropriate):

[Unit]
Description=EXEC_NAME Launcher
After=network-online.target

[Service]
ExecStart=EXEC_DIR/EXEC_NAME
Type=simple
Restart=always
RestartSec=1
WorkingDirectory=EXEC_DIR
Environment=HOME=/root
KillMode=process

[Install]
WantedBy=default.target

You can create this file from the terminal, if you are familiar with it, or you can do this via the Bela IDE as follows:

  • create a file EXEC_NAME.service in your project (make sure the file includes only the text above and none of the automatically-generated content in the file you create)
  • move the file into place by running
    mv /root/Bela/projects/CURRENT_PROJECT_NAME/EXEC_NAME.service /lib/systemd/system/
    

    in the Bela IDE console, where CURRENT_PROJECT_NAME is the name of the project that is currently open in the Bela IDE. If the EXEC_NAME program was built through the IDE and that’s the project that is currently open, then CURRENT_PROJECT_NAME and EXEC_NAME will be the same.

Controlling the service

Once the service file is in place, you can start the program running in the background with

systemctl start EXEC_NAME

in a terminal or in the console of the Bela IDE. You can stop the program with

systemctl stop EXEC_NAME

While this program is running in the background, you can visualise the process’s output running journalctl -fu EXEC_NAME in a terminal, or journalctl -n 20 -u EXEC_NAME | cat in the Bela IDE’s console.

Running at boot

Once you are happy with how this is working, you can enable the EXEC_NAME service to start automatically in the background at boot with

systemctl enable EXEC_NAME

Later you can disable it with

systemctl disable EXEC_NAME

When the program is started on boot you can still use the journalctl commands above to access its output. Note that when starting at boot, your program may start a few seconds after the Bela program that may also be running on boot.