viernes, 9 de agosto de 2019

Developing Nordics' nRF9160 DK using Qt Creator

So I've got my hands into a nRF9160DK (development kit). Like I did with the nRF51822 I would love to develop software for this board using as much FLOSS tools as possible to avoid any kind of vendor lock-in.

This board actually has two interesting ICs: the nRF9160 which anyone would expect and a nRF52840. At first I'm targeting the first one.

The nRF9160's firmware is based on Zephyr which uses CMake. This is great as my preferred IDE is Qt Creator which has quite nice CMake integration.

Preparing the toolchain and proprietary code


There is of course some Nordic proprietary code to put in the mix. So the first step is to setup Nordic's SDK. For that one needs to follow the "Get started with development" section in their web page. One needs to download an nRFConnect AppImage binary and start it. How safe it is to run proprietary code in our machines? Now that's an interesting question.

Once there, and still following Nordic's documentation, we need to install the "Getting started Assistant" and run it. We will follow all steps in it except the last ones for installing a proprietary IDE. We want to code using Qt Creator after all.

Building the asset tracker example from the command line


So let's start by trying to build the example (the only one so far?) from the command line. After some trial and error I've got the following:

mkdir build
cd build
GNUARMEMB_TOOLCHAIN_PATH="/opt/gcc-arm-none-eabi-7-2018-q2-update" \
ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb ZEPHYR_BASE="$NCS_BASE/zephyr" \
cmake -DBOARD_ROOT="$NCS_BASE/zephyr/boards/arm/nrf9160_pca10090" \
-DBOARD="nrf9160_pca10090ns" ../

Where NCS_BASE is the path to the previously downloaded SDK. In this case I selected the non secure version build for this board.

The next step is then easy.

Building the asset tracker example from within Qt Creator


Once we've got to compile the example from the command line switching to Qt Creator is easy. First of all we want to set up a Kit as I did for the nRF51822. Follow the instructions there but this time set up the new GCC version required by this development kit.

The next step is to provide as much definitions as possible as part of the kit itself. Got to ToolsOptions... and then to Kits. Select the newly created kit (I called it nRF9160) and then change "CMake Configuration" settings. The resulting text should look like:

BOARD:STRING=nrf9160_pca10090ns
BOARD_ROOT:STRING=path/to/ncs/zephyr/boards/arm/nrf9160_pca10090
CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}
CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C}
CMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX}
GNUARMEMB_TOOLCHAIN_PATH:STRING=/opt/gcc-arm-none-eabi-7-2018-q2-update
ZEPHYR_TOOLCHAIN_VARIANT:STRING=gnuarmemb

Some of those definitions are not really necessary in there. ZEPHYR_BASE needs to be set as an environment variable. This is the only akward part of this setup, as the only way I could find to do so from within Qt Creator is to set it up in a per-project fashion.

Once the above is done open $NCS_BASE/nrf/applications/asset_tracker/CMakeLists.txt. The configuration will fail, as we haven't suplied ZEPHYR_BASE yet. To do so go to "Projects" on the right, Select "Build" within the kit and set up ZEPHYR_BASE within the "Build Environment" section at the bottom.

That's is, you are now ready to use "Run CMake" from within the "Build" menu and you are ready to go.

sábado, 17 de noviembre de 2018

Using libgps instead of libQgpsmm within a Qt application

I was in need of creating a Qt application using current Debian stable (Stretch) and gpsd. I could have used libQgpsmm which creates a QTcpSocket for stablishing the connection to the gpsd daemon. But then I hit an issue: libQgpsmm was switched to Qt 5 after the Strech release, namely in gpsd 3.17-4. And I'm using Qt 5.

So the next thing to do is to use libgps itself, which is written in C. In this case one needs to call gps_open() to open a connection, gps_stream() to ask for the needed stream... and use gps_waiting() to poll the socket for data.

gps_waiting() checks for data for a maximum of time specified in it's parameters. That means I would need to create a QTimer and poll it to get the data. Poll it fast enough for the application to be responsive, but not too excessively to avoid useless CPU cycles.

I did not like this idea, so I started digging gpsd's code until I found that it exposes the socket it uses in it's base struct, struct gps_data_t's gps_fd. So the next step was to set up a QSocketNotifier around it, and use it's activated() signal.

So (very) basically:

// Class private:
struct gps_data_t mGpsData;
QSocketNotifier * mNotifier;

// In the implementation:
result = gps_open("localhost", DEFAULT_GPSD_PORT, &mGpsData);
// [...check result status...]

