Sunday, 24 January 2016

Raspberry Pi real time kernel

I have recently worked on a realtime application for Raspberry Pi 2.

One of the steps to achieve the goal was to enable the realtime scheduler policies in the Linux kernel.
In this case I have selected the SCHED_FIFO policy.
The behaviour of a process scheduled with this policy is that when it becomes runnable it will be inserted in the list of SCHED_FIFO processes. It will stay running until another process in the SCHED_FIFO policy with a higher priority becomes runnable. 
For more information refer to the sched_setscheduler function documentation.

In this post I am going to show you how to build a kernel with the PREEMPT-RT profile enabled.
Cause the limited Raspberry Pi resources, I decided to cross-compile the kernel on an Ubuntu system. Thus i have setup the compiling environment on a VirtualBox virtual machine on my Intel Core i7.
The VM is configured with 2 cores and 4 GB of RAM. Make sure to define the Virtual Hard Drive maximum size to at least 20 GB.

From this point I will assume that you have a running and updated Ubuntu 15.10 desktop.

Let's start


Download the kernel sources from the raspberry git repository (~ 160 MB).
Before continuing please bear in mind that the RT-Kernel project provides a specific version of the patch for a specific version of the Linux kernel. So, before downloading a version of the kernel, check if the RT patch is available. In my case I have patched the linux-rpi-4.1.y (Linux 4.1.15) branch sources with the patch-4.1.15-rt17.patch.


~ $ git clone -b rpi-4.1.y https://github.com/raspberrypi/linux.git

Or downloading the archive:
~ $ wget https://github.com/raspberrypi/linux/archive/rpi-4.1.y.zip
~ $ unzip rpi-4.1.y.zip
~ $ mv linux-rpi-4.1.y linux


Download the raspberry tools from the raspberry git repository (~ 300 MB):
~ $ git clone https://github.com/raspberrypi/tools

Or downloading the archive:
~ $ wget https://github.com/raspberrypi/tools/archive/master.zip
~ $ unzip master.zip
~ $ mv tools-master tools


Download the version of RT-patches relative to the kernel version:
~ $ wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.1/patch-4.1.15-rt17.patch.xz


Setup the GCC environment:
~ $ export CCPREFIX=~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-


Test GCC:
~ $ ${CCPREFIX}gcc -v

This should output the version of GCC .


Apply the RT patch:
~ $ cd linux
~/linux $ xzcat ../patch-4.1.15-rt17.patch.xz | patch -p1


Compile the kernel:
It is a good idea to start from an existent configuration. Connect to your Raspberry Pi and download the current configuration:
~/linux $ scp pi@raspberrypi:/proc/config.gz .

Extract the config file:
~/linux $ gunzip -c ../config.gz > .config

Bootstrap the kernel configuration using the provided .config file:
~/linux $ ARCH=arm CROSS_COMPILE=${CCPREFIX} make oldconfig

Start the kernel configuration utility and enable the Full real-time profile:
~/linux $ sudo apt-get install libncurses5-dev
~/linux $ make menuconfig

Build the kernel (~35 minutes):
~/linux $ ARCH=arm CROSS_COMPILE=${CCPREFIX} make

Consider adding the -j n option to the command line to compile more than one file at time.

Generate kernel modules:
~/linux $ ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=../modules make modules_install 


Create a new uncompressed kernel image:
~/linux $ cd ../tools/mkimage
~/tools/mkimage $ ./imagetool-uncompressed.py ../../linux/arch/arm/boot/zImage
~/tools/mkimage $ mv kernel.img ../..

Create an archive for all modules:
~ $ cd modules
~/modules $ tar czf modules.tgz *
~/modules $ mv modules.tgz ..

Deploy the new kernel on the Raspberry Pi:
~ $ scp ./kernel.img pi@raspberrypi:/tmp/kernel.img
~ $ scp ./modules.tgz pi@raspberrypi:/tmp/modules.tgz

Complete the deployment in a terminal on the Raspberry PI.
~ $ cd /
/ $ sudo mv /tmp/kernel-test.img /boot
/ $ sudo tar xzf /tmp/modules.tgz


