|  | 1 | = TP2 : Outils de développement et GPIO = | 
                          |  | 2 |  | 
                          |  | 3 | La carte Raspberry Pi offre de nombreuses possibilités pour développer des | 
                          |  | 4 | applications embarquées. Notamment, elle dispose de ports d'entrées/sorties | 
                          |  | 5 | génériques (GPIO) qui permettent de s'interfacer avec un grand nombre de | 
                          |  | 6 | périphériques plus ou moins exotiques. | 
                          |  | 7 |  | 
                          |  | 8 | Dans ce TP il vous est demandé de développer une application "user-land" | 
                          |  | 9 | qui fasse clignoter une ou plusieurs LED's selon on motif que vous choisirez | 
                          |  | 10 | et également de récupérer les informations de plusieurs boutons poussoirs. | 
                          |  | 11 |  | 
                          |  | 12 | À la fin de ce TP, vous devriez avoir acquis les compétences suivantes: | 
                          |  | 13 | * Compilation croisée via un compilateur déporté | 
                          |  | 14 | * Contrôle distant de système embarqué par liaison réseau (SSH) | 
                          |  | 15 | * Manipulation d'un périphérique GPIO et de ses registres "memory mappés" | 
                          |  | 16 | * Interface numérique/analogique via des ports GPIO | 
                          |  | 17 | * Programmation d'automates de contrôle en C | 
                          |  | 18 |  | 
                          |  | 19 | == 0. Plateforme de développement == | 
                          |  | 20 |  | 
                          |  | 21 | [[Image(htdocs:png/plateforme-peri-raspberry.png, width=700px, nolink)]] | 
                          |  | 22 |  | 
                          |  | 23 | Pour exécuter votre programme sur une carte Raspberry Pi, vous devez vous | 
                          |  | 24 | connecter en SSH sur une carte Raspberry Pi en passant par le routeur peri. | 
                          |  | 25 | Le routeur a deux adresses: `132.227.102.36` du coté laboratoire et `192.168.1.1` de l'autre coté. | 
                          |  | 26 | Le routeur crée un sous-réseau (`192.168.1.x`) où sont connectées les cartes. | 
                          |  | 27 | Les cartes sont numérotées de `20` à `24` plus des cartes étudiants (ici n°30), le routeur a été programmé de telle sorte | 
                          |  | 28 | que l'adresse internet de la carte n°`X` est comme adresse 192.168.1.`X` | 
                          |  | 29 | (par exemple la carte n°`20` a comme adresse sur ce réseau `192.168.1.20`). | 
                          |  | 30 | Pour faire ça, le firmware du routeur a été remplacé par '''dd-wrt''' qui permet ce type de mode. | 
                          |  | 31 | Le routeur a été également été programmé pour que tous les paquets entrants sur le | 
                          |  | 32 | port `5000`+`X` de l'adresse `132.227.102.36` soient routés vers l'adresse `192.168.1.X`. | 
                          |  | 33 |  | 
                          |  | 34 | Il n'y a qu'un seul compte utilisateur sur une carte Raspberry Pi. Le nom de login est `pi` et le mot de passe est `raspberry`. | 
                          |  | 35 |  | 
                          |  | 36 | Ainsi, pour se connecter en ssh sur la carte n°`22` avec le login `pi`, il faut taper (remarquez que c'est un `p` minuscule): | 
                          |  | 37 | {{{ | 
                          |  | 38 | $ ssh -p 5022 pi@132.227.102.36 | 
                          |  | 39 | pi@132.227.102.36's password: raspberry | 
                          |  | 40 | }}} | 
                          |  | 41 |  | 
                          |  | 42 | Pour copier un fichier `file.x` depuis votre compte enseignement sur le carte ,°`22` il faut taper (remarquez que c'est un `P` majuscule): | 
                          |  | 43 | {{{ | 
                          |  | 44 | $ scp -P 5022 file.x pi@132.227.102.36 | 
                          |  | 45 | pi@132.227.102.36's password: raspberry | 
                          |  | 46 | }}} | 
                          |  | 47 |  | 
                          |  | 48 | Comme, il n'y a qu'un compte par carte et que vous allez devoir vous les partager, | 
                          |  | 49 | vous devez créer un répertoire à la racine avec le nom de votre login sur le réseau | 
                          |  | 50 | enseignement accolé avec un tiret avec le nom de votre binôme si vous en avez un. | 
                          |  | 51 | Par exemple, deux personnes en binôme se nommant respectivement `almada` et `fomentin` vont créer un répertoire `almada-fomentin` (en minuscule). | 
                          |  | 52 |  | 
                          |  | 53 | = 1. Prise en mains des outils de développement: Hello World! = | 
                          |  | 54 |  | 
                          |  | 55 | La première étape consiste à vous familiariser avec les outils de | 
                          |  | 56 | développement. Pour cela, vous allez développer un petit programme | 
                          |  | 57 | de type "Hello World!" qui affiche une phrase sur la sortie standard | 
                          |  | 58 | grâce à un printf. | 
                          |  | 59 |  | 
                          |  | 60 | Pour compiler votre programme, suivez les instructions suivantes. | 
                          |  | 61 |  | 
                          |  | 62 | * Tout d'abord, configurez votre terminal pour utiliser le compilateur croisé (vous pourrez | 
                          |  | 63 | ajouter cette commande dans le fichier $HOME/.bashrc): | 
                          |  | 64 | {{{ | 
                          |  | 65 | $ source /users/enseig/franck/peri/export_rpi_toolchain.sh | 
                          |  | 66 | }}} | 
                          |  | 67 |  | 
                          |  | 68 | * Une fois le terminal configuré, vérifiez que le compilateur est accessible: | 
                          |  | 69 | {{{ | 
                          |  | 70 | $ which bcm2708hardfp-gcc | 
                          |  | 71 | }}} | 
                          |  | 72 | Si cette commande ne retourne rien, la configuration n'a pas fonctionné. | 
                          |  | 73 | Appelez le chargé de TP pour vous aider. | 
                          |  | 74 |  | 
                          |  | 75 | Votre suite d'outils (toolchain) contient tous les outils nécessaires pour | 
                          |  | 76 | la compilation, l'édition des liens et la manipulation de binaires pour la | 
                          |  | 77 | carte Raspberry Pi. Et tous ces outils sont préfixés par la même chaîne de | 
                          |  | 78 | caractères: `bcm2708hardfp-`. Il s'agit donc d'un compilateur pour un SoC | 
                          |  | 79 | BCM2708 avec l'option hardfp activée (calcul flottant matériel). Il s'agit | 
                          |  | 80 | bien du SoC de la carte Raspberry Pi. | 
                          |  | 81 |  | 
                          |  | 82 | Maintenant, pour compiler un programme C vers un binaire qui puisse | 
                          |  | 83 | s'exécuter sur la carte Raspberry Pi, il vous faut écrire un Makefile pour | 
                          |  | 84 | plus de facilité. Pour cela, suivez la syntaxe de base des Makefile: | 
                          |  | 85 | {{{ | 
                          |  | 86 | cible: dépendances | 
                          |  | 87 | commande | 
                          |  | 88 | }}} | 
                          |  | 89 | Notez bien que l'indentation de la seconde ligne doit OBLIGATOIREMENT être | 
                          |  | 90 | une tabulation et non une suite d'espaces. | 
                          |  | 91 |  | 
                          |  | 92 | Vous pourrez donc par exemple, écrire la règle de Makefile suivante: | 
                          |  | 93 | {{{ | 
                          |  | 94 | helloworld.x: helloworld.c | 
                          |  | 95 | bcm2708hardfp-gcc -o $@ $< -O2 -static | 
                          |  | 96 | }}} | 
                          |  | 97 |  | 
                          |  | 98 | L'option "-static" est importante ici, car la librairie C du compilateur croisé | 
                          |  | 99 | n'est pas tout à fait identique à la librairie C sur la carte Raspberry Pi. | 
                          |  | 100 | Ajouter "-static" à la ligne de compilation permet de créer un binaire qui | 
                          |  | 101 | contient en plus les fonctions de la librairie C utilisée par votre programme. | 
                          |  | 102 | Ceci permettra à celui-ci de ne pas essayer d'utiliser des fonctions de la | 
                          |  | 103 | librairie C installée sur la carte. | 
                          |  | 104 |  | 
                          |  | 105 | Essayez toutes les variantes ou combinaisons de programme C que vous souhaitez. | 
                          |  | 106 |  | 
                          |  | 107 | == 2. Contrôle de GPIO en sortie == | 
                          |  | 108 |  | 
                          |  | 109 | Dans cet exercice, on vous propose de manipuler une pin du GPIO en mode | 
                          |  | 110 | "sortie" pour contrôler le clignotement d'une LED à une fréquence donnée. | 
                          |  | 111 |  | 
                          |  | 112 | Avant de commencer à écrire du code, déterminez quelles sont les différentes | 
                          |  | 113 | étapes nécessaires depuis l'initialisation jusqu'à l'envoi des valeurs 0 ou 1 | 
                          |  | 114 | sur le GPIO. | 
                          |  | 115 |  | 
                          |  | 116 | Dans un premier temps, on vous ne demande pas d'écrire le code spécifique | 
                          |  | 117 | à la manipulation des registres du contrôleur GPIO. Pour vous aider, | 
                          |  | 118 | vous avez à disposition une petite librairie "libgpio". | 
                          |  | 119 |  | 
                          |  | 120 | Pour récupérer cette librairie, exécuter la commande suivante dans un | 
                          |  | 121 | terminal et dans le dossier que vous souhaitez pour contenir votre code pour | 
                          |  | 122 | ce premier TP. | 
                          |  | 123 | {{{ | 
                          |  | 124 | cp -r /users/enseig/jpeeters/m1.peri/lab1 . | 
                          |  | 125 | }}} | 
                          |  | 126 |  | 
                          |  | 127 | Éditez le fichier lab1.c et ajoutez le code que vous pensez nécessaire à la | 
                          |  | 128 | réalisation de cet exercice. | 
                          |  | 129 |  | 
                          |  | 130 | ATTENTION: ne changez pas les valeurs de GPIO_LED0, car vous risqueriez | 
                          |  | 131 | d'endommager la carte Raspberry Pi. | 
                          |  | 132 |  | 
                          |  | 133 | Ensuite, compilez-le grâce au Makefile qui vous est fourni. | 
                          |  | 134 |  | 
                          |  | 135 | Qu'observez-vous ? Essayez de changer la fréquence de clignotement. | 
                          |  | 136 |  | 
                          |  | 137 | == 3. Contrôle de plusieurs GPIO en mode "sortie" == | 
                          |  | 138 |  | 
                          |  | 139 | Refaites le même exercice que précédemment, mais cette fois-ci configurez | 
                          |  | 140 | plusieurs GPIO en sorties. | 
                          |  | 141 |  | 
                          |  | 142 | En plus du GPIO 4 de l'exercice précédent, rajoutez 3 définitions pour les | 
                          |  | 143 | LED1, LED2 et LED3 qui sont respectivement connectées aux GPIO 17, 22 et 27. | 
                          |  | 144 |  | 
                          |  | 145 | Avant d'exécuter votre programme, validez votre code avec le chargé de TP ! | 
                          |  | 146 |  | 
                          |  | 147 | == 4. Lecture de la valeur d'une entrée GPIO == | 
                          |  | 148 |  | 
                          |  | 149 | Maintenant que vous maîtrisez le contrôle d'un GPIO en sortie, passons au | 
                          |  | 150 | mode "entrée". | 
                          |  | 151 |  | 
                          |  | 152 | Toujours à l'aide de la librairie libgpio fournie avec ce TP, écrivez un | 
                          |  | 153 | programme qui configure la GPIO <à définir> en entrée. Et affichez la | 
                          |  | 154 | valeur de ces GPIO dans une boucle infinie (boucle d'échantillonnage). | 
                          |  | 155 |  | 
                          |  | 156 | Une fois réalisé, compilez votre programme comme précédemment à l'aide du | 
                          |  | 157 | Makefile fourni. Et validez votre code avec le chargé de TP ! | 
                          |  | 158 |  | 
                          |  | 159 | Ensuite, copiez votre programme sur la carte comme indiqué dans l'exercice | 
                          |  | 160 | précédent. | 
                          |  | 161 |  | 
                          |  | 162 | Les cartes Raspberry Pi sont équipées d'un petit circuit analogique dans | 
                          |  | 163 | lequel des boutons poussoir sont connectés aux certains GPIO. Ces GPIO sont | 
                          |  | 164 | connectés avec une résistance de Pull-Up, ce qui signifie que lorsque que vous | 
                          |  | 165 | n'appuyez pas, la valeur du GPIO vaut 1 et lorsque vous appuyez, le courant | 
                          |  | 166 | passe par à la masse et la valeur du GPIO passe à 1. | 
                          |  | 167 |  | 
                          |  | 168 | Qu'observez-vous ? | 
                          |  | 169 |  | 
                          |  | 170 | Quelle est la fréquence d'échantillonnage (approximative) en sachant que le | 
                          |  | 171 | processeur de la carte fonctionne à une fréquence de 700MHz ? | 
                          |  | 172 |  | 
                          |  | 173 | À supposer que vous êtes capable d'appuyer sur le bouton à une fréquence de | 
                          |  | 174 | 10Hz (c.-à-d. 10 fois par seconde) et sachant que le théorème de Shannon dit | 
                          |  | 175 | qu'il faut au moins échantillonner au double de la fréquence du signal | 
                          |  | 176 | d'entrée pour ne pas perdre de cycle, quelle est la plus petite fréquence d'échantillonnage possible ? | 
                          |  | 177 |  | 
                          |  | 178 | Pour plus de fiabilité, on utilisera une fréquence d'échantillonnage de 100Hz. | 
                          |  | 179 | Comment pouvez-vous écrire un programme qui échantillonne à cette fréquence ? | 
                          |  | 180 |  | 
                          |  | 181 | == 5. Manipulation de registres bas-niveau == | 
                          |  | 182 |  | 
                          |  | 183 | Pour mieux comprendre les implications à bas niveau de l'utilisation d'un | 
                          |  | 184 | contrôleur de GPIO, on vous demande de réécrire les fonctions gpio_setup, | 
                          |  | 185 | gpio_config, gpio_value et gpio_update. | 
                          |  | 186 |  | 
                          |  | 187 | Vous réaliserez cela étape par étape. Aidez-vous des fichiers objet | 
                          |  | 188 | précompilés dans le répertoire lab1. | 
                          |  | 189 |  | 
                          |  | 190 | Par exemple, si vous souhaitez écrire votre propre gpio_setup, créez un | 
                          |  | 191 | fichier gpio_setup.c dans lequel vous écrirez votre code. Pour recompiler | 
                          |  | 192 | la librairie libgpio, il vous suffit de réutiliser le Makefile fourni. | 
                          |  | 193 |  | 
                          |  | 194 | ATTENTION: pour fonctionner avec le reste de la librairie libgpio, il vous | 
                          |  | 195 | faut déclarer dans gpio_setup.c une variable globale gpio_base_p de type | 
                          |  | 196 | uint32_t volatile *. Cette variable qui est un pointeur vers un entier | 
                          |  | 197 | non signé de 32 bits doit contenir l'adresse de début de la région de mémoire | 
                          |  | 198 | virtuelle associée après un appel à la fonction mmap. | 
                          |  | 199 |  | 
                          |  | 200 | == 6. Amusez-vous ! == | 
                          |  | 201 |  | 
                          |  | 202 | Maintenant que vous maîtrisez tous les aspects liés à la configuration et | 
                          |  | 203 | à la programmation des GPIO sur Raspberry Pi, laisser aller votre imagination | 
                          |  | 204 | et proposer d'autres programmes à exécuter sur la carte Raspberry Pi qui | 
                          |  | 205 | vous est fournie. |