Using the cURL library on the Raspberry Pi

This article is part of a series with the name IoT Remote Power Switch – Project Part 10.

It describes my first experiences with a Raspberry Pi (RPi) 2 board and how I got the Remote Power Switch application working on it. This assumed getting the cURL library installed on the RPi and the development host for cross compilation.

Table of Contents

  1. The Raspberry Pi 2 Board
  2. Get the RPi Up and Running
  3. Build and Run the Learn1RPi Application
  4. Install the cURL Library on the Raspberry Pi
  5. Copy the cURL Library from the RPi to the Development Host
  6. Change Eclipse’s Build Configuration to use RPi’s cURL Library
  7. Build and Run the Remote Power Switch Application
  8. Test the Remote Power Switch Application
  9. Summary and Outlook

The Raspberry Pi 2 Board

It turned out that it was much quicker to obtain a Raspberry Pi 2 board than a B+ board, thus I ordered the former at Farnell. In parallel I ordered the book Raspberry Pi User Guide by Eben Upton and Gareth Halfacree at Amazon, published by John Wiley & Sons Ltd. It provides a solid background about the RPi boards, their hardware, software and history. The model 2 board isn’t covered because it’s too new, but that doesn’t matter; it’s similar enough to the B+ board.

Get the RPi Up and Running

In January I received all the components. With the help of the book and the operating system that came pre-installed on the SD card, I got the thing running within minutes. After connecting keyboard, mouse, screen, network and power, I selected the Raspbian as operating system. Then I made these changes to the system:

  • I changed the default user pi’s password.
  • For convenience I added a .bash_aliases file with my preferred aliases like ll (alias ll='ls -al') to pi’s home directory.
  • Since I am using an English (US) keyboard, I changed the keyboard layout by running sudo dpkg-reconfigure keyboard-configuration from the command line and then rebooting the board. Default was the English (UK) keyboard layout.
  • Then I changed the time zone from UTC+0 (good for the UK) to UTC+1 (good for Switzerland). The shell command is tzselect. It guided me nicely through the short process. I appended the text
    TZ='Europe/Zurich'
    export TZ
    

    to the .profile file in pi’s home directory to make the time zone change permanent.

  • The user pi has all the permissions required for development, thus I didn’t add a standard user for development. A standard user might lack certain required permissions for hardware access and thus cause unnecessary troubles. Once the application is running, I can still run it as another user.

Build and Run the Learn1RPi Application

Switching back to the Learn1RPi project inside Eclipse, cleaning and rebuilding it still worked (it did work in the last post already). I copied it to the RPi and started it like this:
In the development host shell: scp <path/to/Learn1RPi/executable/Learn1RPi pi@192.168.0.11:~
In the RPi shell: cd; ./Learn1RPi
It turned out that it worked flawlessly. It’s output was Hello World!.
This proofs that the cross compilation tool chain works for simple applications.

Install the cURL library on the Raspberry Pi

As on the Ubuntu 14 development host, cURL isn’t installed on the system by default. Remembering how I installed cURL on the development host, I did the same on the RPi. Both, Ubuntu and Raspbian are Debian based packages, thus the commands are identical. I executed the commands sudo apt-get update and sudo apt-get install libcurl4-openssl-dev in the shell. This installed cURL version 7.26.0. curl-config --libs returned -L/usr/lib/arm-linux-gnueabihf -lcurl.
By the way, if you wonder what gnueabihf stands for, it’s: GNU Embedded Application Binary Interface Hard Floating-Point.

Copy the cURL Library from the RPi to the Development Host

Using ifconfig in the RPi’s bash shell I figured out its IPv4 address. Changing to the console on the development host, I entered the following commands there to copy the libraries from the RPi to the host:

$> cd /lib
$> sudo rsync -rl --safe-links pi@192.168.0.11:/lib/arm-linux-gnueabihf .
$> cd /usr/lib
$> sudo rsync -rl pi@192.168.0.11:/usr/lib/arm-linux-gnueabihf .
$> cd /usr/local/include
$> sudo rsync -rl --safe-links pi@192.168.0.11:/usr/include/arm-linux-gnueabihf .