result = gps_stream(&mGPSData,WATCH_ENABLE|WATCH_JSON, NULL);
// [...check result status...]

//  Set up the QSocketNotifier instance.
mNotifier = new QSocketNotifier(mGpsData.gps_fd, QSocketNotifier::Read, this); 

connect(mNotifier, &QSocketNotifier::activated, this, &MyGps::readData);

And of course, calling gps_read(&mGpsData) in MyGps::readData(). With this every time there is activity on the socket readData() will be called, an no need to set up a timer anymore.

viernes, 2 de noviembre de 2018

Cross compiling CMake-based projects using Ubuntu/Debian's multi arch

As you probably already know Ubuntu (and then Debian) added Multi-Arch support quite some time ago. This means that you can install library packages from multiple architectures on the same machine.

Thanks to the work of many people, in which I would like to specially mention Helmut Grohne, we are now able to cross compile Debian packages using standard sbuild chroots. He even was kind enough to provide me with some numbers:

We have 28790 source packages in Debian unstable.
Of those, 13358 (46.3%) build architecture-dependent binary packages.
Of those, 7301 (54.6%) have satisfiable cross Build-Depends.
Of those, 3696 (50.6% of buildable, 27.6% of sources) were attempted.
Of those, 2695 (72.9% of built, 36.9% of buildable, 20.1% of sources) were successful.
633 bugs affecting 772 packages (7.23% of 10663 unsuccessful) are reported.

Now I asked myself if I could use this to cross compile the code I'm working on without the need of doing a full Debian package build.

My projects uses CMake, so we can cross compile by providing a suitable CMAKE_TOOLCHAIN_FILE.

And so the first question is:

How do we create the necessary file using what Multi-Arch brings to our table?


I asked Helmut and he did not only provide me with lots of tips, he also provided me with the following script, which I modified a little:

Now we can run the script providing it with the desired host arch and voilá, we have our toolchain file.

#!/bin/sh

#set -x

ARCH=$1

DEB_HOST_GNU_TYPE=$(dpkg-architecture -f "-a$1" -qDEB_HOST_GNU_TYPE)
DEB_HOST_GNU_CPU=$(dpkg-architecture -f "-a$1" -qDEB_HOST_GNU_CPU)
case "$(dpkg-architecture -f "-a$1" -qDEB_HOST_ARCH_OS)" in
        linux) system_name=Linux; ;;
        kfreebsd) system_name=kFreeBSD; ;;
        hurd) system_name=GNU; ;;
        *) exit 1; ;;
esac

cat <> cmake_toolchain_$1.cmake
# Use it while calling CMake:
#   mkdir build; cd build
#   cmake -DCMAKE_TOOLCHAIN_FILE="../cmake_toolchain_.cmake" ../
set(CMAKE_SYSTEM_NAME "$system_name")
set(CMAKE_SYSTEM_PROCESSOR "$DEB_HOST_GNU_CPU")
set(CMAKE_C_COMPILER "$DEB_HOST_GNU_TYPE-gcc")
set(CMAKE_CXX_COMPILER "$DEB_HOST_GNU_TYPE-g++")
set(PKG_CONFIG_EXECUTABLE "$DEB_HOST_GNU_TYPE-pkg-config")
set(PKGCONFIG_EXECUTABLE "$DEB_HOST_GNU_TYPE-pkg-config")
EOF


Can we improve this?

Helmut mentioned that meson provides debcrossgen, a script that automates this step. Meson is written in python, so it only needs to know the host architecture to create the necessary definitions.

CMake is not interpreted, but maybe it has a way to know the host arch in advance. If this is true maybe a helper could be added to help in the process. Ideas (or even better, patches/code!) welcomed.

miércoles, 23 de mayo de 2018

Running MPLAB X with a PickIt 3 on Debian sid

Due to $JOB I need to work with MPLAB X (I wish I could simply open Qt Creator...). MPLAB X's installation went straightforward, but I could not make the PickIt 3 to work.

So I ran MPLAB X from a console and got:

$ /opt/microchip/mplabx/v4.15/mplab_ide/bin/mplab_ide  
libusb couldn't open USB device /dev/bus/usb/006/013: Permission denied.


Yes, I rebooted my machine previous to running MPLABX (a udev restart would have been enough though) but something is not yet working.

Quick and dirty solution: chmod lisandro:lisandro /dev/bus/006/013

Yes, I'll have to re do this every time I plug the PickIt, but at least I've got it working.

sábado, 21 de abril de 2018

moving Qt 4 from Debian testing (aka Buster): some statistics, update II

