Linear Feedback Shift Register with VHDL.
Tout est très simple si vous voulez démarrer rapidement. J'utilise un PC Portable Asus équipé de Windows Vista qui accède au réseau Internet via une Livebox ou une Neufbox selon mon lieu de connexion. Branchez via un cable Ethernet votre Beaglebone à un port libre de votre box (Assurez vous que ce port Ethernet soit disponible pour une connexion internet et pas réservé pour le service TV). Ensuite le plus rapide est ensuite d'installer le logiciel Putty (client SSH) qui permets d'émuler une console Linux et donc d'avoir accès à votre Beaglebone à distance via une fenêtre terminal/console classique à Linux. Pour établir la connexion il suffit juste d'entrer l'adresse IP de votre Beaglebone, le port d'accès 22, de sélectionner SSH et de cliquer sur Ouvrir. Si vous ne savez pas comment trouver l'adresse IP de votre platine, téléchargez donc le logiciel Advanced Port Scanner 1.3 très facile d'utilisation.
Bien évidemment si vous travaillez sur un PC équipé d'une distribution Linux, vous n'avez pas besoin de Putty, ouvrez une nouvelle console et connectez vous avec SSH à la platine Beaglebone.
Vous devriez donc avoir ces informations qui s'affichent sur la fenêtre/console ouverte par Putty.
Using username "root". root@192.168.1.22's password:
Appuyez ensuite sur la touche Entrée car il n'y a pas de mot de passe installé par défaut sous Root. Vous devriez donc vous retrouver avec la ligne classique d'invite de commandes.
root@beaglebone:~#
La platine Beaglebone dont je dispose est la version rev A3. Elle a été commandée chez l'intéressant magasin Lextronic. La carte SD livrée en série contenait la distribution Angstrom Linux du 16 nov 2011 (v2011-11-core).
J'ai fais une mise à jour en téléchargant ici downloads.angstrom-distribution.org/demo/beaglebone/archive l'image du 10 avril 2012. Puis j'ai construis avec Win32 Disk Imager la nouvelle carte SD. Cette version v2012.04-core est stable et permets toutes les fonctionnalités présentées dans ce site. Si vous avez un doute sur l'utilisation de Win32 Disk Imager, visionnez cette vidéo (en langue anglaise) vers la 5eme minute YouTube - Introduction BeagleBone.
Les 3 commandes suivantes vous permettrons donc de connaître respectivement votre version de la distribution Angstrom, le noyau ou kernel installé et le type de processeur installé sur la platine (un processeur Texas Instrument ARM Cortex-A8)
root@beaglebone:~# lsb_release -a Distributor ID: Angstrom Description: Angstrom GNU/Linux v2012.04-core (Core edition) Release: v2012.04-core Codename: Core edition
root@beaglebone:~# uname -a Linux beaglebone 3.2.14 #1 Mon Apr 9 12:21:19 CEST 2012 armv7l GNU/Linux
root@beaglebone:~# cat /proc/cpuinfo Processor : ARMv7 Processor rev 2 (v7l) BogoMIPS : 718.02 Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x3 CPU part : 0xc08 CPU revision : 2 Hardware : am335xevm Revision : 0000 Serial : 0000000000000000
Si vous voulez en savoir bien plus, allez voir cet excellent lien: Configuring-angstrom-linux (Langue anglaise).
Avant de démarrer, il est nécessaire d'avoir parcouru le document de référence de la platine Beaglebone. Vous le trouverez ici.
Notre premier script sera l'équivalent du fameux "Hello World" lorsque l'on découvre un nouveau langage de programmation: Faire clignoter une Led en utilisant l'une des pattes d'entrée/sortie de la platine. La platine dispose de 66 pattes paramétrables (max voltage 3.3V) mais nous n'en n'utiliserons qu'une pour brancher notre Led, la patte 3 de la double-rangée B aussi appelée Port 8 (celui de droite vu de dessus). Le montage est très simple, une resistance 220 Ohms reliée à la masse d'un côté, reliée à la cathode (-) de la Led de l'autre côté, l'anode (+) de la Led étant reliée à la patte 3 du Port 8 (P8_3). Vous aurez besoin d'une platine de prototypage rapide pour faire ce petit montage et les suivants ou l'extension Cape Breadboard qui se place sur la platine.
Comme la Table 9 du Manuel de Référence nous le montre, il peut exister jusqu'à 8 Modes, appelés Mux Mode, pour chaque patte. Le Mode par défaut dans la distribution Angstrom installée est souvent le Mode 7. Sachez que l'on trouve les différentes valeurs du Mux Mode à partir de ce fichier et qu'il est préférable de vérifier le Mode avant d'utiliser telle ou telle patte.
root@beaglebone:~# cd /sys/kernel/debug/omap_mux root@beaglebone:/sys/kernel/debug/omap_mux# ls ain0 gpmc_ad3 lcd_data3 mii1_txd1 ain1 gpmc_ad4 lcd_data4 mii1_txd2 ain2 gpmc_ad5 lcd_data5 mii1_txd3 ain3 gpmc_ad6 lcd_data6 mii1_txen ... ... ... ... gpmc_ad14 lcd_data14 mii1_rxerr xdma_event_intr0 gpmc_ad15 lcd_data15 mii1_txclk xdma_event_intr1 gpmc_ad2 lcd_data2 mii1_txd0
Revenons à la Table 9 du Manuel de Référence, on voit que le nom de la patte 3 du port 8 (P8_3) est GPIO1_6 et qu'il existe différents labels selon les Modes (0 à 7). L'erreur à ne pas commettre est de bien distinguer que pour sélectionner un Mux Mode, on va utiliser comme nom de fichier pour chaque patte le label qui correspond au Mode 0, ici gpmc_ad6. Cela peut paraître déroutant mais il en est ainsi. Ainsi pour afficher les informations de la patte GPIO1_6, on va utiliser cette commande.
root@beaglebone:/sys/kernel/debug/omap_mux# cat gpmc_ad6 name: gpmc_ad6.gpio1_6 (0x44e10818/0x818 = 0x0037), b NA, t NA mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7 signals: gpmc_ad6 | mmc1_dat6 | NA | NA | NA | NA | NA | gpio1_6
Si on voulait sélectionner le Mode 1 pour cette patte, on utiliserait cette commande. Cela sera revu plus tard, pas d'inquiétude !
root@beaglebone:/sys/kernel/debug/omap_mux# echo 1 > gpmc_ad6 root@beaglebone:/sys/kernel/debug/omap_mux# cat gpmc_ad6 name: gpmc_ad6.mmc1_dat6 (0x44e10818/0x818 = 0x0001), b NA, t NA mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE1 signals: gpmc_ad6 | mmc1_dat6 | NA | NA | NA | NA | NA | gpio1_6
Pour l'instant, gardons le Mode 7 qui est le mode Entrée/Sortie classique pour une patte (Notons le paramètre 0x0037 qui corresponds à un Mode 7 avec certains paramètres, tout comme on pourrait avoir le paramètre 0x0027... Nous y reviendrons plus tard). Le numéro de la patte 3 sur le port 8 que nous utiliserons dans le système de fichier Linux est 38. Pourquoi 38 me direz vous ? Tout simplement, 38=1*32+6, rappelez vous le nom de la patte GPIO1_6 (Pour utiliser la patte GPIO2_8, on utiliserait le nombre 2*32+8 soit 72).
Voilà la séquence de commandes Shell à utiliser pour allumer la Led.
root@beaglebone:~# cd /sys/class/gpio root@beaglebone:/sys/class/gpio# ls export gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport root@beaglebone:/sys/class/gpio# echo 38 > export root@beaglebone:/sys/class/gpio# ls export gpio38 gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport root@beaglebone:/sys/class/gpio# cd gpio38 root@beaglebone:/sys/class/gpio/gpio38# ls active_low direction edge power subsystem uevent value root@beaglebone:/sys/class/gpio/gpio38# echo out > direction root@beaglebone:/sys/class/gpio/gpio38# echo 1 > value
Il faut retenir que lorsque l'on "écrit" le numéro de patte 38 dans le fichier /sys/class/gpio/export, un répertoire gpio38 va être créé /sys/class/gpio/gpio38.
Plusieurs fichiers sont alors créés dans ce répertoire, les deux plus importants étant Direction et Value. Le premier sert à déterminer si la patte sera utilisé pour écrire, Direction aura la valeur 'Out' (Notre cas avec la Led) ou lire, Direction aura la valeur 'In'. Le deuxième sert pour choisir la valeur, '0' ou '1', état Bas ou Haut, qui sera écrite dans le fichier Value. Les pattes en Mode 7 (Entrée/Sortie classique) par défaut ont comme paramètre initial 'In' pour Direction d'où la nécéssité de changer pour 'Out'.
Nous pouvons vérifier l'état de la patte GPIO1_6 (gpio-38) en affichant les infos du kernel, ici dans cet exemple sysfs signifie que la patte est occupé par le système de fichier Linux, Direction vaut 'In' et Value vaut '1'.
root@beaglebone:~# cat /sys/kernel/debug/gpio GPIOs 0-31, gpio: gpio-6 (mmc_cd ) in lo GPIOs 32-63, gpio: gpio-35 (w1 ) in hi gpio-38 (sysfs ) in hi gpio-53 (beaglebone::usr0 ) out lo gpio-54 (beaglebone::usr1 ) out lo gpio-55 (beaglebone::usr2 ) out lo gpio-56 (beaglebone::usr3 ) out lo GPIOs 64-95, gpio: GPIOs 96-127, gpio:
Lorsqu'il faut éteindre la Led, rien de bien compliqué mais il ne faut pas oublier unexport pour libérer la patte ! Le répertoire gpio38 est alors détruit automatiquement comme on peut le voir ci-dessous.
root@beaglebone:/sys/class/gpio/gpio38# echo 0 > value root@beaglebone:/sys/class/gpio/gpio38# cd .. root@beaglebone:/sys/class/gpio# ls export gpio38 gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport root@beaglebone:/sys/class/gpio# echo 38 > unexport root@beaglebone:/sys/class/gpio# ls export gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport
Voici maintenant le script Shell tant attendu :) appelé blink.sh qui fait clignoter notre Led pendant 10 secondes. Vous avez le choix entre utiliser un éditeur intégré à Linux style Vim pour entrer ce script ou bien installer un logiciel tel que WinSCP pour créer le fichier sur votre PC avec le logiciel de votre choix et ensuite le transférer avec WinSCP en choisissant le protocole SCP qui est pris en charge par la distribution Angstrom. N'oubliez pas ensuite de faire dans le répertoire où sera situé le script chmod +x blink.sh pour le rendre exécutable puis le lancer par la commande ./blink.sh.
#!/bin/sh # Fichier blink.sh # Script qui fait clignoter 5 fois la Led connectée sur la patte P8_3. # Par précaution on place la patte dans le Mux Mode 7 (Mode par défaut). echo 7 > /sys/kernel/debug/omap_mux/gpmc_ad6 # On vérifie si le répertoire gpio38 existe ou non. # Dans la négative il est créé. if [ -d /sys/class/gpio/gpio38 ] then echo '/sys/class/gpio/gpio38 existe déjà' else echo 38 > /sys/class/gpio/export echo '/sys/class/gpio/gpio38 a été créé' fi # On place la patte en mode écriture (sortie). echo out > /sys/class/gpio/gpio38/direction # On boucle 5 fois la séquence de 2 secondes Allumé/Eteint. count=1 while [ $count -le 5 ]; do echo 1 > /sys/class/gpio/gpio38/value sleep 1 echo 0 > /sys/class/gpio/gpio38/value sleep 1 let count=count+1 done # On libère la patte P8_3. echo 'Patte 3 Port 8: Unexport' echo 0 > /sys/class/gpio/gpio38/value echo 38 > /sys/class/gpio/unexport
Nous allons utiliser un circuit tout simple pour lire l'état d'une patte avec un Bouton Poussoir classique qui, pressé ou non, allumera/éteindra une Led (branchée comme précédemment). Le principal problème (certes pas vraiment un facteur de gravité dans notre exemple mais important pour la suite) étant lié à une spécificité de la platine qui n'accepte PAS DU TOUT les tensions supérieures à 3.3V en lecture sur une patte en Mode Digital (Etat Haut / Etat bas) et qui a des limitations faibles pour le courant admis en entrée (Attention en Mode Analogique, la tension max. admise est de 1.8V mais nous y reviendrons).
Nous allons maintenant changer de Port et passer sur celui de gauche, le Port 9. Nous allons étudier les modes de deux pattes, la patte 12 et la patte 15. La patte 12 est référencée GPIO1_28 avec un nom de fichier pour le Mux Mode qui est gpmc_ben1 et la patte 15 est référencée GPIO1_16 avec un nom de fichier pour le Mux Mode qui est gpmc_a0.
root@beaglebone:/sys/kernel/debug/omap_mux# cat gpmc_ben1 name: gpmc_ben1.gpio1_28 (0x44e10878/0x878 = 0x0037), b NA, t NA mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7 signals: gpmc_ben1 | mii2_col | NA | mmc2_dat3 | NA | NA | mcasp0_aclkr | gpio1_28 root@beaglebone:/sys/kernel/debug/omap_mux# cat gpmc_a0 name: gpmc_a0.gpio1_16 (0x44e10840/0x840 = 0x0027), b NA, t NA mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7 signals: gpmc_a0 | mii2_txen | rgmii2_tctl | rmii2_txen | NA | NA | NA | gpio1_16
L'affichage ci-dessus nous confirme donc que les pattes sont bien dans le Mode 7 Entrée/Sortie classique mais avec des paramètres différents. Nous lisons 0x0037 pour la patte 12 et 0x0027 pour la patte 15. Nous avons besoin du manuel de référence du processeur du Beaglebone Manuel AM335X_ARM (4600 pages) et d'aller à la page 1278 pour analyser la table 9.58 présente sur cette page.
Attardons nous sur les 6 premiers bits de la configuration de la patte:
Les Bits 0-1-2 servent pour le paramétrage des Modes 0 à 7.
Les Bits 3-4-5-6 servent la configuration d'autre paramètres liés à la patte: Le Bit 3 sert à activer ou non les résistances de tirages internes,
le Bit 4 sert à sélectionner si on utilisera une résistance de tirage haut (Pull Up) ou bas (Pull Down), le Bit 5 sert à sélectionner le mode d'Entrée/Sortie
par défaut de la patte au démarrage. Le Bit 6 sera toujours à Zéro.
La valeur 0x0037 correspond en binaire à 0110111. Nous avons donc les Bits 0-1-2 mis à 1 ce qui correspond bien au Mode 7. Le Bit 3 est mis à 0 ce qui correspond à l'activation des resistances de tirage. Le Bit 4 est mis à 1 ce qui correspond à la sélection de la résistance de tirage interne Haut - Pull Up. Enfin le Bit 5 est mis à 1 ce qui correspond au paramétrage de la patte en mode Entrée.
La valeur 0x0027 correspond en binaire à 0100111. Nous avons donc les Bits 0-1-2 mis à 1 ce qui correspond bien encore au Mode 7. Le Bit 3 est mis à 0 ce qui correspond à l'activation des resistances de tirage. Le Bit 4 est mis à 0 ce qui correspond cette fois-ci à la sélection de la résistance de tirage interne Bas - Pull Down. Enfin le Bit 5 est mis à 1 ce qui correspond encore au paramétrage de la patte par défaut en mode Entrée.
Revenons à notre exemple avec le bouton poussoir qui ne sera donc pas "branché" de la même façon selon qu'on utilise ou non la résistance interne de tirage Haut ou de tirage Bas. En effet la résistance de tirage Bas - Pull Down interne est très faible, autour de 500 Ohms ce qui obligera à utiliser une autre résistance d'une valeur de 1 Kilo Ohms ou même plutôt 10 Kilo Ohms. Il n'y aura donc aucun risque d'endommager la platine avec un courant important.
Le mieux sera donc d'utiliser la configuration avec la résistance de tirage interne Haut - Pull Up, ce sera à la fois plus sûr et il n'y aura pas besoin de rajouter une résistance en plus. Dans ce cas une patte du bouton poussoir sera connectée à la masse et l'autre patte sera reliée à la patte 12 sur la platine. Nous devrions donc lire l'état Haut, donc 1, au repos et l'état Bas, donc 0, lorsque nous appuyerons sur le bouton poussoir. Si nous avions choisi d'utiliser l'autre patte, la patte 15, avec la résistance de tirage interne Pull Up, il aurait fallu changer le paramétrage et "écrire" le Mode 7 avec les paramètres qui correspondent à 0x0037 (Pull Up) en lieu et place de l'ancien paramètre 0x0027 (Résistance de tirage Bas).
Résumons donc notre petit circuit, notre Led est connectée sur la patte 3 du Port 8 (GPIO1_6) et le Bouton Poussoir sur la patte 12 du Port 9 (GPIO1_28). Et voici donc le script Shell qu'on appelera read_button.sh.
#!/bin/sh # Fichier read_button.sh # Script qui lit l'état d'un bouton poussoir sur la patte P9_12. # Une pression momentanée sur ce bouton poussoir éteint la Led sur P8_3. # On vérifie si le répertoire gpio60 (pour GPIO1_28) existe ou non. # Dans la négative il est créé. if [ -d /sys/class/gpio/gpio60 ] then echo '/sys/class/gpio/gpio60 existe déjà' else echo 60 > /sys/class/gpio/export echo '/sys/class/gpio/gpio60 a été créé' fi # On vérifie si le répertoire gpio38 (pour GPIO1_6) existe ou non. # Dans la négative il est créé. if [ -d /sys/class/gpio/gpio38 ] then echo '/sys/class/gpio/gpio38 existe déjà' else echo 38 > /sys/class/gpio/export echo '/sys/class/gpio/gpio38 a été créé' fi # Par précaution on place la patte P8_3 dans le Mux Mode 7. echo 7 > /sys/kernel/debug/omap_mux/gpmc_ad6 # Par précaution on place la patte P9_12 dans le Mux Mode 7 paramétré Pull Up. echo 37 > /sys/kernel/debug/omap_mux/gpmc_ben1 # La patte P9_12 est par défaut en mode lecture (cf paramétrage au dessus). # On ne fait donc rien. # On place la patte P8_3 dans la direction écriture (sortie). echo out > /sys/class/gpio/gpio38/direction # On boucle une grosse vingtaine de secondes pour laisser le temps de tester. count=1 while [ $count -le 200 ]; do let valeur=$(cat /sys/class/gpio/gpio60/value) echo $valeur > /sys/class/gpio/gpio38/value sleep 0.1 let count=count+1 done # On libère les pattes P8_3 et P9_12. echo 'Pattes P8_3 et P9_12: Unexport' echo 0 > /sys/class/gpio/gpio38/value echo 38 > /sys/class/gpio/unexport echo 60 > /sys/class/gpio/unexport
Nous allons utiliser ici un module de détection passive par infrarouge (PIR), aussi appelé capteur pyroélectrique. Le modèle choisi est celui vendu par Parallax car la tension minimale nécessaire à son fonctionnement est de 3.3V contrairement au module vendu par Lextronic qui a besoin de 5V. C'est un capteur "tout ou rien" qui est sensible à la longueur d'onde de la lumière infrarouge émise par le corps humain. Une lentille de Fresnel est utilisé pour que le capteur soit sensible à l'angle de détection le plus grand possible.
Le fonctionnement du capteur est très simple, il détecte tout mouvement dans un rayon de 6 à 7 mètres et la sortie du capteur passe en état Haut lorsque ce mouvement est détecté. Lorsque le mouvement cesse, la sortie passe à l'état Bas. Notons que le fonctionnement du module peut être configuré via un cavalier qui accepte 2 positions, H ou L, la sortie sera active tant qu'un mouvement sera détecté si H est sélectionné ou bien dans l'autre cas la sortie sera active chaque seconde à chaque détection. Je vous conseille d'utiliser la configuration du cavalier sur L si vous voulez capter tout les mouvements (y compris les parasites) ou bien plutôt de sélectionner H si vous voulez éviter d'avoir trop de déclenchements.
Nous allons donc brancher le module PIR sur notre platine en reliant les 2 masses entre elles, puis en connectant la sortie + du PIR sur la patte P9.3 (ou P9.4) VDD_3V3 et finalement en connectant la sortie Out du module sur la patte P9.23 GPIO1_17 de la platine que nous configurerons en mode entrée pour pouvoir lire l'état de la sortie du module PIR. Vérifions aussi que le Mux Mode de la patte 23 (label gpmc_a1 dans le système de fichier) est bien le Mode 7 paramétré en mode Pull Down 0x0027. En effet la résistance de tirage Pull Down de la platine Beaglebone est très très faible et la sortie Out doit être connectée directement sur la patte 23, sans résistance de tirage. Ce Mux Mode assurera donc un bon fonctionnement du module.
root@beaglebone:~# cat /sys/kernel/debug/omap_mux/gpmc_a1 name: gpmc_a1.gpio1_17 (0x44e10844/0x844 = 0x0027), b NA, t NA mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7 signals: gpmc_a1 | mii2_rxdv | rgmii2_rctl | mmc2_dat0 | NA | NA | NA | gpio1_17 root@beaglebone:~# echo 49 > /sys/class/gpio/export root@beaglebone:~# cat /sys/class/gpio/gpio49/direction in
Pour savoir si un mouvement a été détecté ou non, il suffit de lire la valeur de value sur l'entrée de la patte. Ce type de capteur est cependant très sensible, couvre un grand angle et peut facilement afficher un état haut même pour un très petit mouvement. Vous pourrez aussi lire un état Haut plusieurs secondes après la fin de tout mouvement, surtout si le cavalier de configuration est sur H. (Il est ainsi préférable de prévoir 20 à 30 secondes sans mouvement lors de sa mise en route pour avoir un bon étalonnement.)
root@beaglebone:~# cat /sys/class/gpio/gpio49/value 1 root@beaglebone:~# cat /sys/class/gpio/gpio49/value 1 root@beaglebone:~# cat /sys/class/gpio/gpio49/value 1 root@beaglebone:~# cat /sys/class/gpio/gpio49/value 1 root@beaglebone:~# cat /sys/class/gpio/gpio49/value 0