On the 2018-05-03 there was a post published in The Qt Company blog: “Qt on Microcontrollers”. It was about the first PoC of Qt running on several selected MCUs. I say “was”, because for unknown reasons that post is no longer available in the Qt blog.

Qt on MCU

All the work on that PoC was single-handedly done by Mikhail Svetkin, who was an embedded software developer in The Qt Company back at the time, and looks like the post was taken down at some point after he left the company (Internet Archive has the last snapshot on 2019-05-02). Perhaps the new project owner didn’t like something about that article?

Anyway, I thought I’ll resurrect the post and publish it here for the history. Everything below is published almost as it was in the original post in the Qt blog.

Эта статья на русском 🇷🇺.

People often ask us about if it’s possible to use Qt for software development on microcontrollers (MCU), and if Qt can run without an operating system (“bare metal”). Today we will answer these questions and show you some concrete examples.

What is the point of using microcontrollers

MCUs are small computers on a single integrated circuit. They’re similar to systems on a chip (SoC), albeit less sophisticated. Microcontrollers are used in automatically controlled products and devices, such as car engine control systems, implantable medical devices, wearables, remote controls, office machines, appliances, power tools, toys, and other embedded systems. The main advantage of using MCUs is their small size and comparatively very low cost – especially for large volumes of production.

So, we can already see the main features of MCUs from the definition: small size, low power consumption and, naturally, low price per unit. Thus, we can say that the main point of using MCU is a natural desire to save cost.

Why use Qt on an MCU

Low computing power applies certain restrictions to the choice of software development tools, especially if we talk about the GUI, e.g. in regards to firmware size, runtime memory usage and how “fancy” the GUI can be.

Today we do not have a universal GUI library for MCUs. Sure, there are some that could solve some part of the task for this or that particular MCU model, but that is not enough. And quite rarely (or actually never) those libraries are created with “cross-platform-ability” in mind.

Although some commercial toolkits are actually pretty good, in most cases they have a closed source code. So you’re buying a “black box” and risk to find yourself vendor-locked.

Now imagine how great it would be if we could use the Qt framework: cross-platform and comprehensive library of classes (including GUI), with excellent documentation and lots of examples, and with a fantastic Open Source community.

Unfortunately, up to this moment, due to the mentioned hardware restrictions, embedded development with Qt (Qt for Device Creation) was officially supported only on devices of Cortex-A level, mostly under Linux and some commercial RTOSes (INTEGRITY, QNX, and VxWorks).

But today, this situation has changed.

Research

Getting started

So, we got ourselves a research: investigate the possibilities of running Qt on MCU hardware.

Let’s be clear from the beginning on what microcontrollers we’re talking about exactly, because some might start to dream about MCUs with a 12 MHz CPU and 128 bytes of RAM. That would be quite a gap because Qt’s current hardware requirements are:

  • 256 MB of RAM;
  • 500 MHz CPU (1 GHz preferred);
  • OpenGL ES 2.0 support.

Definitely not the microcontroller level, because those have a far smaller footprint.

And the boards we selected for the research are:

STM32F469
STM32F469 - ARM Cortex-M4, FPU unit single precision.
STM32F746
STM32F746 - ARM Cortex-M7, FPU unit single precision, L1 Cache (Data/Instruction).
STM32F769
STM32F769 - ARM Cortex-M7, FPU unit double precision, L1 Cache (Data/Instruction).

As you can see from specifications, their hardware resources are way lower than what Qt “officially” requires.

Regarding OpenGL support, thanks to Qt Quick 2D Renderer it is not a strict requirement, because we can render our graphics using raster paint engine.

We started with porting the following Qt modules:

Porting

How do you port Qt to different target platforms? Well, first we need to understand what exactly is required for Qt to function. And in general, there are two main requirements you need to meet:

  • POSIX-compatible operating system;
  • C++11-compatible compiler.

Let’s start with C++11 requirement. With version 5.7, Qt started to require platforms to support C++11 because we aim to provide a powerful and modern C++ framework. However, if your platform can only support C++98 at best, then you can of course try to do it with Qt 5.6 (or older), but then considering the fact that new configuration system (so-called Qt Lite) was introduced only with Qt 5.8, it will be a tough task for you to “squeeze” Qt into an MCU environment.

