Flutter on Embedded Devices

Payam Zahedi
Snapp Embedded
Published in
16 min readJul 7, 2023

--

By: Moritz Theis and Payam Zahedi

Recently, a session at Google IO showcased the possibility of running Flutter on a Raspberry Pi. However, the session did not provide a comprehensive, step-by-step guide for users to follow. In this article, we aim to bridge that gap by offering a detailed walk through of the process, enabling you to run Flutter on your Raspberry Pi.

By following the steps outlined in this guide, you will gain the knowledge and confidence to set up Flutter on your Raspberry Pi. Whether you are a beginner or an experienced Flutter developer, this guide will ensure that you have a clear understanding of the process and can navigate it seamlessly.

In this article, we specifically focus on utilizing the Raspberry Pi as our embedded device. However, it’s important to note that in most industrial projects you won’t use a Raspberry Pi but other arm64 based solutions. In respect to that we use an approach that’ll also work on most other arm64 based SoCs even in production!

Before we delve into the details, I would like to express my gratitude to Moritz for their valuable assistance in creating this article. I would also like to extend my thanks to Snapp Embedded for providing the necessary environment and support that made it possible for me to write this article.

What do we need to run Flutter on Raspberry pi?

Before we start the development process, it’s important to have a clear understanding of what you’ll need to run Flutter on Raspberry Pi. Let’s go over the essential components:

  1. Raspberry Pi 4 Model B: This is the main hardware component you’ll need. I recommend getting at least the 4GB RAM version for optimal performance. (2Gb should work as well though.)
  2. Display: If you already have a monitor, you can connect it to your Raspberry Pi using a micro HDMI cable. Alternatively, you can consider getting the official 7-inch Raspberry Pi display for a dedicated setup.
  3. SD Card: Raspberry Pi requires an SD card for storage. It is recommended to use a high-quality, Class 10 microSD card for optimal performance. capacity of 32GB should be enough in most cases..
  4. Power Supply: It’s crucial to have a reliable power supply for your Raspberry Pi. You can either use the official Raspberry Pi power supply or any charger that provides a stable output of 5.0V / 3.0A.
  5. Input Devices: To interact with your Raspberry Pi, you’ll need a mouse and keyboard. You can connect them via USB or Bluetooth to the Raspberry Pi.

By ensuring you have these essential components, you’ll be ready to set up your Raspberry Pi for running Flutter and embark on your development journey with confidence.

Development environment

When it comes to creating apps for embedded devices, the development process differs from traditional mobile app development. Unlike developing for mobile devices, where you use your laptop or PC as the development device and your phone as the run device, developing for embedded devices requires a different approach.

In the case of embedded device development, your Raspberry Pi serves as both the run and development device. This means that you use the Raspberry Pi for both building and testing your Flutter applications, providing a unique development experience. You could cross-compile with some of the approaches we will show in this article, since this most often comes with additional challenges we will not cover cross-compilation for this article. Also, the building on the Raspberry-Pi really doesn’t take that long, so just grab a coffee 🙂

In addition, you have the option of utilizing certain techniques, such as pushing your code to GitHub and fetching it on your Raspberry Pi. So you can develop most of your application on your desktop machine anyway, in practice this turned out to work even better than we would have imagined. However, it’s important to note that this approach can introduce additional complexities and challenges into your development process, we just haven’t encountered any of those yet.

What Operating System to use

Selecting the right operating system (OS) for your Raspberry Pi is crucial for running Flutter effectively. It’s important to note that Flutter cannot be run on a 32-bit OS. Thankfully, there are a variety of 64-bit options available, such as Raspberry Pi OS 64-bit (formerly Raspbian) and Ubuntu 64-bit.

Raspberry Pi OS 64-bit is an officially supported OS that offers a user-friendly interface, excellent hardware support, and optimized performance specifically tailored to Raspberry Pi devices. With pre-installed software and tools designed to simplify setup, it’s an attractive choice for running Flutter on your Raspberry Pi.

In addition to Raspberry Pi OS, another noteworthy option is Ubuntu Core. Ubuntu Core is a stripped-down version of Ubuntu designed for embedded devices, offering enhanced security, reliability, and ease of management.

Alternatively, Ubuntu Desktop 64-bit is a well-known and widely-used Linux distribution that provides a robust and versatile environment. However, it’s important to keep in mind that Ubuntu Desktop may be resource-intensive for embedded devices like Raspberry Pi due to its heavier system requirements. This is why we can’t recommend it for our application.

Ultimately, the choice between these options is subjective and depends on individual preferences and requirements. It’s worth noting that besides Raspberry Pi OS and Ubuntu, there are various other 64-bit Linux distributions available, giving you the freedom to select the operating system that aligns best with your needs.

In insudtrial scenarios, it may be beneficial to consider creating a custom distribution tailored specifically to your project requirements for optimal performance and resource utilization. Take a look at the Yocto-Project for more information.

How to install Raspberry Pi OS

To streamline the installation of the chosen operating system (OS) onto your Raspberry Pi, we will introduce you to the Raspberry Pi Imager. This user-friendly tool simplifies the process of flashing the OS image onto your SD card. Below, we will provide a detailed step-by-step guide to help you get started with the installation.

  1. First, download the Raspberry Pi Imager from the official website Download Link.
  2. Once the Raspberry Pi Imager is downloaded and installed, open the application.
  3. You can select the OS option that aligns with your choice, such as Raspberry Pi OS 64-bit or Ubuntu 64-bit, from the list of available operating systems provided in the Raspberry Pi Imager.
  4. Alternatively, If you have already downloaded a custom OS image in .img format, you can choose the “Use custom” option in the Raspberry Pi Imager. This allows you to select the custom OS image file from your computer and proceed with the installation.
  5. Now, insert the SD card into your computer’s card reader slot. Ensure that the SD card is empty or backup any existing data, as the installation process will overwrite its contents.
  6. In the Raspberry Pi Imager, click on the “Choose SD card” option and select your SD card from the available drives. Double-check that you have selected the correct drive to avoid accidental data loss.
  7. After selecting the SD card, click on the “Write” button to initiate the OS image writing process. The Raspberry Pi Imager will either download the selected OS image (if you chose an option in step 3) or write the custom OS image (if you chose the “Use custom” option in step 4) to the SD card.
  8. Once the OS image has been successfully written to the SD card, you will receive a notification or confirmation message from the Raspberry Pi Imager.
  9. Safely eject the SD card from your computer’s card reader.

With the OS image successfully written to the SD card, you are now ready to proceed with setting up your Raspberry Pi. Insert the SD card into the Raspberry Pi’s SD card slot and power on the device to begin the boot process. The Raspberry Pi will initialize with the installed OS, allowing you to move forward with installing Flutter and running your applications.

Linux-Knowledge Excursion: Display Servers

Before we dive into the installation process for Flutter, it’s essential to understand some fundamental aspects of the Linux operating system. One key component to familiarize ourselves with is the Display Server on Linux.

As mentioned in this Article:

A display server is a program which is responsible for the input and output coordination of its clients, to and from the rest of the operating system, and among the hardware and the operating system. Basically, thanks to a display server, you can use your computer graphically (GUI). Without the display server, you would only be restricted to a command line interface (TTY).

The display server provides the framework for a graphical environment so that you can use mouse and keyboard to interact with applications.

The display server communicates with its clients over the display server protocol, like X11. The display server is a key component in any graphical user interface, specifically the windowing system.

Two of the most popular display protocols on Linux, are Wayland and X Window System (X11 or X.Org). These protocols define how graphical data is transmitted and rendered on the screen, facilitating communication between the Display Server, applications, and hardware.

X11, also known as X.Org, is the longstanding standard display protocol in Linux. It provides a reliable framework for graphical display management and offers features like window management and network transparency. Despite its age, X11 remains widely supported by various desktop environments and window managers.

