Embedded ARM Qt with DBUS and TSLIB support

Embedded ARM Qt with DBUS and TSLIB support


This post explains how to build Qt for an embedded board with dbus and tslib support. It also describes how to remotely deploy your applications from the host machine using the Qt Creator IDE to the target board and remotely debug them.

In order to remotely deploy and debug applications on an embedded linux device, your device requires both an SSH and SFTP server built into the root file system. You also need a cross-compiler to build the application for your target and a debugger included in the toolchain.

Once these tools are in place you can build Qt for the target. The first step is to download the latest Qt source.

First edit the qt-src/mkspecs/linux-arm-gnueabi/qmake.conf file to configure qmake. My qmake.conf file looked like:

#

# qmake configuration for building with arm-linux-gnueabi-g++

#

MAKEFILE_GENERATOR = UNIX

TARGET_PLATFORM = unix

TEMPLATE = app

CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index

QT += core gui

QMAKE_INCREMENTAL_STYLE = sublib

include(../common/linux.conf)

include(../common/gcc-base-unix.conf)

include(../common/g++-unix.conf)

# Compiler Flags

QMAKE_CFLAGS = -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mthumb

QMAKE_CXXFLAGS = -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mthumb

# modifications to g++.conf

QMAKE_CC = /my/toolchain/pathbin/arm-linux-gnueabi-gcc

QMAKE_CXX = /my/toolchain/pathbin/arm-linux-gnueabi-g++

QMAKE_LINK = /my/toolchain/pathbin/arm-linux-gnueabi-g++

QMAKE_LINK_SHLIB = /my/toolchain/pathbin/arm-linux-gnueabi-g++

# modifications to linux.conf

QMAKE_AR = /my/toolchain/pathbin/arm-linux-gnueabi-ar cqs

QMAKE_OBJCOPY = /my/toolchain/pathbin/arm-linux-gnueabi-objcopy

QMAKE_STRIP = /my/toolchain/pathbin/arm-linux-gnueabi-strip

# Include tslib

QMAKE_INCDIR += /usr/local/tslib/include/

QMAKE_LIBDIR += /usr/local/tslib/lib/

QMAKE_LFLAGS += -Wl,-rpath -Wl,/usr/local/tslib/lib

QMAKE_LFLAGS += -Wl,-rpath -Wl,/usr/local/tslib/lib/ts

load(qt_config)

The next step is to compile dbus and tslib. Download expat-2.1.0 ( XML support ) required by dbus and build and install using the following commands:

make clean ; make distclean ; ./configure --host=arm-linux --prefix=/usr/local/expat/ CC=/path/to/toolchain/arm-linux-gnueabi-gcc

make

sudo make install

Download dbus (dbus-1.5.0 ) and build and install using the following commands:

make clean ; export NM=nm && ./configure --prefix=/usr/local/dbus/ --host=arm-linux --with-x=no ac_cv_have_abstract_sockets=yes "CC=/path/to/toolchain/arm-linux-gnueabi-gcc -I/usr/local/expat/include -L/usr/local/expat/lib

make

sudo make install

Download the latest tslib and build and install using the following commands:

sudo ./autogen-clean.sh ;sudo ./autogen.sh ;sudo export ac_cv_func_malloc_0_nonnull=yes ; sudo export PATH=%s:$PATH ; sudo ./configure CC=/path/to/toolchain/arm-linux-gnueabi-gcc CXX=/path/to/toolchain/arm-linux-gnueabi-g++ --host=arm-linux --prefix=/usr/local/tslib --enable-shared=yes --enable-static=yes

sudo make

sudo make install

Now build Qt itself. Download the latest source and run the configure program inside the source directory. Here was my configure ( I included Touch Screen support ( tslib ) and dbus ), I also show the make and make install steps here:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/tslib/lib/ts ; export PKG_CONFIG_PATH=/usr/local/dbus/lib/pkgconfig ; ./configure -opensource -confirm-license -prefix /opt/arm -embedded -arch arm -xplatform linux-arm-gnueabi-g++ -qt-mouse-tslib -lrt -dbus -force-pkg-config -no-phonon -no-webkit -no-qt3support -little-endian -nomake examples -nomake tools -nomake translations

make

sudo make install

The steps above create a qmake file in the qt-src/bin directory that describes the Qt installation for the embedded board. Building Qt will take awhile so be patient.

Now let's setup Qt Creator for remote deployment and debugging on the target board from your host machine.

Open Qt Creator and add click on Tools > Options > Build & Run from the top menubar. Now click on Toolchains > Manual > Add and add the path to your cross compiler bin directory. Next click on Qt Versions > Manual > Add and add the path to the Qmake executable that is in the qt-src/bin directory created when we built Qt a few lines back.

Now we have successfully linked our toolchain ( and optionally debugger ) and also our Qmake executable describing our cross-compiled Qt Libraries.

The next step is to setup remote deployment for our target. Click on Tools > Options > Linux Devices from the top menubar. Now click on Linux Devices and click Add. Entire your ip address for the target board ( typically static ) as well as the credentials to reach the board. You must have an SSH and SFTP server running on the target embedded board. After filling out the form click the Test button. If everything is correctly configured you will see a 'success' message like the screenshot below.

Now open a demo Qt application or make your own. Then click on Projects on the left-hand side of Qt Creator. There are 2 tabs to look at here, Build and Run. The following screenshots show my setup for these screens. The important this is to configure the Run options to use the Linux Device configuration you specified in the last step and to make sure the Remote Directory exists on the board. You can change this remote directory by modifiying the target parameter in the .pro file. Also, make sure you specify the -qws argument so that the application will appear on your screen using the Linux framebuffer, if you do have a screen enabled and attached.

Also configure your Build settings to point to the Qmake file you setup under the Tools menu and also specify the correct Toolchain that your also configured under the Tools menu.

Now you should be able to click the Run or Debug buttons ( green triangles ) and run your application from your host machine within Qt Creator on the target embedded Linux Board.

If your application expects stdin and you want to pass command line strings or input to the application, you can do so with named pipes. Just open a new terminal in Ubuntu on the host machine and SSH to your board. Now type the following:

mkfifo mypipe

echo somestring > mypipe

Now in the Run settings for your application launch the app with the following 'Alternate Executable on Device':

tail -f mypipe | /home/test/app -qws

Re-launch the app. Now you can echo data in your SSH terminal to the named pipe and your application will accept the input as stdin!

Feel free to leave feedback - happy coding



ClassyBits 2016