Coding Chase - Projects

My 3D Hub

Thank You For Donating:

Ikeeki (linux-sunxi@irc.freenode.net)
Computer Troubleshooters Brasil

Thursday 29 May 2014

Cubieboard, Qt 5 on Framebuffer and VSync

My personal goals with Qt 5 and Cubieboard have always been to try to get the most bang for my buck.

On cubieboard A20/cubietruck, using r3p2-01rel02 Mali libraries and some tweaking in the fex script it's actually possible to make use of all the power in the GPU and see the FPS go up.

On framebuffer though, going on 80+ FPS and above, it becomes noticeable that some animations display a sort of tearing effect: the vertical refresh rate of the screens is unable to keep up with the actual frame rate and the end result isn't that clean.

Following up on that same issue,which was posted on the cubieforums thread a while back, I managed to find the time to test one solution that popped up - a disabled function inside the framebuffer files in the sunxi kernel.

Enabling the function and re-compiling the kernel did the trick and I think it actually solved the issue.

While waiting to hear back from the user who reported the issue, I posted a couple of videos on youtube hoping to be able to demonstrate the issue (the sun orb going around), and the apparent solution:

Qt 5.3.0 + Qt5 Cinematic Experience

After having Qt 5.3.0 running on my Cubieboard A20, I decided to run the usual Qt Cinematic Experience app from QuitCoding.

I got the Qt5_CinematicExperience_rpi_1.0.tgz version, same as usual, and while expecting to get the action, I got this instead:


Qt5_CinematicExperience.qml:26:5: Type MainView unavailable 
         MainView { 
         ^
/content/MainView.qml:241:9: Type SettingsView unavailable 
             SettingsView { 
             ^
/content/SettingsView.qml:88:13: Type Switch unavailable 
                 Switch { 
                 ^
/content/Switch.qml:9:21: Cannot assign a value to a signal (expecting a script to be run) 
         property string onText: "On" 

                         ^


This issue showed up on both systems - my laptop and cubieboard, and while not entirely sure why that was, the solution came out of editing Switch.qml and SettingsView.qml and doing the following replacements:

onText > textON
offText > textOFF

... and Cinematic Experience runs once more on both platforms! :)

Qt 5.3.0 and Cubieboard

Qt 5.3.0 came out a few days ago, so I set some time aside to test it out on Cubieboard, like I had done with previous versions.

The cross-compilation works just the same, I've only tested the framebuffer procedure on Cubieboard A20 but basically it all cross-compiled and installed fine.

From the beginning, I've been interested in being able to build the sdcard image system from scratch, using the sunxi-bsp, linaro rootfs, the mali libraries, and finally the cross-compiled Qt libraries on top of it all.

This time around I decided to cut some corners and simplify the base image generation process. Considering that there's an "official" distribution out there - Cubian, I decided to save myself some time and use that.

Going through Cubian's resources, I grabbed the Cubian-base-r5-a20.img.

Cubian images are still supporting Mali r3p0, so I headed over to ssvb's materials on github and cloned his most recent sunxi kernel branch

git clone -b 20140116-mali-r3p2-01rel2 https://github.com/ssvb/linux-sunxi.git

From these sources, I used git to extract the specific commit where ssvb introduced support for r3p2-01rel2

git format-patch -1 5bf12905ff1faa38af4c47ff0752d3f5f12f5644

This commit changes a few files and adds a new directory in the kernel sources, targeted at r3p2-01rel2.

I cleaned the resulting patch a little, taking out the changes to the files in that new directory - which isn't present in Cubian kernel sources at this time, so might as well take them out, and just copy the whole dir into the Cubian kernel sources.

I got the Cubian kernel sources, applied my modified patch and copied over the additional r3p2-01rel2 directory - and then set out to cross-compile it, including modules.

Once that was done, the next step was to copy the uImage and modules binaries over to the Cubian-base-r5-a20 SD Card.

Booting up the system, I confirmed I now had a Cubian CLI image, for cubieboard A20, supporting r3p2-01rel2.

I moved on to installing the r3p2-01rel2 Mali userspace libraries as usual and then cross-compiling Qt 5.3.0 as usual.

Note: while cross-compiling the kernel was done with the Cubian recommended toolchain (code sourcery), cross-compiling Qt was still done using the Linaro toolchain - it's possible that cubian's also works, however there's a relevant step before running Qt's configure - fixLibraryPaths - and this step seems to work best with the Linaro toolchain.

I've uploaded the patches to my box.com account, hopefully I'll have the time soon to publish an image on the cubieforums account.

Monday 26 May 2014

Qt 5.x for Cubieboard - A10/A20 general notions

At the moment, I'm without a working A10 Cubieboard, so the work I keep publishing is mostly A20 oriented.

But if you own an A10, there's absolutely no reason for you not to play around with Qt 5 on it.

On A20, in order to take full advantage of the Mali GPU, the r3p2-01rel2 Mali libraries or above are needed. But this usually requires adding some patches to the kernel, prior to everything else.

On A10, the optimizations aren't so meaningful, which means you can skip this kernel hacking step and just use a stock image, which will support r3p0 Mali.

So for the A10 SoC, you may as well follow these simpler steps:

1- decide whether you want to have Qt with or without X
3- install the Mali libraries - r3p0 - and confirm that you get the colored test triangle

Natively compiling Qt5:

If you decide to natively compile Qt5, stop here and follow this sunxi guide (use whichever new stable release is available instead of the stated 5.1.1 version, adapt in case you're going for framebuffer instead of X11).

Cross-compiling Qt5:

4- make an image file out of the SD Card and move on to your development host machine
5- if you have a 64bit OS, make sure it's ready to deal with 32bit libraries/binaries
6- grab a working toolchain - I've been using Linaro GCC but the recommended toolchain for Cubian is also a possibility
7- grab the latest stable Qt5 sources (this link is for 5.3, linux sources. Adjust to your host OS)
8- cross-compile Qt5 using these instructions, from step 4 onwards - just use the patches if needed, the device mkspec files for cubieboard and the configure line.


Wednesday 21 May 2014

Qt 5.2.1 pre-made images - revisited

Recently, a cubieforums user commented on the Qt5 thread with issues regarding Qt Creator configurations, when adding the pre-compiled Qt 5.2.1 environment, specifically, when attempting to use the Linaro ARM gcc binaries.

I took some time to verify the issue and post a step-by-step quick guide, receiving positive feedback from the user in question - and as such, I thought it might also have a place here in the blog.

To recap, I built the environment using an 64bit host system, while the Cubieboard environment itself works with a 32bit instructions set.

If, instead of going through the hard road of cross-compiling the Qt source code on your own environment, you've attempted to use my development suite for rapid deployment and faced this - or other problems, below is a step-by-step Quick Guide for setting up the pre-compiled Qt 5.2.1 environment available for download at cubieforums.

The base will be a Virtualbox Virtual Machine which will house the development environment with Qt Creator, the cross-compiled Qt 5.2.1 binaries and overall, a clean solution for you to start coding in Qt and deploying your creations to Cubieboard, rather than spend any more time getting to this point.


------------------------- Quick Guide -------------------------

Step #1 : Virtualbox > Ubuntu 14.04 LTS Desktop Clean Install

Step #2 : switched to the Documents dir

wickwire@qt5box:~/Documents$

Step #3 : grabbed the linaro arm gcc

wickwire@qt5box:~/Documents$ wget http://releases.linaro.org/13.09/components/toolchain/binaries/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux.tar.bz2

Step #4 : decompressed the archive

wickwire@qt5box:~/Documents$ tar xvjpf gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux.tar.bz2

Step #5 : descended to the bin dir

wickwire@qt5box:~/Documents$ cd gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin/

Step #6 : executed the arm-gcc binary and confirmed the problem

wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$ ./arm-linux-gnueabihf-g++
-bash: ./arm-linux-gnueabihf-g++: No such file or directory
wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$ 

Step #7 : updated apt-get

wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$ sudo apt-get update

Step #8 : searched for ia32-libs - 32bit support under x64

wickwire@qt5box:~/Documents$ sudo apt-get install ia32-libs
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package ia32-libs is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  lib32z1 lib32ncurses5 lib32bz2-1.0

E: Package 'ia32-libs' has no installation candidate

Step #9 : installed the suggested replacement packages

wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$ sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0

Step #10 : executed the arm gcc binary again

wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$ ./arm-linux-gnueabihf-g++
./arm-linux-gnueabihf-g++: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$

Step #11 : installed the missing libstdc package, 32bit version 

wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$ sudo apt-get install libstdc++6:i386

Step #12 : executed the arm gcc binary - success!

wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$ ./arm-linux-gnueabihf-g++ -v
Using built-in specs.
COLLECT_GCC=./arm-linux-gnueabihf-g++
COLLECT_LTO_WRAPPER=/home/wickwire/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin/../libexec/gcc/arm-linux-gnueabihf/4.8.2/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/src/gcc-linaro-4.8-2013.09/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=arm-linux-gnueabihf --prefix=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/install --with-sysroot=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran --enable-multilib --with-arch=armv7-a --with-tune=cortex-a9 --with-fpu=vfpv3-d16 --with-float=hard --with-pkgversion='crosstool-NG linaro-1.13.1-4.8-2013.09 - Linaro GCC 2013.09' --with-bugurl=https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static --with-mpc=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static --with-isl=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static --with-cloog=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static --with-libelf=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static --enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-gold --with-local-prefix=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long --with-mode=thumb
Thread model: posix
gcc version 4.8.2 20130902 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2013.09 - Linaro GCC 2013.09) 
wickwire@qt5box:~/Documents/gcc-linaro-arm-linux-gnueabihf-4.8-2013.09_linux/bin$

------------------------- Quick Guide -------------------------

From this point on, you should only have to

- decompress the qt5cb2fb or qt5cb2x11 tar.bz2 archives to /usr/local/ on the VM OS

- and then run
/usr/local/qt5cb2fb/bin/qmake -v

to obtain the expected Qt 5.2.1 pre-compiled libraries path:

QMake version 3.0
Using Qt version 5.2.1 in /opt/qt5.cubieboard2.workbench/cubie-rootfs/usr/local/qt5cb2fb/lib

From here, you'll need to mount the downloaded SD Card image to /opt/qt5.cubieboard2.workbench/cubie-rootfs so that qmake is able to find the corresponding cross-compiled Qt 5.2.1 libraries, on the VM OS.

This same image should be written to an available microSD card and loaded onto your Cubieboard device - so as to have two identical systems, the native one running on Cubieboard and the VM installed one, which will be used to cross-compile your future Qt5 Apps.

Set up Qt Creator by adding the Linaro GCC binary + the qmake binary + the remote ssh access to your Cubieboard and that should be all!

Sunday 18 May 2014

QtZumoTruck

Going through some of the stuff in the office study, I came up with an idea - how about a remotely controlled vehicle - yet another one - but with Qt 5.2.1 in the mix?

Maybe not the simplest setup, but certainly a great one for learning/testing.
I got hold of an Arduino Uno R3 that was lying around, slapped a Zumo robot on it and connected it to a Cubietruck.

What came out of this got named QtZumoTruck and it has been quite the entertainment around here!





Ok so I'm not the handiest guy around when it comes to shortening usb cables, but it worked and it lightened the load - although to be honest, the little Zumo packs quite a punch and was able to handle the weight of the all the components previous to being stripped down!

As stated, the Zumo has its own Arduino libraries to handle the two microgear motors, I just added serial port communications to it by following this blog.

And then, on to Cubietruck. Cubietruck is quite awesome, in the sense that it already has built-in battery management - it recharges the battery while on power socket and commutes between power sources without affecting the running OS.

I got the battery off of an old HTC Tattoo smartphone and soldered a couple of wires to be able to connect it to the Cubietruck.

Reading the battery state is also possible under /sysfs, which comes in handy to measure remaining battery.

I installed Cubian (server version) on a microSD card, set up the WiFi for the onboard chipset and also mjpeg-streamer to stream live video over a connected Logitech C160 USB webcam, based off of the sunxi wiki.

Once the Arduino got connected to one of the USB ports on the Cubietruck, the /dev/ttyACM0 device was created and I was in business!
I used minicom on Cubietruck, over ssh, to test interaction with Zumo.

Having WiFi and video streaming on Cubietruck and having Zumo accept serial port commands to control the motors, what was left was to combine the two in an attempt to remotely control the little car over IP.

Possibly not the most immediate choice of framework, but I obviously went with Qt.

Qt 5.2.1 includes QtSerialPort which is specifically oriented at serial port communication. Working with the terminal example, I added QtTCPSocket and made Cubietruck act as a TCP Socket-to-Serial gateway.

So with Cubietruck controlling Zumo over serial port and receiving the commands over TCP socket, I made a simple TCP socket client and that's it!

From old Socket-to-GPIO code I had, I tweaked both Server and Client to work with Serial and fit with the Zumo's needs.

When the Client has focus on the Desktop, using the arrow keys sends messages over the TCP socket to the Server.
The Server picks up the message in question and sends the equivalent command over serial port to Zumo, which in turn handles the motors.

Since the serial port code is sequential, to avoid having to press forward and then stop to halt and change command, I used Qt's events to:

- send a forward command on up arrow key press event
- send a full stop command on any arrow key release event

... and so on for the remaining directions.

There is still a lot of polishing code-wise, but onwards with the first run!




WiFi signal was pretty decent although I did get a few break ups in video reception when getting far away from the access point, located inside.

The video feed was at 640x480 resolution and between 25 and 30fps, which is pretty good - and the whole system feels quite responsive!

And in the end, the whole solution from TCP to Serial uses a graphical framework, without caring much for... graphics.

Yes, Qt is that impressive.