Vous êtes sur la page 1sur 9

ENSA Kénitra Informatique embarquée 2017/2018

Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

NB : Les questions sont indépendantes et peuvent être traitées dans n’importe quel ordre.

Barème : Quest1/4pts ; Quest2/2pts ; Quest3/6pts ; Quest4/2pts ; Quest5/4pts ; Quest6/2pts ;

1. Donnez la séquence de commandes shell pour configurer, avec le compte pi, les GPIOs de la
raspberry Pi , comme indiqué dans le tableau suivant :

Numéro BCM de la direction Valeur en sortie ou valeur en entrée sans


GPIO circuit externe
11 entrée 0
13 entrée 1
15 sortie 1
12 Sortie PWM Rapport cyclique 25% type Mark and space

gpio -g mode 11 in ; gpio -g mode down


gpio -g mode 11 in ; gpio -g mode up
gpio -g mode 11 out ; gpio -g write 11 1
gpio -g mode 12 pwm ; gpio -g pwm 12 256

2. La GPIO 2 (wpi) est utilisée comme entrée reliée à un bouton poussoir ; on souhaite que chaque fois
qu’on appuie sur le bouton l’entrée passe à 0 (logique) et quand on le relâche elle passe à 1
(logique) ; donnez le schéma de câblage du bouton poussoir et les commandes de configuration de la
GPIO 2.

3.3V

R
GPIO2(wpi) GPIO2(wpi)
BP
BP

solution 1 solution 2

Solution 1 : on utilise une résistance de pull up externe, on peut alors désactiver (tristate, flottante)
la résistance de pull_up_down interne ou la mettre aussi au pullup.
Configuration :
gpio mode 2 in ; gpio mode 2 tri (ou gpio mode 2 up)
Solution 2 : on n’utilise pas de résistance de pull_up_down externe, on utilise celle qui est interna à
la raspberry pi.
Configuration :
gpio mode 2 in ; gpio mode 2 up.
Comme ça si le BP n’est pas appuié l’état de l’entrée sera 1 (tirée vers 3.3V) ; si on appuie sur BP
l’état sera 0 (tirée par le BP vers Gnd)

Documents autorisés 1-9 Y.ROCHDI


ENSA Kénitra Informatique embarquée 2017/2018
Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

3. Rappel : La commande shell date permet de récupérer la date/heure actuelle, le symbole >> permet
de rediriger les sorties d’une commande pour les ajouter à la fin d’un fichier, comme le montre les
exemples suivantes :

a. Ecrire un programme C qui permet de configurer la GPIO 11 (BCM) comme entrée, puis
chaque fois que GPIO 11 passe de 1 à 0, la date de ce passage est ajoutée au fichier
journal.txt.

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h> // pour utilizer la function system

void journalisation(){ //fonction appellée si Interruption


system("date >> journal.txt"); //system() execution d’une commande shell
}
int main(){
wiringPiSetupGpio(); //numérotation BCM
pinMode(11,INPUT); //GPIO11 (BCM) comme entrée
//active une interruption sur front descendant sur GPIO11
wiringPiISR(11,INT_EDGE_FALLING,&journalisation);
while(1); //pour maintenir le programme en vie
return 0;
}

b. On souhaite rendre le programme précédent générique, dans le sens où il peut journaliser


