Mise en pratique (3/3)

Un IDE ou un Environnement de développement (Integrated Development Environment) est un logiciel qui rassemble des outils permettant de développer d’autres logiciels.
Il y a beaucoup de très bon IDE pour développer en C, C++.
Exemple : Visual Studio Code, Qt Creator, Eclipse, Code:Blocks,…, pour les payants Clion ..

Comme il existe un grand nombre d’IDE pour le développement en C/C++ sur le web, choisir un IDE peut être un choix difficile.
S’approprier de la prise en main de l’IDE peut-être très chronophage, et n’est pas chose facile.

L’approche de réaliser les opérations de façon distincte, avec des manipulation en ligne de commande, permet de mieux comprendre les démarches, et facilitera la mise en œuvre sur un IDE de votre choix.
L’IDE par la suite ne deviendra qu’un outil qui exécutera les tâches de façon dynamique, et surtout plus intégrées.
Le meilleur IDE, reste pour moi : « emacs » car il permet l’association simplicité et séparation des opérations

Prérequis

Mais avant cela

Toutes les opérations ci-dessous s’exécute sur une machine Hôte (Ubuntu)
Nous partons sur un système fraîchement installé en 18.04 (LTS)
Tout d’abord, assurez-vous que votre système est mis à jour et installez les prérequis requis:

sudo apt update
sudo apt upgrade
sudo apt install build-essential git texinfo file wget

Par la suite, nous allons installer les logiciels et ajuster les configurations pour réaliser une compilation croisée vers ARM 32 bits

ssh Manuel

Pour une question de simplicité de configuration ci-dessous, la machine cible : Raspberry Pi 3 est accessible à travers:

@IP : 192.168.1.137
Login: pi
Mot de passe: raspberry

SSH automatique avec clé RSA

Dans l’approche manuelle, un ssh de la machine Hôte Ubuntu, vers la cible Raspbery, impose à chaque fois de spécifier le mot de passe ssh.
Nous pouvons aléger cette approche, en sécurisant la connexion ssh à travers un mécanisme RSA: (Clé-publique et privée)
Il suffit pour cela de créer un jeu de clé ssh sur Ubuntu, et de transmettre la clé Public vers Raspberry, qui gardera cette Clé Publique dans le fichier « authorized_keys « .

Sur Ubuntu : Génération des clés

Sur Ubuntu, au niveau de votre /home/[user]
Lancer la commande « ssh-keygen » qui va générer une clé publique est privée sur Ubuntu, et la placera dans le répertoire: ~/.ssh/
La commande ssh-keygen va créer automatique ce répertoire
Par la suite, l’objectif étant de pousser cette clé publique sur Rasberry, de telle sorte à ce que Raspberry nous fasse confiance !

ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/pi/.ssh/id_rsa): 
Created directory '/home/pi/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 

Sur Ubuntu : Copie sur Raspberry

 ssh-copy-id -i ~/.ssh/id_rsa.pub pi@192.168.1.137

Cette comande va créer un fichier « authorized_keys » sur la cible: Rasberry

 pi@raspberrypi:~ $ ls .ssh/
 authorized_keys

Sur Ubuntu: Connexion vers Raspberry

 sh pi@192.168.1.137

A partir de maintenant la connexion ssh sur Raspberry ne demandera plus de mot de passe, et sera « Automatique »
Pour info: le premier ssh, demandera une confirmation de la passphrase, puis par la suite autorisera la connexion automatique

sshpass

Avant propos

L’autorisation automatique à travers RAS pour SSH, confère chapitre ci-dessus, permet également l’ouverture à sshpass

Méthodologie

Un client SSH permet d’exécuter des commandes d’administration sur une machine cible. SSH fonctionne en mode dit interactif qui nécessite différente opération de la part de l’utilisateur : Entrées claviers par exemple

En contre partie, « sshpass » permet d’exécuter des commandes en mode « non interactif » via ssh en s’authentifiant avec un username et un mot de passe.
sshpass est nécessaire pour exécuter un programme sur la machine cible, et pour en retourner le résultat sur la machine Hôte
sshass s’installe de façon classique à travers

sudo apt-get install sshpass

sshpass s’utilise de la façon suivante

sshpass -p 'mot_de_passe' ssh login@cible 'commande'
Exemple
   sshpass -p raspberry ssh pi@192.168.1.137 'pwd'
donne le résultat
   /home/pi

Attention la première fois il faut faire une connexion ssh afin de mettre à jour la clé de protection

Chaine d’outils ARM

Principe

Comme indiqué dans l’article Raspberry, Raspbian est livré avec GCC 8.3.0.
L’objectif est donc d’installé une chaîne d’outil similaire sur la machine hôte afin de générer un code binaire au plus proche de la cible

Le site ARM, propose une chaîne d’outils GNU pour la famille Arm. C’est une suite d’outils open source prête à l’emploi pour la programmation C, C ++ et d’assemblage ciblant les processeurs de la famille Arm.
Suivan le lien, le choix va tout naturellement sur

