Réaliser un lecteur de badge avec rasberry pi (Partie 2)

raspberry-ban

Introduction

La semaine dernière, nous en étions restés à la compilation de la librairie libnfc. Si vous avez besoin de vous rafraîchir la mémoire c’est par ici. Aujourd’hui nous allons voir comment lire un badge tel que les badges d’entrée d’immeuble avec un programme en C qui tournera sur raspberry Pi.

Lecture de l’uid

Tout d’abord, il est important de savoir que seul un numéro de série est lu par beaucoup de lecteurs de cartes pour le contrôle d’accès. Ceci n’est absolument pas sécurisé et il est possible d’acheter des cartes (sur le marché chinois) permettant de copier ces badges en utilisant le programme d’exemple nfc-mfsetuid disponible dans le dossier exemple. D’ailleurs, les serruriers ne font qu’une simple copie de votre badge vers un nouveau avant de le verrouiller en écriture.

Il serait tout a fait possible de réaliser un protocole sécurisé mais pour cela, il faudrait des badges équipés de capacité cryptographique et donc plus chers. Les badge d’entrée les plus fréquemment utilisés sont des badges Mifare qui ne coûtent vraiment pas grand chose : MIFARE 4K NXP blanche haute qualité Par 5000 = 0.90 € unitaire trouvé sur google.

Nous allons faire comme eux et simplement lire l’uid. Nous ne prétendrons cependant pas que ce soit sécurisé. Pour cela allons dans le dossier exemples/ et lançons le programme suivant :

sudo ./nfc-poll

Et voilà vous venez de lire l’UID de votre badge !

Code C

Nous allons maintenant repartir du programme nfc-poll afin de le personnaliser et de le réutiliser dans notre application. Toujours dans le dossier exemple :

mkdir badgeReader/utils/
cp nfc-poll.c badgeReader/badgeReader.c
cp ../utils/nfc-utils.h examples/badgeReader/utils/
cp ../utils/nfc-utils.c examples/badgeReader/utils/
cd badgeReader/
gcc badgeReader.c utils/nfc-utils.c -lnfc -o myBadgeReader.o
sudo ./myBadgeReader

Félicitation, vous venez de compiler votre première application avec libnfc. Je vous conseille de garder ce squelette de coté, il constitue une bonne base pour commencer avec le NFC.

Vérifier l’UID

Bien, pour l’instant, nous ne faisions que d’afficher l’UID en réutilisant les programmes déjà présents. nous allons maintenant le récupérer et le comparer afin de vérifier si la personne est autorisée à entrer ou non.

Copier le squelette précédemment construit et remplacer le fichier badgeReader.c par celui écrit ci dessous :

/**
 * @file badgeReader.c
 * @brief read a badge and print a message if the badge is the one attended
 */
 
#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
 
#include <nfc/nfc.h>
#include <nfc/nfc-types.h>
 
#include "utils/nfc-utils.h"
 
static nfc_device *pnd = NULL;
 
int main(int argc, const char *argv[])
{
	const unsigned char referenceUID[7] ={0x04, 0x3c,  0x76,  0x7a,  0xa6,  0x27,  0x80};
	const unsigned char referenceUIDsz = 7;	
 
	const unsigned char uiPollNr = 20;
	const unsigned char uiPeriod = 2;
 
	/* Defines the modulation types
	 * for the mifare types, only the type A is requested */
	const nfc_modulation nmModulations[1] = {
		{ .nmt = NMT_ISO14443A, .nbr = NBR_106 },
	};
 
	int i;
	const size_t szModulations = 1;
 
	nfc_target nt;
	int res = 0;
 
	nfc_context *context;
	nfc_init(&context);
 
	/* We open the pn53x */
	pnd = nfc_open(context, NULL);
 
	if (pnd == NULL) {
		ERR("%s", "Unable to open NFC device.");
		exit(EXIT_FAILURE);
	}
 
	if (nfc_initiator_init(pnd) < 0) {
		nfc_perror(pnd, "nfc_initiator_init");
		exit(EXIT_FAILURE);
	}
 
	if ((res = nfc_initiator_poll_target(pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt))  < 0) {
		nfc_perror(pnd, "nfc_initiator_poll_target");
		nfc_close(pnd);
		nfc_exit(context);
		exit(EXIT_FAILURE);
	}
 
	if (res > 0) {
		printf("Read UID     : ");
		print_hex(nt.nti.nai.abtUid, nt.nti.nai.szUidLen);
		printf("Expected UID : ");
		print_hex(referenceUID, referenceUIDsz);
 
	} else {
		printf("No target found.\n");
	}
	nfc_close(pnd);
	nfc_exit(context);
	exit(EXIT_SUCCESS);
}

Vous pouvez maintenant comparer vos deux UID dans un programme.

Conclusion

Pourquoi ne pas ajouter un module comme celui ci à votre raspberry pi et continuer les développement vers quelques chose de plus sécurisé avec l’ajout d’un code PIN par exemple.

It’s oversimple, isn’t it?

Réaliser un lecteur de badge avec rasberry pi (Partie 1)

raspberry-ban

Introduction

Un article en deux parties.Une première cette semaine pour vous expliquer comment installer la librairie sur votre raspberry pi. Le prochain article décrira comment réaliser un programme en C pour lire un badge de type badge d’entrée des immeubles.

La librairie libnfc

La librairie libnfc est une librairie dédiée à la communication en NFC. Cette librairie est publieé sous licence LGPL (libre de droit pour les applications libres ou commerciales).

Celle-ci fonctionne avec un hardware spécifique, on peut trouver la liste sur le wiki de libnfc.

Pour ma part, j’ai un dongle usb équipé d’un PN533 (fabriqué par NXP). La photo est ci dessous :

dongle_pn533.jpg

Télécharger la librairie

Les liens du wiki officiel sont brisés mais une petite recherche google nous permet de retrouver la release. Pour les projets sur le Pi, privilégiez les versions packagées aux versions développeurs.

wget https://libnfc.googlecode.com/files/libnfc-1.7.0-rc3.tar.gz
tar -xvzf libnfc-1.7.0-rc3.tar.gz 
cd libnfc-1.7.0-rc3/

Configuration

Si vous souhaitez configurer la librairie pour un pn532 en UART comme ceux de chez Adafruit il va falloir commencer par libérer l’UART du pi comme indiqué dans cette article :

Puis une fois l’UART libéré, il va falloir copier le fichier de configuration comme suit :

sudo mkdir -p /etc/nfc/devices.d
sudo cp contrib/libnfc/pn532_uart_on_rpi.conf.sample /etc/nfc/devices.d/pn532_uart_on_rpi.conf

Editez ensuite le fichier suivant :

sudo nano /etc/nfc/devices.d/pn532_uart_on_rpi.conf

Et modifiez la ligne suivante à la fin du fichier

allow_intrusive_scan = true

Compilation

Enfin nous pouvons maintenant compiler les sources :

./configure --with-drivers=pn532_uart --sysconfdir=/etc --prefix=/usr
autoreconf -vis
make clean
sudo make install

Et pour tester :

cd utils/
sudo ./nfc-scan-devices

Et vous devriez voir apparaître quelque chose comme ça :

1 NFC device(s) found:
- NXP / PN533:
    pn53x_usb:002:003

Conclusion

En attendant l’article de la semaine prochaine (il est déjà écrit, il ne reste qu’à le mettre en page), vous pouvez parcourir le dossier exemple/. Vous y trouverez de quoi vous amusez un peu avec diverses badges du quotidien.

Utiliser le port série du Raspberry Pi

raspberry-ban

Le port série est un standard qui est très utilisé dans le monde de l’industrie. De nombreux informaticiens utilisent leur raspberry via le port ethernet pour ensuite y connecter une antenne wifi. Dans cet article,  nous verrons comment utiliser ce port série avec une librairie POSIX afin de dialoguer au travers d’un programme C.