Wayland is a modern, lightweight display protocol with a focus on performance, security, and a streamlined user experience. It offers direct rendering, smoother window management, and reduced latency, making it increasingly popular among Linux distributions.

This knowledge is needed to understand the decision of which Flutter-Embedder we will use in the following.

Options to run Flutter on the Raspberry Pi

When it comes to running Flutter on the Raspberry Pi, there are three primary options available to us: (There are other options as well, in this talk, however, we will focus on the following three.)

  1. Flutter Linux desktop: Flutter provides support for Linux desktop environments, allowing you to develop and run Flutter applications directly on the Raspberry Pi. This option offers the most comprehensive and versatile Flutter experience, providing access to the full range of Flutter features and capabilities.
  2. Flutter-pi Engine Embedder by Ardera: Another option is the Flutter-pi engine embedder developed by Ardera. It is specifically designed to optimize Flutter for Raspberry Pi devices.
  3. Flutter-elinux Engine Embedder by Sony: Sony has developed the Flutter-elinux engine embedder, which aims to provide seamless integration of Flutter with embedded Linux systems. This engine embedder focuses on running Flutter on a wide variety of arm64 based options, providing enhanced performance and stability for running Flutter applications.

In this article, we will primarily focus in Flutter-eLinux and compare it with classical Flutter. By exploring the similarities and differences between these approaches, we can gain a deeper understanding of their respective strengths and limitations.

It’s important to note that Flutter-pi is primarily focused on the Raspberry Pi platform (as mentioned in the document). since we aim for a solution which runs on the Raspberry Pi as well as a variety of other arm64 devices we will only look at the solution provided by Sony. However we cannot and don’t want to tell if one solution is better than the other, all we want to say is that because of the approach and excellent documentation in the Sony solution we chose it..

Why do we need Flutter-eLinux in the first Place?

Before we delve into the details of how to run Flutter using these two methods, let’s explore the key differences between Flutter Linux Desktop and Flutter-elinux. Understanding these distinctions will help us understand why we are not just using normal Flutter on our Raspberry Pi.

as mentioned in this wiki page:

The biggest difference is that Flutter-elinux doesn’t use GTK/GDK at all. It uses Wayland, X11 or DRM backends. On the other hand, Flutter desktop for Linux heavily relies on GTK/GDK which needs X11.

So, you may ask yourself why this is important for us?

X11 is still a dependency in a lot of libraries and packages especially in desktop environments, making it hard to move away from it, where at the same time Wayland is clearly the way to go.

If we take a look at the newest arm64 hardware we will see that (nearly) all of them now offer support for Wayland, and the first ones (the iMX8-Series from NXP) are even no longer supporting X11 at all.

In contrast to desktop-environments, embedded solutions normally use a more streamlined operating system, often individually crafted through tools like the Yocto-Project. Therefore it is way easier to already use Wayland and the adoption is moving on much faster. If we aim to use Flutter in industrial applications we should therefore definitely be able to use Wayland and not depend on X11.

Linux desktop vs Embedded linux stack

Sadly using a custom embedder has effects on the plugin compatibility. Flutter-elinux employs a different engine embedder than Flutter Linux Desktop. This means that if you have a plugin specifically designed for Flutter Linux Desktop, it may not be compatible with Flutter-elinux. In such cases, you may need to create the plugin to work with the Flutter-elinux engine embedder. Check this thread in twitter.

Performance-Comparison: Flutter Desktop vs Flutter-elinux

In order to assess the performance of these two options, we will use the Counter app and Coffemachine app. We will run these apps in profile mode and analyze their performance using the dev-tools.

Performance on Raspberry Pi

In the first scenario, we will use Raspberry Pi OS with the default X11 display backend.

Hardware: Raspberry Pi 4 Model B 8Gb
Operating System: Raspberry Pi OS 64bit(Raspbian)
Display Backend: X11 (Raspbian’s default display backend) Wayland is currently only available in beta for Raspberry Pi OS. Nevertheless you can run a Wayland on top of the system-wide display server, which we did for comparison reasons)