Attention de bien choisir la cible : ARM
AArch32 target with hard float (arm-linux-gnueabihf)
gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz

L’objectif est de placer cette chaîne d’outil dans le répertoire « /opt/cross-pi »

sudo mkdir -p /opt/cross-pi
sudo chown $USER /opt/cross-pi

Afin de faire pointer vers cette chaîne de compilation par défaut, il faut modifier le chemin PATH.
Egalement, pour que cette modification perdure, il faut modifier le fichier spécifique ~/.profile, et ajouter à la fin du fichier

export PATH=/opt/cross-pi/bin:$PATH

Par la suite il faut sortir et re-rentrer dans la session Ubuntu

Détail sur l’installation de la chaîne d’outil.

Procédons maintenant à l’installation de la chaîne d’outil.
Dans le répertoire de Téléchargement

tar xvf gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz  -C /opt/cross-pi

Par la suite il faudra modifier l’emplacement étant donné que l’extraction a gardé le nom complet avec le chemin
« gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf »

cd /opt/cross-pi
mv gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/* ./
rm -R gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/

Après être sortir de la session, nous devrions avoir

arm-linux-gnueabihf-gcc --version
 arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0

gcc --version
 gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

Cette vérification clôt la partie Chaîne de compilation

Compilation croisée step by step

Principe

Pour réaliser cette opération, nous allons faire clignoter une led sur notre Raspbery Pi.
Nous utilisons pour cela la librairie WirinPi.
Nous supposons cette librairie installée sur Raspberry.
Sinon, procéder comme indiqué
ici

Une fois les librairies+includes installée sur Raspberry, nous allons les récupérer à travers un rsync sur Ubuntu.

Répertoires

Sur Ubuntu, dans un premier temps, et de façon systématique, je conseille de créer l’arborescence suivante

Répertoire src

Créer le ficher « blink.c » à copier dans le répertoire src

#include <stdio.h>
#include <wiringPi.h>

#define LED 0

int main (void)
{
  // Init 	
  printf("Raspberry Pi Init");
  wiringPiSetup ();

  pinMode (LED, OUTPUT);
  for (;;)
  {
    digitalWrite (LED, HIGH); 
    delay (500);
    
    digitalWrite (LED,  LOW); 
    delay (500);
  }
  return 0 ;
}

Répertoire lib

Il serait possible de récupérer tout l’environnement Raspberry, comme proposé par certains sites. Mais comme nous avons déjà créé notre environnement de compilation croisée, nous allons récupérer uniquement ce qui est nécessaire!
Nous nous plaçons dans le répertoire de travail ici « Work-00 » et récupérer les includes et lib de WirinPi

rsync -avz pi@192.168.1.137:/usr/lib/libwiring* ./lib/
rsync -avz pi@192.168.1.137:/usr/include/wiring* ./include/

Compilation

Dans le répertoire src, nous compilons avec le compilateur gcc_arm. Nous indiquons l’emplacement de l’include à travers l’option -I

arm-linux-gnueabihf-gcc -Wall -o ../bin/blink.o -I../include -c blink.c 

Éditeur de lien

Dans le répertoire bin, nous appliquons l’édition de lien avec le compilateur gcc_arm

arm-linux-gnueabihf-gcc -Wall -o blink -L../lib -lwiringPi blink.o 

Vérification

arm-linux-gnueabihf-objdump blink -x | grep NEEDED
   NEEDED               libwiringPi.so
   NEEDED               libc.so.6

Résultat que nous pouvons comparer avec ceci

Nous poussons le résultat sur Raspberry

rsync -azv ./blink pi@192.168.1.137:~/

Test sur Raspberry

Debug

Debug en ligne de commande

Principe

Afin de pouvoir procéder à un debug en remote, il faut installer gdb-multiarch sur Ubuntu, de telle sorte à pouvoir debuger des architectures qui ne sont pas celle de la machine hôte.

sudo apt install gdb-multiarch

Raspberry: Serveur de debug

Installation sur Raspberry

gdbserver est une commande Unix permettant de déboguer à distance avec le gdb.
Si gdbserver n’est pas installé, y remédier à ravers

sudo apt install gdbserver

Lancement du serveur de Debug

La commande suivante lance le serveur de debug pour l’executable « blink ».
Commande à exécuter sur Raspberry.

gdbserver localhost:5000 blink

Sur Ubuntu

Sur Ubunutu afin de réaliser un debug en ligne de commande avec gdb.
Lancer les commandes comme suite:

gdb-multiarch bin/blink
  (gdb) target remote 192.168.1.137:2000

Pour l’instant je n’ai pas trouvé comment utilsé gdb-multiarch sour emacs.
En attendant, et pour un contexte néanmoins limité, il faudra utilisé le debugger en ligne de commande. Soit sur la machine hôte, ou sur la machine remote !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *