TP2 : Une plate-forme pour les GPIOs
Table of Contents
1 Objectif et consignes :
1.1 Objectifs
L'objectif de ce TP est de se familiariser avec les bases de la programmation C dans Linux, notamment les structures, la gestion de la mémoire et les GPIOs à travers l'écriture d'une librairie de la manipulation de ses derniers. Au delà du compte rendu classique "libre" que vous allez réaliser, vous devez répondre à toutes les questions posées dans ce TP.
1.2 Consgines
20 minutes avant la fin de chaque TP.
- Transférer vos fichiers sur un stockage externe à la carte.
- Supprimer tout vos fichiers de la carte.
- Appelez la commande history -c
- executer la commande "sudo shutdown now"
Le compte rendu sera remis à la fin de la deuxième séance du cours avec le code de la platform que vous avez developpé.
2 Présentation de l'extension de la Jetson Nano :
La carte Jetson Nano, dont vous disposez, est équipée d'une extension permettant de la lier avec un certain nombre de capteurs est d'actionneurs, explicitement : (i) un analyseurs logique, (ii) un moteur, un capteur ultra-son, un accéléromètre et gyroscope, une suite de LED et deux boutons.
Chacun de ces composants est lié à une liste de broches GPIO de la carte Jetson Nano. Dans les figures ci-dessous vous trouvez les schémas de câblage des différents capteurs et actionneurs avec la carte.
Figure 1: Les connexions de bouttons
Figure 2: Les connexions de Leds
Figure 3: Les connexions du capteur ultra-son
Figure 4: Les connexions de l'accéléromètre
Figure 5: Les connexions de l'analyseur logique
Figure 6: Les connexions du moteur
La correspondance entre broches et GPIO Linux est spécifié à travers la figure :
Figure 7: Les correspondances Broche-GPIO
3 Le projet :
Le projet va se composer de 3 fichiers : un fichiers utils.c, utils.h, et main.c. Les deux premiers fichiers contiennent les fonctions nécessaires pour communiquer avec les GPIOs de la carte.
- Définissez la fonction fatal_error dans utils.c ainsi que son prototype dans utils.h :
void fatal_error(int error_code, char *msg) { printf("Error code %d : %s \n", error_code, msg); exit(-1); };
- Appeler la fonction dans le main pour tester son fonctionnement.
- Écrivez un fichier Makefile pour compiler le projet, et tester votre code (PS: pour compiler on utilise la commande make).
4 Les structures et la mémoire :
Pour réaliser les entrées/sorties à travers les GPIOs, on va tout d'abord définir une structure qui représente un GPIO de type : struct GPIO.
- En se basant sur votre cours proposez une structure C pour représenté un GPIO.
- Quelle est la taille mémoire de votre structure GPIO?
- Avant de continuer, valider cette étape par votre enseignant.
5 Ouverture et direction de GPIO :
5.1 Étape 1 :
Nous voulons maintenant définir les broches valides, et les broches invalides de notre carte Jetson Nano. Ainsi, que son port mapping, à travers la structure suivant :
#define PINS -1, -1, -1, -1, -1, -1, 216, -1, -1, -1, 50, 79, 14, -1, 194, 232, -1, 15, 16, -1, 17, 13, 18, 19, -1, 20, -1, -1, 149, -1, 200, 168, 38, -1, 76, 51, 12, 77, -1, 78 int gpios_list[40] = {PINS};
- Écrivez une fonction check\pin(int pin) qui vérifie que une broche représente bien un GPIO valide, si non elle fait appelle à la fonction fatal\error.
- Tester votre fonctions
5.2 Étape 2 :
Nous allons définir la fonction load_pin qui va, à partir du numéro de la broche, remplir votre structure de GPIO (utilisez malloc pour créer une structure et l'opérateur d'accès [., ou ->] pour remplir les différents champs de votre structure).
struct GPIO * load_pin(int pin)
5.3 Étape 3 :
Nous allons définir la fonction init_GPIOS qui va appeler la fonction load_pin pour initialiser tout vos GPIOs.
void init_GPIOs()
- Écrivez une fonction display_gpio qui affiche le contenu d'un GPIOs.
- Utilisez cette fonction pour vérifier que vos GPIOs sont correctement initialiser.
5.4 Étape 4 :
Nous allons définir la fonction export_pin qui va exporter le GPIO gpio.
void export_pin(struct GPIO *gpio)
5.5 Etape 5 :
Nous allons définir la fonction unexport_pin qui va fermer le GPIO gpio.
void unexport_pin(struct GPIO *gpio)
5.6 Etape 6 :
Nous allons définir la fonction set_direction qui va choisir la direction de sortie : si direction est définie en INPUT, la sortie doit etre défini en sortie, si non elle sera défini en entrée.
#define INPUT 1 #define OUTPUT 0 void set_direction(struct GPIO *pin, int direction)
5.7 Etape 7 :
Écrivez la fonction pin_mode qui va vérifier si la broche est un GPIO, ouvrir la broche, si elle n'a pas été ouverte auparavant par l'application, export cette dernier et défini la direction en sortie ou en entrée.
int pin_mode(int pin, int direction)
Valider Cette étape avec votre enseignant.
6 Lecture/Écriture de GPIO :
Une fois un GPIO ouvert, on a souvent tendance à effectuer plusieurs opération de lecture et/ou écriture sur ce dernier avant de le fermer. Ainsi, nous allons séparer la lecture/l'écriture.
Définissez la fonction open_value qui ouvre le fichier et stock son pointer dans votre structure.
void open_value(struct GPIO *pin)
Cette fonction doit ainsi etre appelé une fois le GPIO est ouvert.
Écrivez les fonctions digital_write et digital_read. et effectuer une écriture (ou lecture) des valeurs HIGH ou LOW.
#define HIGH 1 #define LOW 0 void digital_write(int port, int value); int digital_read(int port);
7 Allumer les Leds
Amuser vous à allumer et éteindre les différents Leds.
8 Les performances :
Faites un Le signal carrée, afin de tester les performances de votre plate-forme. Utiliser les analyseurs logiques, puis les oscilloscope.
Remplacer vos appels des fonctions de lecture et écriture de fichiers en utilisant les appels système open, write et read afin d'améliorer davantage les performances de votre plate-forme.
Proposez vos propres améliorations à cette plate-forme.
9 Le capteur ultra-son :
Utilisez les différentes fonctions pour effectuer une lecture sur le capteurs ultra-son