As in my previous blogpost I'm taking a look at our Qt4 removal wiki page.

Of a total of 438 filed bugs:

  • 181 bugs (41.32%) have been already fixed by either porting the app/library to Qt 5 or a removal from the archive has happened. On most cases the code has been ported and most of the deletions are due to Qt 5 replacements already available in the archive and some due to dead upstreams (ie., no Qt5 port available).
  • 257 bugs (58.68%) still need a fix or are fixed in experimental.
  • 35 bugs (8% of the total, 13% of the remaining) of the remaining bugs are maintained inside the Qt/KDE team.
 We started filing bugs around September 9. That means roughly 32 weeks which gives us around 5.65 packages fixed per week, aka 0.85 packages per day. Obviously not as good as we started (remaining bugs tend to be more complicated), but still quite good.

So, how can you help?

If you are a maintainer of any of the packages still affected try to get upstream to make a port and package it.

If you are not a maintainer you might want to take a look at the list of packages in our wiki page and try to create a patch for them. If you can submit it directly to upstream, the better. Or maybe it's time for you to become the package's upstream or maintainer!



martes, 28 de noviembre de 2017

Experimental cross compiling Qt in Debian packages

Some time ago we the Qt/KDE team were contacted by Helmut Grohne. He was trying to cross compile Debian packages in general thanks to Ubuntu/Debian's multi-arch support, and he was having problems with Qt-based ones.

As far as we understand Qt upstreams only support cross compiling by having a toolchain for each pair of architectures involved. In Debian terms, and only considering current official architectures, that would mean building 90 cross toolchains. It clearly doesn't scale.

So we set up to discuss if somehow we could use multiarch to let debian packages using Qt to cross compile.

In the meantime Enrico Zini had the same idea. He wrote a nice summary of the situation at that time in his blog.

After many thinking some ideas were tested and we've got to the point of solving/hacking the issue. As this is not something directly supported by upstream you should take care, and file bugs whenever necessary.

Dmitry Schachnev from our team's side and Helmut from the debian-cross side worked a lot on it, and I would like to present what they have done. To be fair it's mostly described in our team's gobby qt-cross page, but I would like to give it some publicity in order to let people know about it and why not, find and help solving bugs.

General stuff

The first thing that was done was to move Qt binaries from their (Debian original) multi-arch path to a non multi-arch one, providing symlinks for compatibility. In this way the path of the binaries is the same for any arch (why they were not there is a long story, but nothing to worry now).

This move needed some other touches, like qtchooser being updated with the new paths.

The other changes where related to how we do our packaging:


  • All packages containing binaries are now M-A:foreign.
  • Some packages (qt3d, qtwayland) had binaries split to allow that.
  • qttools5-dev-tools now depends on libqt5sql5-sqlite (not uploaded yet)

qmake related changes

We also needed to address qmake. To begin with we splitted the package containing it into qt5-qmake-bin (M-A:foreign) and qt5-qmake (M-A:same). The first one has the binaries and the second the relevant mkspecs for some arch.

The rest of the "magic" comes from debhelper. It generates a qt.conf file with the right paths for each cross compilation and also passes cross QMAKE_CC and QMAKE_CXX to qmake when needed.


autotools

qt5-qmake will ship /usr/bin/$(DEB_HOST_GNU_TYPE)-qmake executable for use with AC_CHECK_TOOL (not uploaded yet).

There is still work to be done, but so far we have been able to cross compile packages using for example sbuild.

Edit 20171129 11:43 ARST: You should really look at the new Enrico's post.

viernes, 24 de noviembre de 2017

Removing Qt 4 from Debian testing (aka Buster): some statistics

I have just looked upon our Qt 4 removal wiki page to see how we are doing. Out of 438 bugs filled:

  • 88 (20.09%) have been already fixed by either porting the app/library to Qt 5 or a removal from the archive has happened. On most cases the code has been ported and most of the deletions are due to Qt 5 replacements already available in the archive and a few due to dead upstreams.
  • 3 (0.68%) packages are marked as fixed an an upload is pending.
  • 65 (14.84%) of the open bugs are maintained inside the Qt/KDE team. Many of them should get a Qt 5 version with the next KF5 uploads.
We started filing bugs around September 9.  That means roughly 11 weeks, which gives us around 8 packages fixed a week, aka 1.14 packages per day. Not bad at all!

So, how can you help?

If you are a maintainer of any of the packages still affected try to get upstream to make a port and package it.

If you are not a maintainer you might want to take a look at the list of packages in our wiki page and try to create a patch for them. If you can submit it directly to upstream, the better.