Mikhail Svetkin

Qt on Microcontrollers (MCU)

Published Thursday May 3rd, 2018
16 Comments on Qt on Microcontrollers (MCU)
Posted in Dev Loop, Embedded | Tags: , , ,

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:

STM32F469STM32F469 – ARM Cortex-M4, FPU unit single precision

STM32F746STM32F746 – ARM Cortex-M7, FPU unit single precision, L1 Cache (Data/Instruction)

STM32F769STM32F769 – 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 your 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;
  • supports various file systems, including NFS and FAT;
  • 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:

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

Porting Qt itself can be presented in 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 three firmwares for each board with different demo applications.

Qt Widgets demo

Firmware size: 6.6 MB.
RAM required: 3.4 MB.

As we can see, Qt Widgets runs just fine.

Qt Quick / QML demo

Firmware size: 9 MB.
RAM required: 5 MB.

It’s easy to see that Qt QML’s dragging animation is somewhat slow on STM32F4/F746, but the clocks work rather well. Such behavior is an excellent example of lacking JIT compilation because those MCUs don’t support double-precision floating-point. However, STM32F769 does support it, thus the dragging animation looks much nicer on this 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.

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 utilize 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!

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Dev Loop, Embedded | Tags: , , ,

16 comments

Dan says:

This is great news for us (embedded developers), bad news for Segger, and other purveyors of embedded GUI software packages (Altia, TouchGFX, etc.)

While it’s true that Segger can run on very low-end MCUs, and probably also TouchGFX, it seems like even mid-range MCUs are getting capable enough to run Qt.

Working “out of the box” demos, with full source, are essential to adoption. Looking forward to seeing what comes next.

Daniel says:

Very interesting article. Are you sure that’s 256 MBs on the requirements? That’s a lot of RAM for a STM32.

Mikhail Svetkin Mikhail Svetkin says:

I guess, you are talking of our minimal requirements for Qt for Device Creation (http://doc.qt.io/QtForDeviceCreation/qtee-supported-platforms.html#minimum-hardware-requirements).
This has nothing to do with MCU and of course we do not have as much memory on the tested boards. 🙂

Gunnar Roth says:

Because you wrote this in your blog post:
“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;”

artemsyd artemsyd says:

Those are current Qt’s recommended hardware requirements. And the article tells about a research that will allow to reduce those, in particular to enable embedded development with Qt on MCU.

Dan says:

That part of the article is poorly written and created wrong impression. If you just casually skim through the article you might think that those specs were what Qt company called MCU’s and what it tested on. Some nice comparison table of the actual HW of the MCU’s Qt managed to run would be nice. So someone might look and see “huh, 16MB RAM, 16MB ROM and 100MHz CPU is enough to run a full-fledged qt app, better look into it!”

Lukas says:

What he likely meant were the requirements presented in your article:

> 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.

That creates an impression you have to use such a powerful MCU, which is indeed not true. I was confused by this paragraph as well and only realized that something like 10MB of RAM is sufficient by reading the comments and then the article again….

Tuukka Turunen Tuukka Turunen says:

@Daniel: That 256MB is minimun recommended RAM for a system using all of Qt, e.g. Qt WebEngine prefers quite a lot of RAM to work with typical web pages. Using only a subset of features (Qt Lite) already now means a lot less RAM is needed. And as explained in the post we are aiming even lower with the MCU configurations.

Roman says:

Do you want to add MCU specific tools for debugging in Qt Creator, like watching peripheral registers, RTOS threads etc?

Mikhail Svetkin Mikhail Svetkin says:

We already have some support for bare metal: http://doc.qt.io/qtcreator/creator-developing-baremetal.html
And yes, there are plans to add more related features to Qt Creator, as we stated in the article.

Rudolph says:

The requirements listed in the blog post are *not* Qt’s own requirements. E.g. Qt can work just fine without a GPU, and with lower CPU/RAM constraints. Those requirements listed seem to be the requirements for a particular “commercial package” of Qt.

artemsyd artemsyd says:

Well yes, the hardware requirements link leads to the “Qt for Device Creation” supported targets page. Although embedded development with Qt is not necessarily a commercial package, and recommended hardware requirements for that would be around the same level.

And of course Qt can work without GPU (especially when there is no GUI 😃) and with lower CPU/RAM constraints, which this article is actually about.

Sébastien says:

“Today we do not have a universal GUI library for MCUs”

That’s simply not true, we have numerous universal GUI libraries for various MCUs. Most of which can integrated with an RTOS or run baremetal on their own.

meriton says:

Mikhail Svetkin, thanks so much for the post.Really thank you! Keep writing.

jeandet says:

“Configure the board – set clock generator (frequency), memory (SDRAM, caches, MMU), initialize peripheral and so on;”

MMU in STM32F4/7 seriously?

artemsyd artemsyd says:

That is a typo, of course. There should be MPU (fixed already). Thank you for noticing.

Commenting closed.

Get started today with Qt Download now