Pwew! Hope you will find this guide useful for your next Raspberry real-time project.


Thursday, 21 January 2016

The Good Dinosaur

Last weekend my family and I finally watched the last Disney Pixar movie.
This was our first time in a cinema with Stefano, so it was a great experience, regardless of the movie.
We watched the 2D version of the movie, and frankly, I have been in more comfortable and technically-equipped cinemas, but this did not make the visual experience less pleasant.
I think Pixar wanted to show the maximum photorealism they could achieve.
The representation of nature is perfect in every detail: the mountains, the grass, the water, everything in the environment seems more real than real.
The character design, with the exaggerated animations and those big eyes, is that toon-ish style that makes the movie more suitable for kids.
Because, after all, this should be a movie for kids.
The problem is that, even with that PG rate that it took, it is not remarked enough that this is not exactly a movie for kids.
In hindsight, I wish I had read the reviews on imdb.com before going to the cinema.
Some scenes are, to say the less, not appropriate for a young public. Stefano is not scared easily, but some scenes made him silent (I know what this means), and I did my best to mitigate the tension in such moments.
The story has great potential: imagine the world if the dinosaurs would not be extinct after the meteor. It could be intended for families, but I think they put too much unnecessary tension in different parts of the movie.

I cannot really understand the reason of some scenes:

Why graphically represent a decapitation? Why visualize a small animal eaten alive? Why repeat the scene of the death of Arlo's father? Why put so much tension in the storm representation?



Even the short that precedes the movie is somewhat not appropriate: the graphic style of the monster could be a little less scary considering the average age of the public.

As an adult, I somewhat enjoyed The Good Dinosaur, even with its over-simplistic story, but I would not recommend other parents watch it with their children.

Stefano was very bored, and for the last 20 minutes, he barely resisted leaving and did not watch the movie.

We spent the rest of the day at his favourite playground to reward his patience. 

This was the first time I did not bother watching the credits at the end of the movie.
I promised myself to read the reviews before watching a movie in future.

Saturday, 16 January 2016

Playing with... MonkeyRunner

A few days ago, Stefano was playing with our Samsung Galaxy Tab 2.

He usually enjoys playing a plethora of MineCraft clones on it, and he was playing with a game with the well-known blocky graphic style (I have already purchased the XBox360 version, and I don't want to spend other money for the same game on a different platform... this actually already happened some months ago, but this is another story  ).
I enjoy watching him play video games because, in general, children have different and way-more-creative ways to play than adults.
I think this is one of the reasons for Minecraft's global success.
Apart from the graphic style, the game was not a sandbox this time.

PickCrafter is a very simple arcade where your only aim is to collect as many blocks and "picks" as possible.

All you have to do is shake your device, mimicking mining with a pickaxe (the only tool of the game) or tapping as fast as you can on the screen. Moving your device allows you to collect "picks" faster than tapping.
You can buy enhancements by spending your "picks" in the game shop. Enhancements allow you to collect picks faster.

While helping Stefano tap furiously on the poor tablet screen, I thought the game was an excellent target for the Android SDK MonkeyRunner utility  .

MonkeyRunner is a tool that helps the developer to simulate some user events by writing a Python program using the MonkeyRunner API.

For me, it was also an occasion to work with Python.


Ok, let's start then from the Python program.
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
import time
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection()

points = [{"x":300, "y":900},
          {"x":500, "y":300},
          {"x":400, "y":700},
          {"x":600, "y":600}]

while True:
  for p in points:
    device.touch(p["x"], p["y"], MonkeyDevice.DOWN_AND_UP)

    time.sleep(.05)


This program defines a list of points (technically a list of dictionaries) and then sends them indefinitely to the device.

After a few attempts, I found the screen coordinates to get the best from the game.
I also found that a small sleep is necessary after each touch event; otherwise, the game will hang.

To find the exact screen coordinates, I enabled the option "Show touches" and "Show pointer location" in the developer options menu of the device settings.

Remember to disable both settings afterwards because they will slightly slow the device considering that we send a touch event every 50 ms.



It is time to run MonkeyRunner: save the code in a file (e.g. send_touch_events.py) and open the Console link you can find in the root folder of the Android SDK installation.
As MonketRunner sends the touch events to the foreground activity, you should open the game on your device before starting the script. 

On the Command Prompt type
monkeyrunner SendTouchEvents.py

and hit return.

If the device is connected correctly and you have authorized the USB debug connection in the device settings, the game now should receive the touch events.
You will then quickly collect a large amount of "picks" and blocks without risking damaging your device.


 
PickCrafter during a MonkeyRunner session

Issues

- During the first few seconds of the "fire time", you will still need to tap on the screen. I don't know exactly why, and I don't want to spend more time finding it.- The script cannot catch the "creep" that randomly appears on the screen. Without knowing the game code, we will need a complete AI and a more sophisticated system.

 
Enjoy! :)


