Episode 13: Burkhard on Qt Embedded Systems
View this email in your browser
Welcome to Episode 13 of my newsletter on Qt Embedded Systems!
Qt 6.0 was released on 8 December. So, writing a Qt 6 Special suggested itself. I take a look at 7 posts from the Qt 6 launch through the lens of Qt embedded systems. I have migrated the terminal application of a sugar beet harvester from Qt 5.12 via Qt 5.15 to Qt 6.0 in 1.5 days. You can expect my post in early January.
My conclusion: Qt 6 will not be a viable option for embedded systems for another year. Essential modules like Multimedia, SerialBus, SerialPort, RemoteObjects, Charts and WebEngine didn’t make it into Qt 6.0. They will become available with Qt 6.2 LTS in autumn 2021. So, you’ll have to stick with Qt 5.15 for the time being.
I wish you a happy, healthy and successful year 2021 🎉
Enjoy reading and stay safe - Burkhard 💜
My Blog Posts
Determining the Architecture of Qt Embedded Systems: Getting Started
Are you about to start the development of a Qt embedded system? Then a lot of questions are going through your head: Which SoC is the best? Should you build your own Linux distribution with Yocto, use a container OS or even desktop Linux/Windows? Should you use Qt Commercial or Qt LGPLv3? What are the operating conditions? How does the system communicate with sensors, ECUs and the cloud?
This is a small selection of the 50+ questions in my post. Finding the right answers in the specific context of your project will save you a lot of time. It will also decide whether your project will be a success or a failure.
My Most Viewed Posts in 2020
Here is a list of the five posts most viewed on my web site in 2020.
Lessons from Six Years as a Solo Consultant (published: 2019-06-26, views in 2020: 21.8K). My three main lessons are: don’t bill by the hour; make potential customers call you; introduce productised services. When the post got featured on Hacker News in January 2020, my web server broke down under 10K views within a few hours. Most commenters can’t get their heads around anything else but hourly billing. That’s their bad.
Using Docker Containers for Yocto Builds (2019-02-11, 12.0K). It seems that I was the first to write down how to set up Docker, how to build a Docker image and how to build a Qt embedded Linux system (a simple Internet radio) with Yocto in the Docker container. This post was the basis for more posts (including #4 of this list), a webinar and a conference talk (Qt Day Italy, 2020). The post also got linked from the Qt blog.
Comparing Two Floating-Point Numbers (2019-08-26, 5.2K). Comparing two floating point numbers with the equality operator is almost always a bad idea. This post and its older companion Is a C++ Float Variable Ever Equal to 0.0f? (2016-05-04, 2.3K) make it clear, why you should replace all occurrences of float1 == float2 with an appropriate solution. It can save you days of debugging.
Qt Embedded Systems – Part 1: Building a Linux Image with Yocto (2020-05-26, 3.5K). This post is my reference when I bring up a new Qt embedded Linux system for my customers. Part 2 (2020-06-19, 1.8K) shows how to build a Qt SDK for cross-building Qt applications. This is the only post written in 2020 that made the Top 5, although my 11-day old post Determining the Architecture of Qt Embedded Systems: Getting Started came very close.
CMake Cross-Compilation Based on Yocto SDK (2017-06-03, 3.4K). 3.5 years ago, this was probably the only post describing how to cross-build Qt applications with CMake from QtCreator. QtCreator, CMake and my understanding have improved a lot since then. This lead to my recent post Cross-Compiling Qt Embedded Applications with QtCreator and CMake.
Qt 6 Special
Add-on support in Qt 6.0 and beyond by Tuukka Turunen (The Qt Company)
Qt 6 is 10-12 months away from feature parity with Qt 5.15. Qt 6.0 is a technology preview and so will be Qt 6.1 in April 2021. Qt 6.2 LTS will be the first Qt 6 version on par with Qt 5.15 and will be released not before September 2021.
Here is the availability of Qt modules most relevant to embedded systems:
Qt 6.0: Core, Gui, Network, OpenGL, QML, Quick, Quick 3D, Quick Controls, SQL, SVG, Test, Wayland, Wayland Compositor, Image Formats, CoAP, MQTT and OPC UA.
Qt 6.1: Charts and Virtual Keyboard.
Qt 6.2: Bluetooth, Multimedia, NFC, Positioning, Remote Objects, Sensors, SerialBus, SerialPort and all Web modules.
The inavailability of Qt Multimedia will be a big obstacle for the adoption of Qt 6.0 and 6.1, as most embedded systems use video and audio. The lack of Qt SerialBus (CAN, ModBus), Qt SerialPort (RS-232, RS-485) and Qt NFC before Qt 6.2 is a showstopper for many industrial products.
Qt Charts is especially useful for medical devices and for measuring instruments. It will be available in Qt 6.1.
Qt Wayland Compositor is available in Qt 6.0 for composing the HMIs of multiple applications into one. However, Qt Remote Objects for the communication between multiple applications will only be available in Qt 6.2. You must either wait for Qt 6.2 or fall back to Qt DBus from Qt 6.0.
All the Web modules - Web Engine, Web View, Web Sockets and Web Channel - will only be available in Qt 6.2. That’s a small sacrifice, as I tend to avoid the Qt Web modules, which are badly optimised for embedded systems.
Qt 6.0 Released by Lars Knoll (The Qt Company)
Don’t expect any glamorous new features. Qt 6.0 is a solid evolutionary step in some core areas.
C++17. Qt 6.0 is the first Qt release fully embracing modern C++ (C++11 and newer). For example, container classes like QList and QVector come with full support for move semantics. So, you better brush up on modern C++ features. I can recommend the books C++ Move Semantics - The Complete Guide and C++17 - The Complete Guide by Nicolai Josuttis.
Core Libraries and APIs. Qt 6 introduces property bindings for C++. It improves the performance of QList by implementing it as QVector. QMetaType and QVariant were rewritten almost completely.
New Graphics Architecture. Low-level 3D graphics API like Metal (macOS), Direct3D (Windows), OpenGL and Vulkan are hidden behind an abstraction layer called the rendering hardware interface (RHI). Qt Quick implements its 2D and 3D graphic scenes with the RHI, which implements the platform-specific graphics API.
Qt Quick 3D. Qt 6 brings more 3D goodness to QML and a better integration of QML 2D into QML 3D as outlined in this post.
Build System. Qt 6 is built entirely with CMake. QMake will be supported for the complete lifetime of Qt 6. Lars recommends to use CMake for new developments. I fully agree.
Compatibility. The recommended strategy is to port your Qt 5 application to Qt 5.15 in a first step and to port it to Qt 6.0 in a second step. Once you have fixed all the warnings about APIs deprecated in Qt 5.15, your code is fairly close to Qt 6.0. The Qt5CoreCompat module makes your transition to Qt 6.0 easier: compiler warnings instead of errors. The guide Porting to Qt 6 is your starting point.
Supported Platforms. If you want to use the pre-built binaries for Qt 6.0, you will have to use Ubuntu 20.04 or newer on your development PC. If you want to stick with an older Ubuntu version, you will have to build Qt 6.0 from sources.
Qt 6 in OpenEmbedded and Yocto by Samuli Piippo (The Qt Company)
The Yocto meta layer for Qt 6 is unsurprisingly called meta-qt6. The recipe to build the toolchain or SDK is called meta-toolchain-qt6. A recipe that builds an application with CMake inherits qt6-cmake. When you cross-build an application against the SDK from QtCreator, you can avoid sourcing the SDK’s environment setup script by using the file Qt6Toolchain.cmake.
I checked in my Qt account for the small business license, for which target devices a QBSP (Qt board support package) is available. All the QBSPs are built with Yocto 3.1 Dunfell and can be installed on a Linux or Windows host. More QBSPs will follow.
Raspberry Pi 4 Model B (35 USD).
Toradex Apalis i.MX8 (3 variants for 260 USD, 290 USD and 310 USD).
NXP EVK for i.MX 8M Mini (400 USD), Nano (400 USD) or Quad (450 USD). The prices are for buying these boards directly from NXP. Buying them through a distributor like Arrow, Digikey or Mouser may be more expensive.
Intel NUC boards with Core i3 (350 USD), Core i5 (720 USD) and Core i7 (830 USD).
Property bindings in Qt6 by Lars Knoll (The Qt Company)
For me, the most exciting feature of Qt 6.0 are property bindings in C++. Property bindings have the potential to make C++ code simpler and more declarative as they have already done it for QML code for 10 years.
Lars describes how the class QProperty is implemented. He refines a trivial implementation until all goals are reached: fast, no overhead when not used, memory efficient and integrated with Q_PROPERTY. For a Q_PROPERTY, the binding is defined by the BINDABLE attribute and the Q_OBJECT_BINDABLE_PROPERTY macro. The latter lacks proper documentation. The macro is mentioned briefly on the documentation page of the class QObjectBindableProperty.
As interesting as the implementation of the class QProperty is, it doesn’t help you decide when to use C++ property bindings. Let me fill this gap.
The user fills out a form, where the fields first name, last name and email address are mandatory and where the fields age and gender are optional. The submit button of the form is only enabled, if the user has entered valid values for the mandatory fields.
Before Qt 6, the setter functions of the mandatory fields would call a function checkSubmitEnabled(). This function would update the enabled property of the submit button and emit a value-changed signal. With Qt 6, you could write your model class like this:
// Header file of model class
// Mandatory fields
QProperty<QString> m_firstName;
QProperty<QString> m_lastName;
QProperty<QString> m_email;
QProperty<bool> m_submitEnabled{false};
// Source file of model class
// Constructor body
m_submitEnabled.setBinding([this]()
{
return !m_firstName.value().isEmpty() &&
!m_lastName.value().isEmpty() &&
!m_email.value().isEmpty();
});
You specify a binding as a lambda function. Whenever the user changes the first name, last name or email address, the binding function is executed and the m_submitEnabled is updated. You don’t have to remember when to call the function checkSubmitEnabled(). The new C++ property bindings relieve you from this easy-to-forget duty.
Question to you, dear reader. Enabling buttons is a good use case for C++ property bindings. What other use cases do you see?
Porting from Qt 5 to Qt 6 using Qt5Compat library by Karsten Heimrich (The Qt Company)
The Core5Compat module contains class from Qt 5 that have been removed or replaced in Qt 6. If you link Qt 6 applications against Core5Compat, you won’t get any compilation errors from these obsolete classes (see this page for a complete list). You’ll get deprecation warnings instead.
You can fix the other compilation errors before tackling the errors from the Core5Compat classes. This allows you to port your code step by step and keep the number of errors low in each step.
The description in the post how to build Core5Compat with CMake is wrong. You find the right description here.
Here are some of the more prominent replacements. QRegExp from Qt 5 was replaced by QRegularExpression in Qt 6, QStringRef by QStringView, QTextCodec by QStringConverter and QXmlSimpleReader by QXmlStreamReader.
Qt Creator 4.14 released by Eike Ziller (The Qt Company)
QtCreator 4.14 is the first version supporting Qt 6. It pretty prints Qt 6 code and provides project wizards to create CMake projects for Qt 6. Eike puts it in a nutshell: “If you plan to use or test Qt 6 for your applications, make sure to use Qt Creator 4.14 for the best experience.”
New features in CMake 3.19 by Cristian Adam
When you build CMake projects from the command line (e.g., as part of CI/CD), you end up passing half a dozen -D options to set cache entries. From CMake 3.19, you can define CMake cache entries, Linux environment variables and more in the CMakePresets.json and CMakeUserPresets.json files. Then you pass —preset=<name> to CMake, where <name> is the preset name defined in the preset file. Cristian gives an example.
You can enjoy this CMake feature both in Qt 5 and Qt 6, as the CMake version is independent of the Qt and QtCreator versions. I typically use the latests CMake version in my projects. Qt 6 requires CMake 3.18 or newer. So, you can go for CMake 3.19 right away.
Copyright (C) *|CURRENT_YEAR|* *|LIST:COMPANY|*. All rights reserved.
*|IFNOT:ARCHIVE_PAGE|**|LIST:DESCRIPTION|**|END:IF|*
*|IFNOT:ARCHIVE_PAGE|**|HTML:LIST_ADDRESS_HTML|**|END:IF|*
Update Preferences | Unsubscribe
*|IF:REWARDS|* *|HTML:REWARDS|* *|END:IF|*