La Platine Beaglebone, Tutoriels, Trucs et Astuces.

Linear Feedback Shift Register with VHDL.

Mise en route.

Quelques informations sur la platine.

Un premier script pour débuter: Ecriture binaire sur une patte.

Notre deuxième script: Lecture binaire sur une patte.

Interfaçage avec un module de détection PIR.


Mise en route.

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:~#

Quelques informations sur la platine.

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).

Un premier script pour débuter: Ecriture binaire sur une patte.

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

Notre deuxième script: Lecture binaire sur une patte.

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

Interfaçage avec un module de détection PIR.

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