Sunday, 10 January 2016

Windows 10 is here

I have finally decided to accept the insistent Microsoft invitation to the upgrade. I was happy with Windows 7 on both my laptop and home desktop, but I thought to try it anyway.

First, I upgraded my Asus K53SJ laptop after a quick check on the support website for known issues: the upgrade was successful and faster than expected.
I tried it for two days before applying the upgrade to the desktop. This is a custom-made one with an AMD AM3 Socket based motherboard. The upgrade process was flawless also in this case.

Issues

Unfortunately, I have noticed some minor issues on both PC.

Laptop

The integrated webcam was not recognised anymore. To fix this issue, I uninstalled the driver, downloaded the latest version from the Asus website and installed it again, taking care to reboot after each setup execution.
Another issue that I have not fixed yet, the user switch sometimes gets the laptop stuck: the only solution is to hard reset and reboot.

Desktop

Even in this case, the webcam - an external Logitech C525 - was not recognised anymore. I fixed the issue with the same solution for the laptop webcam (uninstall, reboot, install the latest driver, reboot).
After the upgrade, the additional PCIEx-to-USB was not recognised anymore. Fortunately enough, in this case, a simple reboot fixed it.
Last, sometimes during the boot animation, the PC hangs.
I have yet to find a solution better than a hard reset.


Privacy Settings

Windows 10 is well known to send user information to Microsoft without asking for permission.
After an upgrade, I would recommend disabling all the privacy-related settings.
I have found this helpful guide, but you can find many similar ones on the internet. Somebody also created utilities that automate these tasks.

Conclusions

Apart from those minor annoyances, I feel the new OS is worth the upgrade.
The best improvements on the early versions are in the Command Prompt (that finally supports the windows resizing!) and the integrated Modern UI windows in the desktop environment.

Sunday, 20 December 2015

Is English an official language?

Stefano has been attending SkolaSport for some time. SkolaSport is a program of the Maltese government to promote sports for kids of every age.

My wife and I decided to register him for the gymnastics class.

Actually, because of the average age of the participants, during this class, they just play together. Still, we think this is more than sufficient, considering this is also an occasion for Stefano to socialise with other children.

Last week, I received an email from the sports centre: they invited me to a parents' meeting to discuss the new gymnastic academic course. The idea behind this is to identify potential in the kids to build a future team of professionals.

We decided to attend the meeting, even though we were aware that it is perhaps too early for such a commitment.
The meeting started with the introduction by one of the organisers.

Unfortunately for me - but, after all, we are in Malta - he started speaking Maltese.
I then politely asked him to switch to English to let us understand.
What surprised my wife and me was the face of the speaker and the rest of the committee.
After a short discussion, the speaker replied in English that the rest of the attendees preferred Maltese.

We were about to leave the room when one of the committee members proposed himself as a translator from Maltese to Italian: he invited me to sit beside him.
With his help, I understood the most important topics, but the bottom line is that Stefano is still too young (and "inexpert", whatever it means for a young child) to attend the academic program.

In hindsight, that situation raised a question in my head:

Maltese and English are both official languages in Malta: is it my right to request to speak English at a public event?