Désactiver le terminal sur le port série du raspberry pi

Nous souhaitons maintenant utiliser le port série du raspberry non plus pour ouvrir un terminal dessus mais pour émettre et recevoir des trames.
Nous allons pour cela configurer le linux embarqué pour qu’il ne redirige plus vers un terminal mais vers le port série.
Avant de faire cela, il vous faut un autre moyen de vous connecter à votre raspberry pi. Vous pouvez soit utiliser un câble ethernet et ouvrir une session ssh ou bien configurer un hotspot wifi comme décrit dans cet article.
Cependant, si vous disposez d’un clavier et d’un écran hdmi, ceci peut tout aussi bien faire l’affaire.

Pour désactiver le bind du terminal sur le port série il vous faut éditer deux fichiers.
Le premier et le plus important est : /etc/inittab

Ce fichier contient la commande qui active le bind du terminal (type vt100) sur le port série à une vitesse de 115200 baud.
Allez à la fin du fichier et commentez la ligne suivante en ajoutant un ‘#’ devant :

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

La simple modification de ce fichier peut être suffisante. Cependant, le raspberry pi redirige automatiquement les informations du boot sur le port série. Si vous avez un système branché sur le port série lors de son démarrage,  il est possible que vous ne souhaitiez pas qu’il puisse recevoir les informations du boot.

Pour cela, il vous faut également éditer le fichier boot/cmdline.txt

Le fichier doit ressembler à ceci :

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Retirez toutes les références à ttyAMA0 qui est le nom du port série. Votre fichier doit maintenant ressembler à ceci :

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Pour appliquer les changements réalisés il vous est nécessaire de rebooter le raspberry pi. Vous pouvez vérifier le bon fonctionnement en utilisant le programme minicom. Par exemple,  vous pourriez utiliser votre raspberry pi pour ouvrir une session sur un autre raspberry pi via le port série.
Comment ça mes idées sont parfois tordues?

Programmer en C

Il existe de nombreuses choses déjà toutes faites pour contrôler les ports séries. Cependant,  rien ne vaut une bonne librairie POSIX qui a l’avantage d’être compatible avec tous les systèmes linux embarqués ou non.

Nous utilisons la librairie POSIX pour communiquer avec le Raspberry Pi. Celle ci est donc compatible sur l’ensemble des systèmes embarqués Linux.

Voici un exemple permettant de renvoyer le message reçu :

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
 
typedef int serialPort;
serialPort SerialLib_open(const char * portPath);
 
int main(int argc, char **argv) {
   serialPort p = SerialLib_open("/dev/ttyAMA0"); /* The serial port of the raspberry pi */
   char buffer[16];
 
   read(p, buffer ,15);
   write(p, buffer ,15);
   buffer[15] = "";
 
   printf("Message recu: %s n",buffer);
   return EXIT_SUCCESS;
}
 
/**
 * Open the specified serial port
 * and return the associated file descriptor
 * 
 */
serialPort SerialLib_open(const char * serialPortPath) {
   int fd; /* File descriptor for the port */
 
   fd = open(serialPortPath, O_RDWR | O_NOCTTY);
   if (fd == -1) {
      /* Error opening the serial port */
      printf("Could not open the serial port : %s - ", serialPortPath);
   }else {
      fcntl(fd, F_SETFL, 0);
   }
   return (serialPort)fd;
}

Conclusion

Vous pouvez tester le code précédent avec un second rapberry pi par exemple. Ceci peut s’avérer très utile lors de l’utilisation de devices externes. Nous l’avons par exemple utilisé pour connecter notre rapsberry pi à un microcontrôleur 8bits.

It’s oversimple isn’t it?

Point d’accès wifi avec un Raspberry Pi

raspberry-ban

