After setting up a number of small Yocto side-projects using Qt on a Raspberry Pi in the past, I realized that I was recreating some base “plumbing” over and over again. So I figured that it was time to create a separate layer where I could put this work so it could be easily reused, and thus Project QtiPi was born. Currently it consist of a Yocto meta-layer, a manifest for Googles repo tool that can be used to fetch all the needed layers, and a Dockerfile for creating a docker container suitable for building the project.
Since basically all my projects are either headless or single-app only, the first thing I wanted to make sure Qt was built with eglfs support, and that it is the default platform plugin so running apps with
-platform eglfs is not needed. Nowadays the meta-raspberrypi layer now enables eglfs backend automatically if DISTRO_FEATURES contains opengl, so all that is needed from meta-qtipi is to make sure eglfs is the default platform.
Another thing I found myself doing was creating some custom network configuration recipes in order to set up how the device was supposed to interact with the world around it. Usually it was one of the following:
- Connect as a client to a predefined wifi network, using DHCP
- Connect as a client to a wired network, using DHCP
- Serve as a stand-alone Wifi access point, using static IP
And since the two client options uses DHCP to get an IP adress, I wanted to configure avahi so that I could access the device using qtipi.local. By doing this I can just start up a new device and connect to it using e.g.
ssh email@example.com instead of having to look up the IP adress either on the device or using the DHCP server.
So what QtiPi now provide is a recipe called network-config that provides three different packages: network-config-eth-client, network-config-wifi-client and network-config-wifi-ap. You specify the wifi credentials by overriding the QTIPI_SSID and QTIPI_PASSKEY variables for the recipe. This can be done using a bbappend in a separate project layer, or from local.conf using something like:
QTIPI_SSID_pn-network-config = "MySSID" QTIPI_PASSKEY_pn-network-config = "supersecret"
QML Live for Rapid UI Development
Something I’ve found to be quite useful when working on a Qt/QML project is the ability to quickly see how the application look on the actual device, and luckily some of my previous colleagues have create a tool for this called QML Live that is now part of the Qt Project. One thing lacking in the upstream recipe though is a systemd service so that the runtime (the part running on the device) is automatically started on boot. So this is added using a simple bbappend.
Convenience Quick-Start packagegroup
Another thing that is useful is the qtipi-bundle packagegroup that pulls in a wide set of Qt packages, so that the image has a lot of functionality from the start. This is especially useful if you develop the application using QtCreator setup to cross-compile for the target image, then you don’t need to worry about having the right Qt modules on the device. When the application is mature enough so it’s properly packaged into it’s own recipe, the packagegroup can be removed in favor of properly defined RDEPENDS in the application recipe to reduce the image size.
Simple Example Application
When I started this project I was mainly using the official 7″ touch screen, so I packaged a simple QML application called touchpoints that just draw colored rectangles under the four first detected fingers. It serves as a quick function tester of the device, and as a reference of how to create a recipe with a systemd service file for launching a simple QML application.
One thing I have on my todo wishlist that I think could often be useful, would be a ready solution for connecting to an “unconfigured” device from your phone, and there have the possibility to scan for existing wifi network and provide the needed credentials. A lot of IoT products today come with such solutions, but I don’t think there’s any ready-to-use open-source components that provide this. All the different parts are available, but it needs some extra glue to make it an easy to use solution.
When writing this post I also took a good look at what was in the meta-qtipi layer to make sure it was up-to-date and working with the newly released dunfell version of the Yocto Project. I was glad to see that a lot of the things I had to manually customize a few years ago was now actually handled in upstream layers using smart PACKAGECONFIG customization based on DISTRO_FEATURES etc. This allowed me to clean up some deprecated stuff, leaving the meta-qtipi layer a bit slimmer.
As often before I end up reflecting on how amazing it is that so many awesome open source projects exist, that enables both organizations and individuals to create cool things reusing the previous work of others.