Notes:

  • Don’t use –safe-links in the second rsync command, since not all links would be copied.
  • It would be correcter to copy the /usr/lib/arm-linux-gnueabihf files to /usr/local/lib/, but I didn’t manage to configure the cross compiler tool chain such that it finds all required libraries.

Change Eclipse’s Build Configuration to use RPi’s cURL Library

For the Learn1RPi application I didn’t have to change the build config since it doesn’t use the cURL library. Thus all changes described here just apply to the Remote Power Switch application. I changed the settings of the following tools: compiler (include file paths), linker (library paths and required libraries) and indexer (build configuration).
I opened the file main.c of the RPS project and opened the project’s properties dialog via the main menu. Here’s what I’ve done:

  • Select DebugRaspbian as active configuration
  • C/C++ Build –> Settings –> Tool Settings –> Cross GCC Compiler –> Includes –> Include paths (-I): Add /home/andreas/devl/git/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/arm-linux-gnueabihf/include/c++/4.8.3 and /usr/local/include/arm-linux-gnueabihf
  • C/C++ Build –> Settings –> Tool Settings –> Cross GCC Linker –> Libraries –> Libraries (-l): Add these libraries: curl, gpg-error, p11-kit, keyutils, sasl2, gcrypt, tasn1, gnutls, krb5, k5crypto, com_err, krb5support, rtmp, z, ssl, crypto, gssapi_krb5, ldap_r, lber, ssh2, idn (21 in total)
  • C/C++ Build –> Settings –> Tool Settings –> Cross GCC Linker –> Libraries –> Library search path (-L): Add /usr/lib/arm-linux-gnueabihf and /lib/arm-linux-gnueabihf
  • C/C++ General –> Indexer: tick Enable project specific settings, then under Build configuration for the indexer select Use active build configuration

The long list of libraries shows that cURL introduced a pile of dependencies to other libraries.

Build and Run the Remote Power Switch Application

In my case, the application didn’t build immediately. The linker complained about two missing libraries, although I had them included in the list of libraries. The affected libraries were libkeyutils and libsasl2. After some investigation I figured out that the soft links were missing. I don’t know why, maybe it’s because I copied the files from the RPi using scp instead of rsync with the proper flags. Anyway, I created the missing links with these commands:

$> cd /lib/arm-linux-gnueabihf
$> sudo ln -s libkeyutils.so.1 libkeyutils.so
$> cd /usr/lib/arm-linux-gnueabihf
$> sudo ln -s libsasl2.so.2 libsasl2.so

With this fix, the build worked. I copied the resulting executable file to the RPi using this command in the host shell: scp <path/to/RPS/executable/RemotePowerSwitch pi@192.168.0.11:~
In the RPi shell, I started the application with the command cd; ./RemotePowerSwitch http://192.168.0.15:9000/
192.168.0.15 is the IP address of the development host. It is required for the test in the next paragraph. The application outputs a periodic Slow loop triggered. line followed by two lines of status information. It works. Amazing!

Test the Remote Power Switch Application

In order to test the whole chain, all links have to be up and running. Summarizing and repeating myself, this is the web server and a browser on the development host and the Remote Power Switch application on the Raspberry Pi. I started all three applications (node server/app.js and Chrome on the development host and ./RemotePowerSwitch http://192.168.0.15:9000/ on the RPi) and entered the URL http://localhost:9000/index.html in the address field of the browser.
The device identifier is still hard coded in the RPS application; it’s 1. Finally I clicked the buttons ON and OFF in the browser window and checked if the Status changed accordingly. With a delay of roughly 1 second it did indeed!

Summary and Outlook

The RPS app is running on the RPi, thereby sending and receiving commands over the network via HTTP.

As usual, you find the source code here; it’s pre-release v0.8. Note that the node_modules folder isn’t part of the repository. After downloading the repo or its zip file you’ll have to change directory to the top-level folder of the project and run $> npm install.

Not much left anymore. I’ve to figure out how to toggle a digital output on the RPi, and wire up the power switch to the board. The switch is a solid state relay of type SSR-100 DA manufactured by Fotek Control Ltd, a Taiwanese company. I ordered it via Amazon.