Nous avons récemment eu besoin d’avoir un point d’accès sur le Raspberry Pi. Cet article a pour but de faire un petit rappel lorsque l’on va en avoir de nouveau besoin!

Tout d’abord, nous allons commencer par installer le firmware pour le dongle USB :

apt-get install zd1211-firmware

Petite erreur que j’avais avec un freeze du raspberry (dmesg) :

[   43.500170] usb 1-1.3: Could not load firmware file zd1211/zd1211b_ub. Error number -2
[   43.500204] zd1211rw 1-1.3:1.0: couldn't load firmware. Error number -2

Une fois le dongle USB installé sur notre raspberry pi, on configure le serveur DHCPD sur l’interface wifi.

sudo apt-get install isc-dhcp-server
sudo vi /etc/dhcp/dhcpd.conf
sudo ifconfig wlan0 192.168.3.1 netmask 255.255.255.0
sudo /etc/init.d/isc-dhcp-server start

Dans mon cas, j’ai choisi de mettre comme adresse sur notre interface wifi 192.168.3.1

Pour faire le hostspot wifi, j’ai choisi hostapd

sudo apt-get install hostapd
sudo vi /etc/hostapd/hostapd.conf

La configuration est la suivante :

# Configuration récupère sur http://doc.ubuntu-fr.org/hostapd
# interface wlan du Wi-Fi
interface=wlan0
 
# nl80211 avec tous les drivers Linux mac80211
driver=nl80211
 
# Nom du spot Wi-Fi
ssid=oversimple
 
# mode Wi-Fi (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g)
hw_mode=g
 
# canal de fréquence Wi-Fi (1-14)
channel=8
 
#WPA2-PSK-CCMP
wpa=2
wpa_passphrase=oversimple
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
 
# Beacon interval in kus (1.024 ms)
beacon_int=100
 
# DTIM (delivery trafic information message)
dtim_period=2
 
# Maximum number of stations allowed in station table
max_num_sta=255
 
# RTS/CTS threshold; 2347 = disabled (default)
rts_threshold=2347
 
# Fragmentation threshold; 2346 = disabled (default)
fragm_threshold=2346

On peut exécuter hostapd :

hostapd -d /etc/hostapd/hostapd.conf

Cependant, si l’on désire avoir notre point d’accès wifi au démarrage du raspberry , il faut configurer l’interface wifi avec une IP Fixe :

vi /etc/network/interfaces
 
allow-hotplug wlan0
iface wlan0 inet static
address 192.168.3.1
netmask 255.255.255.0

On édite le fichier de config pour le démarrage de hostapd:

 sudo vi /etc/default/hostapd

Le contenu :

allow-hotplug wlan0
iface wlan0 inet static
address 192.168.3.1
netmask 255.255.255.0

On édite dans le fichier /etc/default/hostapd afin de pouvoir sélectionner la configuration requise :

DAEMON_CONF="/etc/hostapd/hostapd.conf"

Puis on active le tout au démarrage :

sudo update-rc.d hostapd enable
sudo update-rc.d isc-dhcp-server enable

Si vous avez besoin que le raspberry fasse une passerelle, il faut activer l’ip forwarding afin que les 2 interfaces(eth0 & wlan0) puissent communiquer.

It’s Oversimple, isn’t it?

Wake me up !

raspberry-ban

Aujourd’hui, ajout de la fonctionnalité réveil matin à notre Raspberry pi. Pour réaliser tout ça, nous allons greffer à notre raspberry pi : un bouton champignon.

Réalisation du bouton champignon

Pour éteindre notre réveil, nous allons hacker la petite veilleuse pour enfant.

Eclairage-technique-Inspire-GELA-Veilleuse-LED-Vert-11270-444

Vous pouvez la trouvez en cliquant ici.

On commence par démonter la lampe et désolidariser la led de l’interrupteur poussoir. Nous voulons faire ressortir la masse, une entrée pour allumer la led et une sortie pour avoir l’état de l’interrupteur (ouvert ou fermé).