Friday, 18 December 2015

L'inglese è una lingua ufficiale o no?

Stefano da qualche tempo partecipa a SkolaSport un programma governativo che promuove lo sport per gli studenti di tutte le età. Io e mia moglie abbiamo deciso di iscriverlo al corso di ginnastica.

Durante questa ora settimanale in realtà, vista l'età media di cinque anni, più che altro fanno giochi di gruppo, ma riteniamo che sia più che adeguato dato che è anche un modo per socializzare.

La settimana scorsa ho ricevuto una email dal centro sportivo con l'invito ad un incontro con i genitori per spiegare l'organizzazione del nuovo anno accademico di ginnastica.
In buona sostanza, un incontro per gli interessati ad un programma più impegnativo per fini possibilmente agonistici.
Pur avendo in mente di non stressare troppo il nostro piccolo sportivo, abbiamo comunque deciso di partecipare all'incontro.

Il giorno fissato, siamo arrivati al centro sportivo inusualmente puntuali (per i nostri - ahimè - standard).
Dopo una breve attesa ci siamo finalmente seduti per ascoltare il discorso degli organizzatori.

Come immaginavo, lo speaker ha cominciato subito a parlare in maltese.
Poco male - mi sono detto - mi sono quindi alzato e chiesto, in inglese, scusandomi per l'interruzione, se poteva parlare in inglese anche lui.
La faccia stupita della gente sul palco mi ha lasciato perplesso a mia volta: dopo aver confabulato brevemente fra loro, l'uomo mi ha risposto in inglese che il pubblico avrebbe preferito il maltese, anche se sinceramente non ho capito da cosa lo ha dedotto.

Stavo quindi pensando di andare via, quando, visto che fra gli organizzatori era presente un italiano, sono stato invitato a spostarmi vicino a lui che si è cortesemente prestato a fare da traduttore.

Alla fine ho capito i punti essenziali del discorso e che comunque Stefano è ancora piccolo (e inesperto) per accedere all'accademia.

Non è mia intenzione dare colpe a nessuno, ma la situazione vissuta mi ha lasciato in testa delle domande:


  • Se non ci fosse stato l'interprete, lo speaker avrebbe accettato di parlare in inglese o sarei stato costretto a rinunciare a capire? 
  • In una nazione dove l'inglese è una delle due lingue ufficiali, non è mio diritto insistere nel chiedere di usarlo?

Wednesday, 14 October 2015

Timing a function

Some time ago, I started practising Codility tests.
While I believe they cannot be the only way to evaluate a good developer, Codility tests propose fairly interesting programming tasks to keep your mind fit.
Since usually, the task asks you to implement a function that solves the problem in a certain level of complexity indicated with the big-O notation, you will need to find a way to measure the performance of your code.

I created a Visual Studio C++ solution including all the Codility problems and their solutions.
For each class that implements a particular problem, the main function calls the method solution() and measures it.

To avoid repeating the code for measuring the execution time, I thought to use a generic approach.
The idea was to pass a functor to another function that executes the functor and evaluates the total elapsed time. In C++, this can be done by writing a template function.
This is the code of the function:

  template<typename Function>
  inline static float timeFunction(Function f)
  {
    clock_t t = clock();
    f();
    t = clock() - t;
    return ((float)t) / CLOCKS_PER_SEC;
  };


Where Function is the generic type of the argument.
I can, therefore, pass a lambda expression to timeFunction:

float elapsed = timeFunction([](){ function_to_be_timed(); }); 


Here is another version that makes use the Windows high-resolution timer:

  template<typename Function>
  inline static double timeFunctionMicroSec(Function f)
  {
    LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
    LARGE_INTEGER Frequency;

    QueryPerformanceFrequency(&Frequency);
    QueryPerformanceCounter(&StartingTime);

    f();

    QueryPerformanceCounter(&EndingTime);
    ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
    ElapsedMicroseconds.QuadPart *= 1000000;
    ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

    return double(ElapsedMicroseconds.QuadPart);
  };


I hope this will be useful to you.