IMPORTANT! During our tests we sadly lost some pictures of running the tests of Flutter-elinux. Nevertheless, we still have the results, and of course, share them.

Lets take a look at images.
Left: Counter app — Flutter-elinux Wayland backend(On top of X11!)— 44 FPS.
Right: Counter app — Flutter-DesktopX11 backend —59 FPS .
Without Picture: Counter app — Flutter-elinux X11 backend — 57 FPS.

Left: Flutter-elinux-wayland | Right Flutter-desktop-x11

Now, let’s put these options to the test with a different project. For this comparison, we’ll use the “Coffemachine” project created by Moritz, which involves more complexity and includes charts and animations.

Lets again take a look at the results. This time we not only started Wayland on top of the already running X11 Backend (which as we expected results in poor performance) But we also tried directly running Raspberry Pi OS with Wayland as system-wide display server, which is currently supported in beta (and really is not recommended nor stable).

Left: Coffemachine— Flutter-elinux — Wayland backend(On top of X11!)— 41 FPS.
Right: Coffemachine— Flutter-Desktop — X11 backend — 59 FPS.
Without Picture: Coffemachine — Flutter-elinux — Wayland backend directly(beta) — 55 FPS.
Without Picture: Coffemachine — Flutter-elinux — X11 backend — 58 FPS.

Left: Flutter-elinux-wayland | Right Flutter-desktop-x11

Based on the information provided by Flutter-elinux, we might expected a better performance with elinux. However, the results indicate that Flutter Linux Desktop even outperforms Flutter-elinux in some setups. and the question is WHY?

Is this an issue with Flutter-elinux? We don’t think so. The issue most likely lies with the default display backend of Raspberry Pi OS, which is X11. When running a Wayland compositor on top of X11, it for sure severely impacts the device’s performance, leading to reduced efficiency.

Also using Wayland as a system-wide option under Raspberry Pi OS didn’t work out that well even though we could see a significant improvement, but this setup was far from stable and produced bugs in other places of the system.

Clearly the easiest option to go for under Raspberry Pi OS is to just use X11 as a system-wide option and also use it for your flutter development. However, the important thing for our solution in the long run is the possibility to also run it under Wayland, which is clearly proven here.

Out of curiosity we also tested the performance under Ubuntu even though it’s a desktop-env because it comes with Wayland as default display backend.

Performance on Ubuntu

Before delving into the details, it’s important to note that Ubuntu can be resource-intensive for a device like The Raspberry Pi. Even simple tasks such as opening a browser or running other applications can take some time, and the default user interface may exhibit noticeable lag.

We utilized Ubuntu 22.04 for testing purposes, as it comes with Wayland as the default display backend. checkout this resource.

In 2017, Ubuntu made it the default with version 17.10. The experiment didn’t go well and they reverted to Xorg with Ubuntu 18.04. Now, Wayland becomes default again in version 21.04.

In this particular test, We focused solely on evaluating the performance of Wayland in Ubuntu, and did not assess the performance of X11.

Left: Counter app — Flutter-elinux Wayland backend — 42 FPS.
Right: Coffemachine — Flutter-elinux Wayland backend— 15 FPS .

Yea, as you can see results are awfull in ubuntu as ubuntu desktop is too heavy for embedded devices like Raspberry Pi.

Conclusion

If you are looking to create a test or prototype using Flutter, utilizing a Raspberry Pi device along with Flutter Desktop can provide satisfactory performance. This setup allows you to run your test applications and validate their functionality.

However, when it comes to creating a real product where your application is the primary and sole running app, it is recommended to consider creating your own customized Linux distribution that is specifically tailored to your hardware and application requirements.

In such cases, Flutter-elinux with the Wayland backend emerges as an excellent choice. This setup ensures that your application receives the necessary resources and optimizes the performance, resulting in a smooth and reliable user experience.

Installing Flutter on Raspberry Pi OS

While it is recommended to follow the official documentation for installing Flutter on Linux, we will provide an overview of the easiest way to install Flutter in this article. Please note that the installation process may evolve over time, so referring to the official documentation ensures you have the most up-to-date instructions.

