3 min read

MAVLink Router Daemon

MAVLink Router is an essential connection and routing component within a Micro-Air Vehicle architecture. It is an open-source C++ daemon for MAVLink message bridging.

Its build-time and run-time requirements include:

  1. C++ compiler and tools,
  2. standard C++ libraries,
  3. The pkgconf package configurator,
  4. Meson and
  5. Ninja.

How does the embedded developer install this important tool on a Buildroot system? The solution is pretty straightforward; it requires

  • a mavlink-router.mk Makefile,
  • a Config.in configuration file and
  • a package sub-menu.

Buildroot already supports Meson-based packages. However, some trickiness does exist: the source repo uses sub-modules; the Meson build script also assumes by default that the embedded target uses systemd as the Linux service manager but such is not always the case.

Solution

Here is the solution for the impatient.

Configuration

Add a Config.in menu item to the Buildroot packages under buildroot/package/mavlink-router.

config BR2_PACKAGE_MAVLINK_ROUTER
	bool "MAVLink Router"
	help
	  MAVLink Router is an application to distribute MAVLink messages between multiple
	  endpoints. It distributes packets to a single port or multiple endpoints
	  depending on the target address. Connections can be made via UART, UDP or TCP.

	  https://github.com/mavlink-router/mavlink-router

Insert the following sub-menu directive just before the last endmenu in buildroot/package/Config.in. This connects the new package to the packaging system.

menu "MAVLink"
	source "package/mavlink-router/Config.in"
endmenu

These kconfig directives will make the “MAVLink Router” appear as an option in the Buildroot configuration menus.

Makefile

Add a new Makefile for the package, buildroot/package/mavlink-router/mavlink-router.mk as follows.

################################################################################
#
# mavlink-router
#
################################################################################

MAVLINK_ROUTER_VERSION = 42529d55b665e0a9a29e424e186f514c56c2e5b5
MAVLINK_ROUTER_SITE = $(call github,mavlink-router,mavlink-router,$(MAVLINK_ROUTER_VERSION))
MAVLINK_ROUTER_SITE_METHOD = git
MAVLINK_ROUTER_GIT_SUBMODULES = YES
MAVLINK_ROUTER_LICENSE = Apache-2.0
MAVLINK_ROUTER_LICENSE_FILES = LICENSE
MAVLINK_ROUTER_INSTALL_STAGING = YES

ifeq ($(BR2_PACKAGE_SYSTEMD),y)
MAVLINK_ROUTER_DEPENDENCIES += systemd
else
MAVLINK_ROUTER_CONF_OPTS += -Dsystemdsystemunitdir=/usr/lib/systemd/system
endif

$(eval $(meson-package))

If the Buildroot has systemd then the make script asserts it as a dependency. If not then it bypasses the Meson build dependency on systemd by passing a custom systemdsystemunitdir. Note also the site ‘method’—packages with Git submodules, as in this case, require git as the pull method.

Alpine Comparison

Building on Docker using bare-bones Alpine Linux \(3.x\) can act as a boilerplate. A simple Docker-based deployment illustrates the Router daemon’s dependencies, both build and run-time requirements included. See below.

FROM alpine:3 AS builder
RUN apk update && apk add --no-cache \
        gcc \
        g++ \
        git \
        pkgconf \
        meson \
        ninja \
        linux-headers \
    && rm -rf /var/cache/apk/*
RUN git clone --recursive https://github.com/mavlink-router/mavlink-router \
    && cd mavlink-router \
    && meson setup -Dsystemdsystemunitdir=/usr/lib/systemd/system --buildtype=release build . \
    && ninja -C build

FROM alpine:3
RUN apk update && apk add --no-cache libstdc++
COPY --from=builder /mavlink-router/build/src/mavlink-routerd /usr/local/bin
ENTRYPOINT [ "mavlink-routerd" ]

The dependencies match those of Buildroot.

Conclusions

Integrating the Router with Buildroot’s packaging system allows the package to correctly compile and link using the correct cross-compiling toolchain.

Gotchas exist as usual. The Router by default depends on systemd for launching. But what if the target does not use systemd? For example, it uses eudev. The two are mutually exclusive. Choose one or the other. For non-systemd Linux environments, the Meson build needs to know where to install its boilerplate configuration even though systemd not present.