Now regarding POSIX - Portable Operating System Interface. That actually answers the question why Qt does not work on “bare metal” out of the box. Inside Qt we are using a lot of POSIX functions (pthreads, mmap, fopen, open and others), so if we want to run Qt on bare metal, we need to create your own implementation of POSIX – basically implement our own operating system. Fortunately, that isn’t the case in our research.

We decided to use an Open Source RTOS and we chose RTEMS for its most notable features:

  • simplicity;
  • POSIX support;
  • it supports various file systems, including NFS and FAT;
  • it includes a port of the FreeBSD TCP/IP stack;
  • C++11 support;
  • Open Source license (modified GPL);
  • an active community.

The process of porting Qt to RTEMS consists of the following steps:

  1. Configure the board: set clock generator (frequency), memory (SDRAM, caches, MPU), initialize peripheral and so on;
  2. Port RTEMS to STM32F4/F7 (create a BSP);
  3. Port Qt to RTEMS:
    • Add support for it in Qt Core;
    • Create a new QPA plugin.

Porting Qt itself can be presented on the following illustration:

Porting Qt

We won’t describe the whole process in detail (from configuring the board till the creation of a new QPA) just yet, even though that’s probably the most interesting part of the research. But this article was aiming only to tell you about the research and not to provide a step-by-step manual. If you are interested in conduction a pilot project, please contact us and submit your request.

Results

To demonstrate the results, we created 3 firmwares with different demo applications:

If video doesn't play in your browser, you can download it here.

Qt Widgets demo

  • firmware size: 6.6 MB
  • RAM required: 3.4 MB

Video (initially was published on YouTube, but The Qt Company has made it private, good thing there is original):

If video doesn't play in your browser, you can download it here.

As we can see, Qt Widgets runs just fine (if you ignore the touchscreen’s poor responsibility/precision).

Qt Quick demo

  • firmware size: 9 MB
  • RAM required: 5 MB

Video (initially was published on YouTube, but The Qt Company has made it private, good thing there is original):

If video doesn't play in your browser, you can download it here.

It’s easy to see that Qt Quick’s dragging animation is somewhat slow on STM32F4/F746. Such behavior is a good example of lacking JIT compilation because those MCUs don’t support double-precision floating-point. And STM32F769 does support it, thus the dragging animation looks much nicer on that board.

E-bike demo

We decided not to stop on simple demos and for the third firmware, we tried to run something more interesting. For instance - our recent e-bike demo.

  • firmware size: 13 MB
  • RAM required: 10 MB

Video (initially was published on YouTube, but The Qt Company has made it private, good thing there is original):

If video doesn't play in your browser, you can download it here.

And even this demo works fine too. By the way, thanks to the cross-platform nature of Qt, we didn’t have to change a single line of code to compile it for RTEMS (the original target was running on Linux).

Conclusion

We can conclude that our research was successful. Sure, it is not a ready out-of-the-box solution right now, but we will continue to work on it.

Current tasks include the following:

  • porting more Qt modules, and first of all - libraries from Qt for Automation addon;
  • further port optimizations and performance improvements, e.g. to make use of the graphics accelerators provided by the boards, which we haven’t utilized yet;
  • further tinkering with the Qt configuration system (Qt Lite);
  • adding support for development on MCUs into Qt Creator.

So, what does this research mean for you and your projects? The source code of the new QPA and other modifications to the Qt code base should be available in Open Source (most probably under GPLv3), and of course in commercial license too, so you’ll be able to try it out yourself.

And we plan to provide consultancy services for preparing a system image and porting Qt to your MCU-based platform. We’ll have more information about that very soon, so stay tuned!

In the meantime, make sure to sign up for the Qt on MCUs webinar where we tell you more about the topic, show you some demos and answer your questions! The webinar is no longer available via that link, but here’s a recording (~24 MB):

If video doesn't play in your browser, you can download it here.