After showing how to build a minimal Linux system for the STM32MP157 platform, how to connect and use an I2C based pressure/temperature/humidity sensor and how to integrate Qt5 in our system, in this blog post, we are going to see how to set up a development environment to write our own Qt5 application, with QtCreator.
List of articles in this series:
- Building a Linux system for the STM32MP1: basic system
- Building a Linux system for the STM32MP1: connecting an I2C sensor
- Building a Linux system for the STM32MP1: enabling Qt5 for graphical applications
- Building a Linux system for the STM32MP1: setting up a Qt5 application development environment
- Building a Linux system for the STM32MP1: developing a Qt5 graphical application
- Building a Linux system for the STM32MP1: implementing factory flashing
- Building a Linux system for the STM32MP1: remote firmware updates
A minimal Qt5 application
We’ll call our application qt-sensor-demo
, so create a directory with this name, outside of Buildroot. It’s important to not mix up your application code with your build system: you could very well decide to use another build system one day, while keeping your application code. To keep things simple, create this qt-sensor-demo
side-by-side with Buildroot, as this will be important for a future step in this blog post.
In this directory, create a main.cpp
file with the following code:
#include <QApplication> #include <QPushButton> int main(int argc, char* argv[]) { QApplication app(argc, argv); QPushButton hello("Hello world!"); hello.resize(100,30); hello.show(); return app.exec(); }
It should be fairly straight-forward to understand that this program creates a QApplication object, a push button with the Hello world! label, sets the button size to 100 by 30 pixels, shows the button, and enters the application event loop. It is obviously a very basic application, because it doesn’t do anything useful, but that’s good enough as a starting point.
Now, we need to build this application. Building Qt applications by hand is definitely not reasonable, as Qt may need to run several tools on the source code before it gets built, and requires a number of compiler and linker flags. So, we won’t write a Makefile by hand, but instead use a build tool that generates the Makefile for us. We have a number of options here:
- qmake, the build tool provided by Qt itself
- cmake, with its Qt5 integration
- autotools, with the ax_have_qt macro from autoconf-archive
- meson with its Qt5 module
In this blog post, we’ll simply stick to qmake, which is good enough for a number of Qt-based applications. qmake takes as input one or several .pro
files describing the project, and uses that to generate Makefiles (on Linux systems).
In our case, the qt-sensor-demo.pro
file will be as simple as:
QT += widgets SOURCES = main.cpp
Building our application
We have two ways to build our application:
- Manually outside of Buildroot. In this case, we’ll use the Buildroot-provided compiler and tools, but we will trigger the build of our application separately from the Buildroot build.
- Using Buildroot. In this case, our application would have a corresponding Buildroot package, that would automate building the application as part of the complete system build process.
Ultimately, we definitely want to have a Buildroot package for our application, to make sure the entire build is fully automated. However, during the active development of the application, it may be useful to build it manually outside of Buildroot, so we are going to see both solutions, which are not mutually exclusive: you can have a Buildroot package for your application, and still build it manually when you’re doing active development/debugging.
Building manually outside of Buildroot
To build manually, we simply need to first invoke Buildroot’s provided qmake
:
/path/to/buildroot/output/host/bin/qmake
This will generate a Makefile
, that we can use to build our application:
make
At this point, you should have:
$ ls main.cpp main.o Makefile qt-sensor-demo qt-sensor-demo.pro
The qt-sensor-demo
executable is compiled for ARM, and linked against the various libraries built by Buildroot.
Now, we need this executable on our STM32MP15 target. For now, we’ll simply add it to the SD card image:
cp qt-sensor-demo /path/to/buildroot/output/target/usr/bin/ cd /path/to/buildroot/ make
This will copy the executable to the output/target
folder, which contains the root filesystem produced by Buildroot. Then invoking Buildroot’s make
will ensure that the root filesystem and SD card images get re-generated. Of course, beware that if you run a Buildroot make clean
, all the contents of output/
, including output/target/
get removed. So this technique is only suitable for temporary changes. This is fine since anyway as discussed above, ultimately we’ll have a proper Buildroot package to build our qt-sensor-demo application.
Reflash your SD card with the new image, and on the target, run the demo:
# qt-sensor-demo -platform linuxfb
Setting SSH for communication with the board
Regenerating the SD card image and reflashing the entire SD card every time we want to change our application is not going to be very efficient during the application development/debugging. So instead, we’ll set up networking communication with the board, and use SSH to transfer files. This will also be useful for Qt Creator, as it uses SFTP to deploy files to the target.
Let’s start by enabling a small SSH client/server, called Dropbear. Go in Buildroot menuconfig, and enable the BR2_PACKAGE_DROPBEAR
option (in Target packages, Networking applications, dropbear). While Dropbear provides SSH access, it does not support SFTP which will be needed by Qt Creator, so we’ll also enable an SFTP server, gesftpserver. So, we’ll enable BR2_PACKAGE_GESFTPSERVER
as well (in Target packages, Networking applications, gesftpserver).
Then, in order to log in through SSH as root, we must have a non-empty root password, so set BR2_TARGET_GENERIC_ROOT_PASSWD
(in System configuration, Root password) to a value you like.
You can now exit menuconfig, as we have enabled all features we needed. Before restarting the build, we need to do one last thing: set up a network configuration file so that our STM32MP15 system configures an IP address. To do this, we’ll create a /etc/network/interfaces
file, and add it to the root filesystem using the root filesystem overlay mechanism, which was presented in the first post of this series. So, in your Buildroot sources, just create a file board/stmicroelectronics/stm32mp157-dk/overlay/etc/network/interfaces
, with the following contents:
auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 192.168.42.2 netmask 255.255.255.0
This will ensure the eth0
interface of our target gets configured with the 192.168.42.2
IP address. Of course, feel free to use a different IP address.
Then, run make
in Buildroot, reflash your SD card, and boot your system. At boot time, you should see:
Starting dropbear sshd: OK
You can also run ip addr show dev eth0
to check the IP address of the eth0
interface:
2: eth0:mtu 1500 qdisc mq qlen 1000 link/ether 00:80:e1:42:4d:e3 brd ff:ff:ff:ff:ff:ff inet 192.168.42.2/24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::280:e1ff:fe42:4de3/64 scope link valid_lft forever preferred_lft forever
So the IPv4 address is properly set to 192.168.42.2
, as expected.
Now, on your workstation, we need to configure the 192.168.42.1
static IP address so that you can connect to your board. It is very likely that the Linux system on your workstation is using NetworkManager. Let’s add a connection:
$ nmcli con add con-name buildroot-target type ethernet ifname enp57s0u1u3 ip4 192.168.42.1/24 Connection 'buildroot-target' (234e0d9a-5c4f-4eac-9277-c3587bbd370d) successfully added.
Make sure to replace enp57s0u1u
by the name of your PC wired interface, to which the board is connected. We of course assume you have an Ethernet cable directly connecting your PC to the board.
Finally, enable the connection:
$ nmcli con up id buildroot-target Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/10)
We can now ping our target:
$ ping 192.168.42.2 PING 192.168.42.2 (192.168.42.2) 56(84) bytes of data. 64 bytes from 192.168.42.2: icmp_seq=1 ttl=64 time=1.33 ms
Log-in over SSH:
$ ssh root@192.168.42.2 root@192.168.42.2's password: # uname -a Linux buildroot 4.19.26 #1 SMP PREEMPT Wed Aug 28 15:54:58 CEST 2019 armv7l GNU/Linux # cat /etc/issue Welcome to Buildroot #
And verify that SFTP is working:
$ sftp root@192.168.42.2 root@192.168.42.2's password: Connected to root@192.168.42.2. sftp> ls / /bin /boot /dev /etc /lib /lib32 /linuxrc /lost+found /media /mnt /opt /proc /root /run /sbin /sys /tmp /usr /var sftp>
So, now we can make a change to our Qt5 application, for example changing the label of the button, recompile by running make
in the application directory, and directly copy the application using scp
, and run it over ssh
:
$ make [...] $ scp qt-sensor-demo root@192.168.42.2:/usr/bin/ root@192.168.42.2's password: qt-sensor-demo 100% 12KB 634.7KB/s 00:00 $ ssh root@192.168.42.2 root@192.168.42.2's password: # qt-sensor-demo -platform linuxfb
Much nicer, we don’t have to reflash our SD card every time we want to test a change in our application!
Note that we could create a public/private key pair, with the public key on our target, and this way not have to enter our password every time we want to transfer a file or log-in to the target. Since this blog post is already very long, we’ll live that as an exercise for the reader, there are plenty of resources on the Web about this topic.
Setting up Qt Creator
Some people (such as your author) are happy with using a powerful text editor (such as Vim or Emacs) and a terminal to do their application development. But others are sometimes more comfortable with an integrated development environment (IDE). So in this section, we’ll see how to set up Qt Creator to write, build, deploy and debug a Qt5 application.
Installing Qt Creator
First of all, you’ll have to install Qt Creator, which you can do using the package management system of your distribution. On Fedora systems, this would be:
$ sudo dnf install qt-creator
On Debian/Ubuntu systems:
$ sudo apt install qtcreator
The following instructions have been written and tested against Qt Creator version 4.9.2.
Creating a kit
After starting Qt Creator, the first thing to do is to create a kit, which describes the cross-compiler and Qt installation provided by Buildroot. Go to Tools -> Options
, and the first item should be Kits:
Click on Add
, and fill in the different fields as follows:
- Name:
Buildroot ARM
- Device type:
Generic Linux Device
- Sysroot:
/path/to/buildroot/output/host/arm-buildroot-linux-gnueabihf/sysroot/
. Of course, replace/path/to/buildroot/
with the appropriate path on your system. - For the compiler, click on Manage, then in the Compiler panel:
- Add one GCC C compiler, with the name
Buildroot GCC
and pointing to/path/to/buildroot/output/host/bin/arm-linux-gnueabihf-gcc
- Add one GCC C++ compiler, with the name
Buildroot G++
and pointing to/path/to/buildroot/output/host/bin/arm-linux-gnueabihf-g++
- Add one GCC C compiler, with the name
- Back in the Kits panel, select Buildroot GCC and Buildroot G++ as the C and C++ compilers, respectively.
- For the debugger, click on Manage, then in the debugger panel add one debugger named
Buildroot GDB
, and pointing to/path/to/buildroot/output/host/bin/arm-linux-gnueabihf-gdb
. Back in the Kits panel, select Buildroot GDB as our debugger. - For the Qt version, click on Manage, then on Add, and point to the
qmake
binary in/path/to/buildroot/output/host/bin/
. It will auto-detect that Buildroot has built Qt 5.11.3. You may want to adjust the version name fromQt %{Qt:Version} (host)
toQt %{Qt:Version} (Buildroot)
, as this Qt version is clearly not built for our host PC. Then back in the Kits panel, select this new Qt version. - For the Qt mkspec, enter
devices/linux-buildroot-g++
, which is the name of the mkspec configuration Buildroot generates.
You’ll find below screenshots of the various panels, with the details related to the Buildroot cross-compiler, cross-debugger and Qt installation:
We’re now done configuring a Kit!
Creating a device
In order to allow Qt Creator to deploy our application to the device, run it and debug it, we need to create a Device. Go again in Tools -> Options
, and this time go to the Devices panel.
In the first window, select Generic Linux Device.
Then, for the device name, use STM32MP15 Discovery board
for example, for the IP address, 192.168.42.2
and for the user, root
, which should give:
In the next step about Key deployment, simply skip to the next section, as we have not created a private/public key pair, as explained previously in this blog post. You can then finalize the device creation. Qt Creator will now test that it can communicate as expected with our device:
As you can see, it doesn’t find rsync
on the target, because we have not installed it. It will use sftp
instead, which is fine.
Back in the Device panel, you should see our device definition as follows:
You can click on Open Remote Shell to directly open a shell over SSH to your target, or Show Running processes.
Our device is now set up correctly, time to create our first application!
Importing our project
We now want to import our qt-sensor-demo project in Qt Creator. To do so, go in File -> Open File or Project
, then browse to the directory containing our qt-sensor-demo application, and select both the main.cpp
and qt-sensor-demo.pro
files, and click Open. Qt Creator should now switch to a Configure project window, where it asks you to select the Kit to use for this project. Obviously, select the Buildroot ARM kit we have just created, and validate by clicking Configure Project:
You should now see our project imported, with both of its files, and main.cpp
is opened by default:
If we now use Build -> Build All
, and then go in the Compile Output
panel, we see:
13:11:58: Running steps for project qt-sensor-demo... 13:11:59: Starting: "/home/thomas/projets/outputs/st/host/bin/qmake" /home/thomas/qt-sensor-demo/qt-sensor-demo.pro -spec devices/linux-buildroot-g++ CONFIG+=debug CONFIG+=qml_debug Info: creating stash file /home/thomas/build-qt-sensor-demo-Buildroot_ARM-Debug/.qmake.stash 13:11:59: The process "/home/thomas/projets/outputs/st/host/bin/qmake" exited normally. 13:11:59: Starting: "/usr/bin/make" -f /home/thomas/build-qt-sensor-demo-Buildroot_ARM-Debug/Makefile qmake_all make: Nothing to be done for 'qmake_all'. 13:11:59: The process "/usr/bin/make" exited normally. 13:11:59: Starting: "/usr/bin/make" -j4 /home/thomas/projets/outputs/st/host/bin/arm-linux-gnueabihf-g++ -c -pipe -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -Og --sysroot=/home/thomas/projets/outputs/st/host/arm-buildroot-linux-gnueabihf/sysroot -g -Wall -W -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../qt-sensor-demo -I. -I../projets/outputs/st/host/arm-buildroot-linux-gnueabihf/sysroot/usr/include/qt5 -I../projets/outputs/st/host/arm-buildroot-linux-gnueabihf/sysroot/usr/include/qt5/QtWidgets -I../projets/outputs/st/host/arm-buildroot-linux-gnueabihf/sysroot/usr/include/qt5/QtGui -I../projets/outputs/st/host/arm-buildroot-linux-gnueabihf/sysroot/usr/include/qt5/QtCore -I. -I../projets/outputs/st/host/mkspecs/devices/linux-buildroot-g++ -o main.o ../qt-sensor-demo/main.cpp /home/thomas/projets/outputs/st/host/bin/arm-linux-gnueabihf-g++ --sysroot=/home/thomas/projets/outputs/st/host/arm-buildroot-linux-gnueabihf/sysroot -o qt-sensor-demo main.o -lQt5Widgets -lQt5Gui -lQt5Core -lrt -ldl -latomic -lpthread 13:12:00: The process "/usr/bin/make" exited normally. 13:12:00: Elapsed time: 00:02.
So we see that it is invoking qmake
from Buildroot, and then running make
, which builds our application, with the appropriate cross-compiler provided by Buildroot!
The application has been built in /home/thomas/build-qt-sensor-demo-Buildroot_ARM-Debug
, which contains:
-rw-rw-r-- 1 thomas thomas 620760 30 août 13:12 main.o -rw-rw-r-- 1 thomas thomas 31522 30 août 13:11 Makefile -rwxrwxr-x 1 thomas thomas 516504 30 août 13:12 qt-sensor-demo
Running the application on the target
In order for Qt to deploy our application on the target, we need to adjust our .pro
file so that it has directives to install the application. We’ll simply make our .pro
file look like this:
QT += widgets SOURCES = main.cpp INSTALLS += target target.path = /usr/bin
We invite you to read the relevant part of the Qt documentation to get details about the INSTALLS
directive and the special target
keyword.
Before we can really deploy on your target, we need to adjust the Run configuration, so click on the Project icon in the left bar, which should bring you to:
We’re seeing the Build settings, so click on Run to see the Run settings. Everything should already be auto-detected: we want to deploy qt-sensor-demo
to /usr/bin
on the target, the target is STM32MP15 Discovery board. The only thing we need to change is to set Command line arguments to -platform linuxfb
. Your settings should then look like this:
Now, you can finally do Build -> Run
. Qt Creator will prompt you for the root password of your target, and automatically deploy and run the application!
Just to test it, make a change to the QPushButton
label, and do Build -> Run
again. You’ll see the new version of your application running!
Debugging your application
The last part in setting up our development environment is to be able to debug our application from Qt Creator. This involves remote debugging, where the debugger runs on your workstation, while the program being debugged runs on a separate target. As part of the Kit definition done previously, we have already told Qt Creator where the cross debugger provided by Buildroot is.
Now, we need to have gdbserver on the target, which is the program with which the cross-debugger will communicate to control the execution of our application on the target. To achieve this, go to the Buildroot menuconfig, and enable the option BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY
, in Toolchain -> Copy gdb server to the Target
. With this done, we now need to have Buildroot take this change into account. Unfortunately simply running make will not take this change into account (see here for more details). We could do a full clean rebuild of Buildroot (make clean all
), but that would take quite some time, so we’ll ask Buildroot to only reinstall the toolchain
package and regenerate the root filesystem image:
make toolchain-external-arm-arm-reinstall all
Reflash your SD card, and reboot the system. You should now have gdbserver available on the target:
# ls -l /usr/bin/gdbserver -rwxr-xr-x 1 root root 355924 Aug 29 2019 /usr/bin/gdbserver
We’ll now change a bit our program with some additional dummy code to play around with the debugger:
#include <QApplication> #include <QPushButton> int main(int argc, char* argv[]) { int a = 42; QApplication app(argc, argv); QPushButton hello("Hello world!"); a++; qDebug("Test 1"); a++; qDebug("Test 2"); hello.resize(100,30); hello.show(); return app.exec(); }
Place a breakpoint on the line QApplication app(argc, argv)
by clicking to the left of this line, it should show a red dot, like this:
Then you can start debugging by clicking on the following button in the left bar:
It will switch to the debug view, with the program stopped at our breakpoint:
At the bottom of the screen, click on Application Output
so that we can see the stdout of the application running on the target. Now hit F10
to step through our code line by line. You should then see the value of the variable a
updated in the top right panel, and the Test 1
and then Test 2
messages printed in the application output:
So, as expected, we are able to debug our application! This concludes the setup of Qt Creator, which allows us to very easily make a change to our application, build it, deploy it on the target and debug it.
Building using a Buildroot package
Before we conclude this article, we want to see how to integrate the build of our application with Buildroot. Indeed, building the application manually or through Qt Creator is perfectly fine during the active development of the application. But in the end, we want Buildroot to be able to build our complete system, including all the applications and libraries we have developed, in a fully automated and reproducible fashion.
To achieve this, in this section, we’ll create a Buildroot package for our qt-sensor-demo application. A package in Buildroot speak is a small set of metadata that tells Buildroot how to retrieve and build a particular piece of software.
To learn how to create a Buildroot package, we suggest you to read the relevant section of the Buildroot manual, or to read the slides of our Buildroot training course. The following steps will however guide you in the process of creating our qt-sensor-demo package.
First, in the Buildroot source tree, create a package/qt-sensor-demo/
directory. Then, create a file named package/qt-sensor-demo/Config.in
, which describes one configuration option to be able to enable/disable this package from Buildroot’s menuconfig:
config BR2_PACKAGE_QT_SENSOR_DEMO bool "qt-sensor-demo" depends on BR2_PACKAGE_QT5 select BR2_PACKAGE_QT5BASE_WIDGETS help This is the qt-sensor-demo application.
Note that the bool
, depends on
, select
and help
keywords need to be prefixed with a tab (not spaces), and that the BR2_PACKAGE_QT_SENSOR_DEMO
string should be exactly as-is, as it needs to match the name of the directory qt-sensor-demo
.
This Config.in
file basically creates a boolean option which will appear as qt-sensor-demo
in menuconfig. The depends on BR2_PACKAGE_QT5
definition ensures that our option will only be selectable if Qt5 is available, while select BR2_PACKAGE_QT5BASE_WIDGETS
makes sure Qt5 will be built with QtWidgets support, as we use them.
Now, edit the existing package/Config.in
file, and at a relevant place (perhaps Graphic libraries and applications, submenu Graphic applications), you need to add:
source "package/qt-sensor-demo/Config.in"
So that Buildroot’s menuconfig properly includes and reads our new package Config.in
file. Now, if you run make menuconfig
in Buildroot, you should be able to see our new option and enable it. Of course for now, it doesn’t do anything useful.
The next step is to create a qt-sensor-demo.mk
file in package/qt-sensor-demo/
to teach Buildroot how to build our package. This .mk
file is a Makefile, which uses a number of Buildroot-specific variables and macros, to a point where it doesn’t really look like a typical Makefile. In our case, qt-sensor-demo.mk
will look like this:
################################################################################ # # qt-sensor-demo # ################################################################################ QT_SENSOR_DEMO_SITE = $(TOPDIR)/../qt-sensor-demo QT_SENSOR_DEMO_SITE_METHOD = local QT_SENSOR_DEMO_DEPENDENCIES = qt5base define QT_SENSOR_DEMO_CONFIGURE_CMDS (cd $(@D); $(QT5_QMAKE)) endef define QT_SENSOR_DEMO_BUILD_CMDS $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) endef define QT_SENSOR_DEMO_INSTALL_TARGET_CMDS $(INSTALL) -D -m 0755 $(@D)/qt-sensor-demo $(TARGET_DIR)/usr/bin/qt-sensor-demo endef $(eval $(generic-package))
The first two variables, QT_SENSOR_DEMO_SITE
and QT_SENSOR_DEMO_SITE_METHOD
tell Buildroot how to retrieve the source code for this application. Most Buildroot packages retrieve tarballs of source from HTTP servers, or clone source code from Git repositories. But in the case of our package, we are simply taking the source from the qt-sensor-demo
directory, located just one level up from the main Buildroot source directory.
The QT_SENSOR_DEMO_DEPENDENCIES
variable tells Buildroot that the qt5base
package needs to be built before qt-sensor-demo
gets built.
The QT_SENSOR_DEMO_CONFIGURE_CMDS
variable describes the commands to run to configure our package. Here, we simply call Qt’s qmake utility, using the Buildroot-provided variable QT5_QMAKE
.
The QT_SENSOR_DEMO_BUILD_CMDS
variable describes the commands to run to build our package. In our case, we invoke make in the application directory, $(@D)
, passing appropriate variables in the environment ($(TARGET_MAKE_ENV)
).
Then, the QT_SENSOR_DEMO_INSTALL_TARGET_CMDS
variable describes the commands to run to install our package. We simply copy the qt-sensor-demo
executable from the build directory ($(@D)
) to usr/bin
in the target directory.
Finally, the generic-package
macro invocation is what triggers the Buildroot machinery to create a package. Read the Buildroot manual and/or our Buildroot training slides for more details.
With this in place, if you have already enabled qt-sensor-demo
in menuconfig, when you run make in Buildroot, you should see:
>>> qt-sensor-demo Syncing from source dir /home/thomas/qt-sensor-demo rsync -au --chmod=u=rwX,go=rX --exclude .svn --exclude .git --exclude .hg --exclude .bzr --exclude CVS /home/thomas/qt-sensor-demo/ /home/thomas/buildroot/output/build/qt-sensor-demo >>> qt-sensor-demo Configuring (cd /home/thomas/buildroot/output/build/qt-sensor-demo; /home/thomas/buildroot/output/host/bin/qmake -spec devices/linux-buildroot-g++) >>> qt-sensor-demo Building PATH="..." /usr/bin/make -j5 -C /home/thomas/buildroot/output/build/qt-sensor-demo /home/thomas/buildroot/output/host/bin/arm-linux-gnueabihf-g++ --sysroot=/home/thomas/buildroot/output/host/arm-buildroot-linux-gnueabihf/sysroot -Wl,-O1 -o qt-sensor-demo main.o -L/home/thomas/buildroot/output/host/arm-buildroot-linux-gnueabihf/sysroot/usr/lib -lQt5Widgets -lQt5Gui -lQt5Core -lrt -ldl -latomic -lpthread >>> qt-sensor-demo Installing to target /usr/bin/install -D -m 0755 /home/thomas/buildroot/output/build/qt-sensor-demo/qt-sensor-demo /home/thomas/buildroot/output/target/usr/bin/qt-sensor-demo
You’re seeing:
- Buildroot copying the source code from its original location to the Buildroot build directory
- Buildroot configuring the build of our package by invoking qmake
- Buildroot building our application
- Buildroot installing our application
The application being installed in Buildroot’s target directory, it is automatically part of the root filesystem image, and consequently the SD card image sdcard.img
. You can flash it again, and see that you have the same application.
Now, if you want to change the source code of your application, you can simply change it in its original location, the qt-sensor-demo
directory, and issue the following command in Buildroot:
$ make qt-sensor-demo-rebuild all
Buildroot will synchronize again the source code from its original directory to Buildroot’s build directory, and rebuild the application. It will only transfer the files that have changed, and only rebuild the files that have changed. The all
target ensures that the root filesystem and SD card images get regenerated with the new version of the code.
Conclusion
In this article, we’ve seen many things:
- How to create and manually build our first Qt5 application
- How to deploy our application to the target by adding it to the SD card
- How to set up network communication, and SSH, to deploy our application more efficiently during development
- How to set up Qt Creator as a development environment to write, build, deploy and debug our application
- How to create a Buildroot package to automate the build of our application
You can find the Buildroot changes corresponding to this blog post in the 2019.02/stm32mp157-dk-blog-4 branch of our repository. The qt-sensor-demo
application code can be found in the blog-4 branch of this application Git repository.
In our next blog post, we’ll extend our qt-sensor-demo
application to make it really useful!