The simplest method for installing Flutter on Linux is by utilizing snapd. Before proceeding, ensure that snapd is installed on your machine. If it’s not already installed, you can find instructions on how to install snapd at this link:

https://snapcraft.io/docs/installing-snapd

Once snapd is installed, you can proceed with installing Flutter by using the Snap Store or via the command line.

Open a terminal and enter the following command:

sudo snap install flutter --classic

you can find your flutter path with this command:

flutter sdk-path

In case you prefer to install Flutter manually or encounter any issues with the snap installation, You can find the manual installation guide at this link https://docs.flutter.dev/get-started/install/linux#install-flutter-manually

Installing Flutter-eLinux on Raspberry pi OS

Before installing Flutter on your machine with Flutter-elinux, you need to ensure that several dependent libraries are installed.

These libraries include curl, unzip, git, clang, cmake (version 3.15 or higher), and pkg-config. You can install these libraries by running the following command in your terminal:

sudo apt install curl unzip git clang cmake pkg-config

Once the dependent libraries are installed, you can proceed with the installation of Flutter-elinux. Begin by cloning the Flutter-elinux repository and moving it to the /opt/ directory:

$ git clone https://github.com/sony/flutter-elinux.git
$ sudo mv flutter-elinux /opt/

Next, update your system’s path to include the Flutter-elinux binaries:

$ export PATH=$PATH:/opt/flutter-elinux/bin

To ensure that the installation was successful and everything is working correctly, run the following command to check the Flutter-elinux environment:

$ flutter-elinux doctor

Running the flutter-elinux devices command will display the connected devices. You should see two connected devices, one using the elinux-x11 backend and the other using the elinux-wayland backend.

$ flutter-elinux devices
2 connected devices:

eLinux (desktop) • elinux-wayland • flutter-tester • Ubuntu 20.04.2 LTS 5.8.0-63-generic
eLinux (desktop) • elinux-x11 • flutter-tester • Ubuntu 20.04.2 LTS 5.8.0-63-generic

Running on X11

If you intend to use the x11 backend, you will need to install the libx11-dev library by running the following command:

$ sudo apt install libx11-dev

and you can run the app like this:

$ flutter-elinux run -d elinux-x11

Running on Wayland

For the Wayland backend, you will need to install the libwayland-dev and wayland-protocols libraries:

$ sudo apt install libwayland-dev wayland-protocols

If you plan to run Wayland on top of a system-wide X11(what we recommend, for now), you must install a Wayland compositor. The most used one is Weston and can be installed by:

$ sudo apt install weston

so before you run your flutter app in wayland mode you easlily start Weston by running:

$ weston &

Follow by:

$ flutter-elinux run -d elinux-wayland

IDE and development

We recommend to use vs code as your IDE because it’s lightweight and runs pretty good even on the Raspberry Pi.

Raspberry Pi OS

To install vs code on the raspberry pi you can simply run this command in your terminal:

sudo apt update
sudo apt install code

find more info in this link.

Ubuntu

in Ubuntu as mentioned in this Document:

The easiest way to install Visual Studio Code for Debian/Ubuntu based distributions is to download and install the .deb package (64-bit), either through the graphical software center if it’s available, or through the command line with:

sudo apt install ./<file>.deb

Bonus — Good News

As you may have noticed, running Flutter on Raspberry Pi or other embedded devices can be a challenging process. Considering the complexities involved, we recognize the need for a streamlined solution. As part of our plans, we aim to create a dedicated repository that will simplify the setup and configuration of Flutter on embedded devices. Our goal is to make the process of running Flutter on Raspberry Pi as straightforward as possible. if you want to follow us on this topic make sure to follow me in twitter. Also make sure to follow: https://twitter.com/SnappEmbedded

https://twitter.com/payamzahedi95

--

--

Payam Zahedi
Snapp Embedded

I’m a Software Engineer, Flutter Developer, Speaker & Open Source Lover. find me in PayamZahedi.com