IMG_6027

IMG_6047

IMG_6049

Enfin pour le haut parleur, n’importe lequel peut faire l’affaire. En prévoir un qui soit tout de même auto alimenté, ou bien utiliser comme nous un ampli audio 5V que l’on a relié à l’alimentation du Raspberry pi.
Attention dans le cas où l’ampli audio est alimenté via le Raspberry pi, ne pas oublier de prendre une alimentation plus forte qu’un simple chargeur de téléphone.
Screenshot from 2013-07-24 20:02:20

Ce qui nous donne :

IMG_20130726_194125

Nous codons la détection en C. Pour cela nous réutilisons la même librairie que pour l’alarme de maison : Alarme de maison avec un raspberry pi
La fonction suivante nous permet d’allumer ou d’éteindre la led de notre lampe :

void detectInput(void) {
   uint8_t value;
   uint8_t refValue;
 
   refValue = bcm2835_gpio_lev(PIN_SENSOR);
 
   do {
      // lecture du niveau d'entre©e
      value = bcm2835_gpio_lev(PIN_SENSOR);
      delay(400);
   } while(refValue == value);
 
   bcm2835_gpio_write(PIN_ACTOR, HIGH);
}

Enfin pour ce qui est de jouer de la musique nous allons utiliser le programme aplay qui est présent par défaut.
Le fichier source est disponible en annexe.

Il nous suffit alors de lancer le programme à l’aide d’une tâche cron à l’heure du réveil.

Sources et Bibliographie

It’s Oversimple, isn’t it?

Alarme de maison avec un raspberry pi

raspberry-ban

J’ai un ami qui souhaite vérifier que personne n’entre chez lui quand il n’est pas là. Ceci peut être intéressant pour Dexter mais aussi en cas de propriétaire invasif. Afin de contrôler les allers et venues dans son appartement, nous avons eu l’idée de prendre en photo avec une webcam toutes les personnes qui passent la porte. Les photos pourront ensuite être envoyées par mail ou bien sur une interface web.

Mise en place d’un système de sécurité

Un système de sécurité est composé de capteurs. L’ensemble des capteurs permet de détecter une présence. On va retrouver des capteurs sur les portes et fenêtres qui permettent de savoir si celles ci sont ouvertes. On peut aussi trouver des capteurs de mouvement. Dans notre cas, nous souhaitons utiliser un capteur permettant de détecter l’ouverture d’une porte. Celui ci a été récupéré dans le vieux carton d’un projet de technologie réalisé en 4ième.

capteur

Ce capteur va alors être relié à un GPIO du raspberry pi. Il faudra ensuite prendre une photographie en direction de la porte d’entrée sur laquelle le capteur sera placé. On aurait tout aussi bien pu activer un buzzer.

Partie hardware

le capteur fonctionne avec un commun et une sortie normalement ouvert et normalement fermé. L’idée est de relier ce capteur à un GPIO du raspberry pi afin que l’on détecte sur le GPIO :

  • Un état haut (3.3V) si la porte est fermé
  • Un état bas (0V) si la porte est ouverte

Nous obtenons le câblage suivant :

cablage

Afin de s’assurer que la sortie est à l’état bas lorsque la porte est ouverte nous utiliserons une résistance de pulldown.
pour réaliser ce montage nous utilisons un connecteur au pas de 2.54 ainsi qu’un petit domino et nous obtenons le montage suivant, qui se fixe simplement sur le raspberry pi :

pontRasp

Il faut maintenant détecter le niveau de la pin GPIO22. Pour cela nous allons utiliser, une librairie C conçue pour piloter nos GPIO.

Librairie C pour le BCM 2835

La librairie que nous utilisons est disponible ici : librairie

Sur le raspberry pi, ouvrez un shell :

