Login procedures have been improved. Check this page for details.

Devices/RaspberryPi

From QtProject
< Devices
Revision as of 08:38, 19 April 2012 by Dcarr (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Raspberry Pi (BCM2835): Device Information

Architecture ARMv6
CPU ARM11
RAM 256MB (shared)
GPU VideoCore IV
OpenGL OpenGL ES 2.0
Multimedia OpenMax IL 1.1.2
Qt 5.0 (eglfs/QPA) Supported, with OpenGL ES 2.0
"The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It’s a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming."
[1] Raspberry Pi Foundation FAQ

Hardware Details

Low end ARM11 CPU running at ~700 BogoMIPS. VideoCore IV GPU is capable of running QtQuick2/SceneGraph at high resolutions. Both CPU and GPU share main memory.

Linux Platform

If you are not interested in building everything yourself then consider:

  • the pre-built Debian snapshots
  • the QtonPi project, which aims to build a more complete end-to-end Qt stack specifically targeting the Raspberry Pi.

The Raspberry Pi Foundation provides a few different distributions. This documentation is tested on the Debian "Squeeze" image, which can be downloaded here. The images come with the needed packages for the VideoCore GPU and a suitable kernel. Additionally there are three different start.elf files located in /boot. Those are GPU binary firmware images, provided by the Raspberry Pi Foundation, which can be used to select the amount of memory available for the GPU.

Building AppLibs/RefSW for Qt

Helper scripts

These scripts will be cited at relevant sections and are intended as a rough guide as to the automation of labourious tasks.

https://gitorious.org/cross-compile-tools/cross-compile-tools

Use when prompted at your own disgression.

Adjusting the root filesystem for development

Qt 5 has a hard dependency on libudev for hot pluggable hardware detection/support. This mandates the installation of the libudev-devel package. (Or the filthy use of an arbitrary libudev.h and the creation of a libudev.so symlink, which is how we roll in the trenches(When life gives you mustard gas, eat franks!)) (This consideration will fall away with the release of the next Debian reference image)

In order to use the root filesystem from the SD card, mount the rootfs partition as a loopback device, you might need root access. The offset for mount can change with different images, please query the partition offset with fdisk.

$ mkdir /mnt/rasp-pi-rootfs
$ mount -o loop,offset=$((512*157696)) debian6-17-02-2012.img /mnt/rasp-pi-rootfs

eg (or the official Debian image(s)):

$ #mount -o loop,offset=80740352 /opt/bulk-overflow/images/debian6-17-02-2012/debian6-17-02-2012.img /mnt/rasp-pi-rootfs

In order to be able to use the --sysroot option during the Qt build process, you have to resolve all absolute library links inside the mounted rootfs, but replacing full qualified symlinks with relative ones, otherwise the linker will pickup your host libraries and promptly barf. The magical fixQualifiedLibraryPaths script in the cross-compile-tools repo above should be run in ./usr/lib of your targets rootfs and will presumptious replace all symlinks linking to /lib/foo with ../../lib/foo.

You will also need to create several missing symlinks, notably: libstdc++.so (/usr/lib) and libgcc_s.so (/lib) (and any other friends of the forest who rear their frothy maws with the earnest intent to munch on you)

This might seem hacky but it is important that we pass the reference debian image to the code sourcery toolchain to ensure that we are linking against the right system libraries, and not toolchain libs in conflict with the libraries on the actual device.

Additional packages

These are entirely optional since the base Debian image has all the development requires for GLESv2 and input support.

libicu-dev (Webkit requires it)

I personally install it on the device, shuttle across the .deb, unarchive it and unpack the data.tar.gz over the original mounted image.

Toolchain

we are using the Code Soucery 2011.09 release, available here:

https://sourcery.mentor.com/sgpp/lite/arm/portal/release2029

Qt 5 on the Raspberry Pi (BCM2835)

Installing Qt 5 nightlies from the repo

We are generating Qt 5 nightlies for the Raspberry PI reference Debian image, and these are available here:

http://archive.qmh-project.org/rpi/debian/pool-armel/

this is already shipped as part of the reference image, and hence all you need to do to get piping hot Qt 5 action in your life is:

apt-get update apt-get install qt50-snapshot

Building Qt

This will build everything in-source, if you want to build out-of-source execute configure and qmake for additional modules from within a separate empty folder.

qtbase

$ cd <qtbase>
$ ./configure -prefix <your prefix> -release \
  -device linux-rasp-pi-g++ -make libs \
  -device-option CROSS_COMPILE=<your toolchain path>/bin/arm-none-linux-gnueabi-
  -sysroot <your sysroot path>
$ make install

Other modules

Depending on your needs/desires you can now use your freshly minted qmake to (shadow) build whatever Qt 5 modules you require, using the following approach:

$ cd <qt_module_dir>
$ <your prefix>/bin/qmake
$ make
$ make install

At a bare minimum we would recommend: qtjsbackend and qtdeclarative

Runtime information

We would like to get Wayland up and running on the Pi but this requires modifications to EGL that need to be provided by the chipset vendor, Broadcom in this case. We therefore explicit set the default plugin to be the eglfs plugin which is ideal for single process use cases like set top boxes. (This can be overridden by explicitly using -platform if you see fit).

If you want keyboard support, you need to either explicitly pass -plugin EvKeyboard to your application or export this as part of your base environment via QT_QPA_GENERIC_PLUGINS. (Please note, the keyboard driver currently has a hard dependency on udev support)

Building and running qtwayland (NEW)

These instructions cover how to get qtwayland up and running, with plain SHM buffers (shared memory raster images, so no OpenGL acceleration on the client side yet, for that we'd need some kind of cross process buffer sharing mechanism in the GPU drivers).

First, clone and build qtjsbackend and qtdeclarative per the instructions above.

Now we're going to have to cross compile libffi and wayland. First we need to set up our environment with the following environment variables:

export RPI_SYSROOT=/mnt/rasp-pi-rootfs
export TOOLCHAIN=$HOME/raspberry/arm-2011.09
export QTDIR=$HOME/raspberry/qt5/qtbase
export PATH=$QTDIR/bin:$TOOLCHAIN/bin:$PATH
export PREFIX=/opt/myqt
export PKG_CONFIG_PATH="$RPI_SYSROOT/usr/lib/pkgconfig:$RPI_SYSROOT/opt/myqt/lib/pkgconfig:$RPI_SYSROOT/opt/myqt/share/pkgconfig"
export PKG_CONFIG_SYSROOT_DIR="$RPI_SYSROOT"
export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1
export CPP=$TOOLCHAIN/bin/arm-none-linux-gnueabi-cpp
export CC=$TOOLCHAIN/bin/arm-none-linux-gnueabi-gcc
export CXX=$TOOLCHAIN/bin/arm-none-linux-gnueabi-g++
export CFLAGS="--sysroot=$RPI_SYSROOT"
export CXXFLAGS="--sysroot=$RPI_SYSROOT"
export CPPFLAGS="--sysroot=$RPI_SYSROOT"
export LD=$TOOLCHAIN/bin/arm-none-linux-gnueabi-ld
export LDFLAGS="--sysroot=$RPI_SYSROOT"
export AS=$TOOLCHAIN/bin/arm-none-linux-gnueabi-as
export STRIP=$TOOLCHAIN/bin/arm-none-linux-gnueabi-strip
export AR=$TOOLCHAIN/bin/arm-none-linux-gnueabi-ar

Make sure to replace the RPI_SYSROOT, TOOLCHAIN, and QTDIR variables with your equivalents. PREFIX should be whatever you used when configuring Qt above. Now we're ready to cross compile. First, for libffi:

git clone git://github.com/atgreen/libffi.git
cd libffi
./configure --host=arm-linux --prefix=$RPI_SYSROOT$PREFIX
make
sudo make install

Unfortunately this produces a pkg-config file that has a redundant prefix. Edit $RPI_SYSROOT/$PREFIX/lib/pkgconfig/libffi.pc and remove the $RPI_SYSROOT part from the "prefix=" line, leaving it just as $PREFIX.

As for wayland, we first need to build it for the host to get the wayland-scanner binary which reads wayland extension .xml's and produces C interfaces. You might need to install libffi-dev and libexpat-dev on your host as well for this. You also need to set WAYLAND_SHA1 according to the wayland_sha1.txt in the qtwayland repo, so that we get a compatible version.

Make sure to run these in a clean environment, not the cross compile environment we set up earlier. You may copy wayland-scanner to anywhere as long as it ends up in the $PATH later on.

git clone git://anongit.freedesktop.org/wayland/wayland
cd wayland
git checkout $WAYLAND_SHA1
./autogen.sh
make
cp src/wayland-scanner $QTDIR/bin

Now to build wayland for the target. Again make sure the cross compile environment above is sourced. This time we disable the scanner, as we don't want it as an arm binary.

cd wayland
git clean -dxf
./autogen.sh --host=arm-linux --prefix=$RPI_SYSROOT$PREFIX --disable-scanner
make
sudo make install

Again we need to fix some pkgconfig files. Edit $RPI_SYSROOT/$PREFIX/lib/pkgconfig/wayland-client.pc and wayland-server.pc as for libffi.pc above, removing the $RPI_SYSROOT from the prefix variable. This is required for qtwayland to successfully build.

Now we get to, as we say in Norway, the raisin in the sausage, namely qtwayland. Since we have no hardware integration / buffer sharing mechanism, we configure it with nogl. This means only raster based clients will be able to run. The -lffi addition is necessary for some reason I haven't figured out.

export QT_WAYLAND_GL_CONFIG=nogl
cd qtwayland
echo "LIBS += -lffi" >> src/compositor/compositor.pri 
cd src
qmake
make && sudo make install
cd ../examples/
qmake
make && sudo make install

I ran into some issues where make failed due to requiring sudo permissions, but following the steps above should give you a working install.

Now it's time to test the stuff we've built. I typically do "rsync -av $RPI_SYSROOT/$PREFIX root@rpi:$PREFIX", but whatever floats your boat.

ssh into the device, and go to the examples/qtwayland/qml-compositor folder, then do as follows:

export XDG_RUNTIME_DIR=/tmp
export QT_COMPOSITOR_NEGATE_INVERTED_Y=1
./qml-compositor -platform eglfs

The XDG_RUNTIME_DIR is where the wayland socket ends up, and QT_COMPOSITOR_NEGATE_INVERTED_Y is because qml-compositor is otherwise vertically challenged. You should now have the qml-compositor running in all its glory, time to add some clients.

If you've build and installed wiggly from qtbase/examples/widgets/wiggly, here's how to run it:

export XDG_RUNTIME_DIR=/tmp
./wiggly -platform wayland&
./wiggly -platform wayland&

This launches two beautiful wiggly instances as wayland clients. Bon Appétit!

Qt 4 on the Raspberry Pi (BCM2835)

Qt 4 runs on the Pi with minor modification and using the following spec:

https://gitorious.org/qt-platform-mkspecs/qt-platform-mkspecs/trees/master/4.8/linux-rasp-pi-g++

there are inherent graphical constraints in the Qt 4 architecture that make spending any significant time in adapting Qt 4 to the Raspberry Pi seem a little pointless. We merrily welcome anyone else's passion/contributions towards this end.

Personal tools
license
Attribution-ShareAlike 2.5 Unported