les passages de 1 à 0 de n’importe quelle GPIO choisie par l’utilisateur et donner comme
premier argument en ligne de commande, dans n’importe quel fichier dont le nom est
donnée comme deuxième argument en ligne de commande. Exemple d’utilisation (nom du
programme prog_journal :
prog_journal 13 journ_13.txt # journalise les passag de 1 à 0 de GPIO13 ds journ_13.txt
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h> // pour utiliser la function system
#include <string.h> //pour utiliser strcat : concaténation

char cmde[50]="date >> "; //commande à compléter par le nom du journal


void journalisation(){ //fonction appellée si Interruption
system(cmde);//system() execution d’une commande shell
}
int Gpio ; //numéro de pin (BCM)
int main(int argc, char * argv[]){

Documents autorisés 2-9 Y.ROCHDI


ENSA Kénitra Informatique embarquée 2017/2018
Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

//argv[1]: chaine de caractère représentant le numéro de la GPIO


//argv[2] : chaine de caract représentant le nom du fichier journal
Gpio=atoi(argv[1]); //conversion premier argument en int

strcat(cmde, argv[2]) ; // concatener cmde et argv[2] vers cmde


//permet d’ajouter le nom du journal donné comme deuxième argument à la
//commande : date >>
wiringPiSetupGpio(); //numérotation BCM
pinMode(Gpio,INPUT); //Gpio (BCM) comme entrée
//active une interruption sur front descendant sur Gpio
wiringPiISR(Gpio,INT_EDGE_FALLING,&journalisation);
while(1); //pour maintenir le programme en vie
return 0;
}
4. On souhaite automatiser la commande d’allumage et d’extinction de l’éclairage public en fonction du
lever et du coucher du soleil, à l’aide d’un raspberry Pi. On suppose que la GPIO 2(wpi) est utilisée
pour commander un relais qui permet d’allumer/éteindre les ampoules (GPIO2 à 1 ampoules
allumées, GPIO2 à 0 ampoules éteintes). Les horaires de coucher/lever du soleil au niveau de la ville
de Kenitra sont donnés, en partie, par la figure 1. Proposer une crontab qui permet toujours
d’allumer les ampoules avant le coucher du soleil et de les éteindre après le lever du soleil ; on se
limitera dans cet exercice aux mois 01 au mois 05. NB : pendant tous les jours d’un mois les horaires
d’allumage/extinction seront les mêmes.

figure1. Une partie des horaires du lever/coucher du soleil au niveau de Kenitra


Pendant le mois de janvier le levier et le coucher du soleil changent, par exemple au 01/01 le lever est à
07 :32, alors qu’au 31/01 il sera proche de 07 :24 (lever au 01/02) ; on prendra alors comme heure
d’extinction, une heure juste supérieure à la plus tardive des heures du lever pendant le mois de janvier soit
07 :33 ; de même le coucher au 01/01 est à 17 :29 alors qu’au 31/01 il sera proche de 17 :57, on prendera
l’heure d’allumage comme étant l’heure juste inférieure à la plus précoce de toutes les heures du coucher
pendant mois de javier. En prenant en considération le NB ci-dessus, la crontab doit être
#m h dom mon dow command
33 7 * 1 * gpio write 2 0
28 17 * 1 * gpio write 2 1
25 7 * 2 * gpio write 2 0
56 17 * 2 * gpio write 2 1
57 6 * 3 * gpio write 2 0
22 18 * 3 * gpio write 2 1
15 6 * 4 * gpio write 2 0
47 18 * 4 * gpio write 2 1
39 5 * 5 * gpio write 2 0

Documents autorisés 3-9 Y.ROCHDI


ENSA Kénitra Informatique embarquée 2017/2018
Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

10 19 * 5 * gpio write 2 1

5. On désire concevoir un radar automatique de contrôle de vitesse basé sur une raspberry Pi munie
d’une caméra (picamera), d’un capteur électromagnétique enterré dans la voie ayant une sortie
logique qui reste à 1 tant qu’une voiture se trouve au-dessus du capteur (détection du métal du
châssis du véhicule), et d’un compteur temps réel externe (voir figure 2).

Oscillateur à
Quartz Freq F0 Compteur SPI
Ck
RST GPIO2 (BCM)
AND
Raspberry Pi

GPIO3(BCM)

SL : sortie logique du capteur

Capteur=détecteur de figure 2. Architecture Hardware du radar


métal automatique

Principe de fonctionnement simplifié : (Voir Illustration figure3).


Dans un état de repos SL est à 0 , le compteur est à 0, GPIO2 est à 1; les impulsions de l’oscillateur
n’atteignent pas l’entrée horloge Ck du compteur qui reste à 0 grâce au AND Logique. Chaque fois
qu’un véhicule arrive au-dessus du capteur, la sortie SL passe à 1 et reste à 1 pendant toute la durée
où le véhicule est détecté par le capteur. Cette durée dépend de la vitesse du véhicule (plus la
vitesse augmente plus cette durée diminue). Pendant cette durée, le compteur se met à compter (SL
passe à 1 compteur compte et s’arrête quand SL retourne à 0). Quand la Raspberry Pi détecte que
GPIO3 passe de 1 à 0 alors elle lit via le bus SPI la valeur du compteur, puis fait passer GPIO2 à 0 puis
à 1 pour provoquer la remise à 0 du compteur. Si la valeur lue est inférieure à un seuil S, alors la
raspberry pi commande la picamera pour prendre une photo du véhicule ayant commis une
infraction d’excès de vitesse. Cette photo est stockée localement sur la microSD de la Raspberry Pi
dans le répertoire /home/pi/ sous un nom de fichier ayant la forme suivante Date_heure.jpeg.

Documents autorisés 4-9 Y.ROCHDI


ENSA Kénitra Informatique embarquée 2017/2018
Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

SL=0
t<t1

t=t1
SL=1

t=t2
SL=1

t>t2 prise de photo si excès


SL=0 de vitesse

Rspi+picam

sortie GPIO2

sortie du capteur SL=GPIO3


temps

1
0
temps
entrée Ck du compteur

1
0 temps
t1 t2
compteur à 0 comptage des comptage
impulsions (F0) s’arrête compteur à 0

figure 3. Illustration du fonctionnement

a. Ecrire un script python qui permet d’implémenter le fonctionnement décrit précédemment :


notamment :
i. la configuration des GPIO, et la RAZ du compteur lors du lancement du script.
ii. La surveillance répétée de GPIO3 et la lecture de la valeur du compteur par une
fonction : on suppose l’existence d’une fonction spi_read(), qui quand elle est
appelée, retourne un entier représentant la valeur actuelle du compteur.
iii. La comparaison de la valeur lue avec un seuil S (entier qu’on suppose connu) et la
décision de prendre ou pas une photo.

Documents autorisés 5-9 Y.ROCHDI


ENSA Kénitra Informatique embarquée 2017/2018
Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

Non demandé dans le contrôle :


Pour faire un test sur raspberry munie de picamera, il faut :
*remplacer dans le script précédent GPIO 3 par GPIO 4 (BCM) par exemple (GPIO3 BCM joue un rôle
particulier, voir gpio readall)
*provoquer une impulsion sur cette entrée à l’aide des résistances PULL_UP_DOWN, à l’aide de la
commande tapée dans un terminal :
gpio -g mode 4 up ; sleep 1 ; gpio -g mode 4 down ; date

Documents autorisés 6-9 Y.ROCHDI


ENSA Kénitra Informatique embarquée 2017/2018
Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

b. En supposant l’existence d’un script python nommé transfert.py dans /home/pi, qui permet
de transférer un fichier donné comme argument en ligne de commande vers un serveur ftp ,
syntaxe :
./transfert.py nom_fichier
Donner un script shell qui permet de transférer toutes les photos capturées et stockées dans
/home/pi vers un le serveur ftp en vous inspirant des commandes shell suivantes :

Pour tout nom_fichier se trouvant dans Liste, copier ce fichier var ./rep_jpeg/ sous le nom
copie_nom_fichier

# !/bin/usr/bash
Liste=$(ls *.jpeg)
for fich in $Liste # pour chaque fichier dans liste
do
./transfert.py $fich #transférer le fichier vers serveur ftp, puis refaire pour le suivant
done

Complément d’informations (non demandé dans la question) : pour tester ce script on commence
part créer d’abord un script transfert.py, qui ne fait pas le transfert vers un serveur ftp mais juste
copie un fichier.jpeg donné en argument dans le même répertoire sous le nom cpfichier.jpeg (ceci
simule un transfert), ce script est donné ci-dessous :

Essai :

Documents autorisés 7-9 Y.ROCHDI


ENSA Kénitra Informatique embarquée 2017/2018
Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

6. On développe un projet en C de manière modulaire sous linux embarqué. Ce projet contient


plusieurs fichiers source .c et .h avec des dépendances qui sont regroupées dans le tableau suivant :
dépend de types.h lcd.h uart.h adc.h stepper.h
main.c *
stepper.c * *
adc.c * *
affich.c * * *
queue.c *
Ce tableau indique que, par exemple, stepper.c contient les directives suivantes :
#include "types.h"
#include "stepper.h"
donc stepper.c depend de types.h et stepper.c, et toute modification de l’un des deux fichiers doit
impliquer la recompilation de stepper.c pour obtenir stepper.o.
La cible qu’on souhaite obtenir après construction de ce projet sera appelé myprogram (exécutable),
et ça sera la cible par défaut.
Tous les fichiers source .c sont regroupés dans le répertoire /home/user/prj/sources
Tous les fichiers d’entête .h sont regroupés dans le répertoire /home/user/prj/sources/include
Ecrire un fichier Makefile (en indiquant où il faut le placer ?) qui permet :
· la construction du projet et l’obtention de myprogram à l’aide d’un appel à make de type :
/home/user/prj$ make ou make myprogram
· la suppression des fichiers .o et de myprogram à l’aide d’un appel à make de type :
/home/user/prj$ make clean
· la suppression des fichiers .o et mypogram puis la reconstruction du projet par un appel à
make de type :
/home/user/prj$ make clean_build

Fichier Makefile placé dans le répertoire /home/user/prj/ , car d’après les question l’appel à make
se fait à partir du répertoire /home/user/prj (indiqué par le prompt=invite de commande), donc
make cherchera Makefile dans ce répertoire (/home/user/prj/).
La solution présentée ici n’est pas la seule possible, on n’utilisera pas de commande cd pour
changer de répertoire s’il le faut, on utilisera plutôt les chemins relatifs par rapport au répertoire
où se trouve Makefile (en exploitant les variables)
les fichiers .o et l’exécutable myprogram seront générés dans le répertoire /home/user/prj, alors
que les .c sont dans /home/user/prj/sources et les .h sont dans /home/user/prj/sources/include

#Makefile à placer dans /home/user/prj


#répertoire ou se trouvent les .c relatif par rapport à /home/user/prj
Src=./sources/
#chemin relatif des .h
Inc= ./sources/include/

Documents autorisés 8-9 Y.ROCHDI


ENSA Kénitra Informatique embarquée 2017/2018
Filière d’ingénieur GE/SE-S8 Contrôle terminal 1H30

#liste des .o qui seront dans répertoire courant soit /home/user/prj


Obj= main.o stepper.o adc.o affich.o queue.o
#l'excec sera aussi dans /home/user/prj (répertoire crt à partir duquel est
#lancé make et où se trouve Makefile
myprogram : ${Obj}
cc -o myprogram ${Obj}
main.o : ${Src}main.c ${Inc}types.h
cc -I $Inc -c ${Src}main.c
stepper.o : ${Src}stepper.c ${Inc}types.h ${Inc}stepper.h
cc -I $Inc -c ${Src}stepper.c
adc.o : ${Src}adc.c ${Inc}types.h ${Inc}adc.h
cc -I $Inc -c ${Src}adc.c
affich.o : ${Src}affich.c ${Inc}types.h ${Inc}lcd.h ${Inc}uart.h
cc -I $Inc -c ${Src}affich.c
queue.o : ${Src}queue.c ${Inc}types.h
cc -I $Inc -c ${Src}queue.c

clean :
rm -f myprogram ${Obj}

#target clean_build revient à viser target clean puis target par défaut
#d’abord un clean puis une reconstruction
clean_build :
make clean
make

Documents autorisés 9-9 Y.ROCHDI

Vous aimerez peut-être aussi