$ wget http://www.open.com.au/mikem/bcm2835/bcm2835-1.17.tar.gz
$ tar zxvf bcm2835-1.17.tar.gz
$ cd bcm2835-1.17
$ ./configure
$ make
$ sudo make check
$ sudo make install

La librairie est maintenant installée.
Les noms des GPIO sont ceux décrit en orange dans l’image ci dessus. Il sont nommés de RPI_GPIO_P1_01 à RPI_GPIO_P1_26. Et ils correspondent aux 26 broches de sorties. Cependant, ils ne correspondent pas aux sorties que vous pouvez utiliser via le système de fichier. Le GPIO22 que nous allons utiliser est ainsi appelé RPI_GPIO_P1_15.

Sur le site de la librairie nous trouvons directement un exemple que nous allons réutiliser dans notre projet. Si vous souhaitez repartir de la source originale, elle se trouve ici : source
Pour détecter le niveau de sortie du GPIO22, nous utilisons le code C suivant:

//input.c
#include <bcm2835.h>
#include <stdio.h>
// Input sur le GPIO22 qui est nommé 15 dans le système de la librairie
#define PIN RPI_GPIO_P1_15
 
int main(int argc, char ** argv) {
    if (!bcm2835_init()) {
        return 1;
   }
    // Fixe le GPIO en entrée
    bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
    //  avec une résistance de pull down
    bcm2835_gpio_set_pud(PIN, BCM2835_GPIO_PUD_DOWN);
 
    while (1) {
        // lecture du niveau d'entrée
        uint8_t value = bcm2835_gpio_lev(PIN);
        printf("lecture GPIO22: %d\n", value);
 
        // attendre 2s
        delay(2000);
    }
    //Un brin de toilette
    bcm2835_close();
    return 0;
}

Compilons et lançons le programme et amusons nous à déplacer le capteur (équivalent à ouvrir et fermer la porte) :

$ gcc input.c -l rt -l bcm2835 -o input
$ sudo ./input
lecture GPIO22: 1
lecture GPIO22: 1
lecture GPIO22: 0
lecture GPIO22: 0
lecture GPIO22: 1

Photographie avec la webcam

Afin de photographier l’entrée, nous allons réutiliser la librairie openCV. Celle ci avez déjà été utilisé à Halloween pour réaliser un capteur de mouvement avec une webcam. Je vous invite à lire l’article suivant pour l’installation et la programmation : Halloween project

Pour ce qui est de l’installation, elle est faite directement depuis les dépôts.

$ sudo apt-get install libcv-dev libcvaux-dev libhighgui-dev

Le code complet est disponible en annexe.

Envoi par mail et interface graphique

L’envoi par mail et l’interface graphique sont codés en php. Les appels entre les deux langages se font soit via la commande system, soit via des pipes nommées.

Et l’interface web donne:

screenShot

Conclusion

Vous pouvez remplacer le capteur par un détecteur de mouvement. N’hésitez pas à nous contacter si vous souhaitez en savoir d’avantage ou avez d’autres idées saugrenues.

It’s oversimple isn’t it?

Cross compilation avec un raspberry pi

raspberry-ban

Qu’est ce qu’un cross compiler?

Un cross compiler est une chaîne de compilation qui tourne sur une architecture mais qui génère un exécutable binaire pour une autre plate forme.

Avec notre raspberry pi, s’il est assez simple de compiler un code de petite taille,il devient très difficile de compiler de gros programmes.

Enfin, il est beaucoup plus agréable de compiler sur votre machine de guerre vos fichiers en une fraction de seconde que d’attendre une minute entre chaque retouche du code compilé par le petit processeur du raspeberry pi.

NOTE : Afin de fonctionner correctement, il est nécessaire d’utiliser une distribution utilisant le hard-float ABI. Ceci est le cas de la raspian et de la dernière version de d’arch pour le raspberry.

Le jeu d’instruction

Chaque processeur utilise son propre jeu d’instructions. Celui ci correspond au jeu d’instructions assembleur. Ce jeu d’instructions est dépendant de l’architecture du microprocesseur. Il dépend directement de la manière dont sont gravé les circuits en silicium.
L’article suivant en anglais explique le fonctionnement des portes logiques que l’on peut trouver dans un microcprocesseur : Article

247x180xQuiz-Silicon-ARM-247x180.jpg.pagespeed.ic.0dZq6IhOZ8

Le jeu d’instructions supporté par les pc et qui est bien connu des reverser est le x86 qui correspond aux architectures Intel. Pour les AMD, c’est assez simple, c’est le même jeu d’instructions. Donc lorsqu’un code, par exemple du C, est compilé pour votre PC, il génère un assembleur x86 qui correspond à des instructions propres aux processeurs Intel et AMD.
Le problème c’est que le processeur présent sur le raspberry pi est un processeur ARM : 700 MHz ARM11 ARM1176JZF-S

Nous allons donc utiliser une chaîne de compilation qui générera un binaire pour le ARM1176JZF-S. Pour cela nous allons utiliser l’outil crosstool-ng.

Installation de crosstool-ng

Crosstool-ng est un outil permettant de construire des chaînes de compilation pour des plate-formes données.
Pour installer crosstool :

$ wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.17.0.tar.bz2
$ tar xjf crosstool-ng-1.17.0.tar.bz2
$ cd crosstool-ng-1.17.0/
$ sudo ./configure --prefix=/opt/crosstool
$ make
$ sudo make install

J’ai du installer quelques programmes supplémentaires. Le script configuré indique ce qu’il manque. Dans tous les cas, n’hésitez pas à poster dans les commentaires si vous avez besoin de plus d’informations.

Réaliser la chaîne de compilation pour le raspberry pi

Il va falloir créer un répertoire dans lequel crosstool-ng va enregistrer votre chaîne de configuration.

  • Créer un répertoire pour héberger votre chaîne de compilation
  • Lancer /opt/crosstool/bin/ct-ng menuconfig

Le menu suivant apparaît:
menuconfig

  • Dans Path and misc options cocher Try features marked as EXPERIMENTAL (touche Y)
  • Toujours dans Path and misc options Changer Shell to use as CONFIG SHELL et choisir sh
  • Revenir au menu principal et sélectionner Target options
    • Target architecture : ARM
    • Endianess : little endian
    • Bitness : 32 bits
  • Revenir au menu principal et sélectionner Operating system
  • Choisir Target OS linux
  • Revenir au menu principal et sélectionner Binary utilities
  • Changer binutils version pour la 2.21.1a
  • Revenir au menu principal et sélectionner C compiler
  • Cocher Show Linaro versions (EXPERIMENTAL) (touche Y)
  • Choisir linaro-4.6-2012.04 (EXPERIMENTAL)
  • Quitter et sauvegarder les changements

Cross compilons

La compilation s’effectue alors de la manière suivante :

$ ~/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gcc helloWorld.c -o helloWord
$ ls
helloWord  helloWorld.c
$ scp helloWorld pi@192.168.1.107:helloWorld
pi@192.168.1.107's password: 
helloWord                                     100% 4985     4.9KB/s   00:00

On l’execute maintenant sur le raspeberry pi :

$ ssh pi@192.168.1.107
pi@192.168.1.107's password: 
Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l
 
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
 
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Jan 13 13:33:49 2013 from 192.168.1.100
pi@raspberrypi ~ $ ./helloWorld 
Oversimple says hello!

Conclusion

On remarque qu’il est relativement difficile de monter une chaîne de compilation pour un processeur ARM et surtout assez long. La réalisation de la chaîne à pris presque une heure chez moi. Cependant, il devient très vite quasi indispensable de le faire si vous souhaitez développer sur le raspberry.
La conception et la compilation de gros projets devient donc plus simple. A titre d’information, les kernels que l’on récupère sur le site du projet raspberry sont compilé de cette manière.

Source :
helloWorld.c