Différences entre versions de « Linux sunxi armbian gpio »
Ligne 135 : | Ligne 135 : | ||
223: consommateur = , Direction = IN , Autres: ACTIVE_HIGH | 223: consommateur = , Direction = IN , Autres: ACTIVE_HIGH | ||
</source> | </source> | ||
+ | On remarque qu'il nous manque l'état de la broche et il se récupère avec une autre structure: | ||
= Modification = | = Modification = |
Version du 9 juin 2020 à 12:30
Introduction
Nous allons piloter les broches d'un Orange Pi Zéro grâce à l'API C libgpiod ainsi qu'à la fonction ioctl.
- ioctl prend trois paramètres:
- un descripteur de fichier
- le code de la requête (souvent une macro)
- une valeur discrète (type primitif) ou un pointeur sur une structure de données.
#include <sys/ioctl.h>
int ioctl(int d, int requête, ...);
- libgpiod fournie les structures de données qui vont nous permettre de manipuler ou lire l'état des broches
#include <linux/gpio.h>
struct gpiochip_info {
char name[32];
char label[32];
__u32 lines;
};
struct gpioline_info {
__u32 line_offset;
__u32 flags;
char name[32];
char consumer[32];
};
Lecture
Informations sur les contrôleurs
Commençons par récupérer des informations sur les contrôleurs il faut d'abord récupérer leurs noms:
root@orangepizero:~# ll /dev/gpiochip*
crw------- 1 root root 254, 0 May 25 08:44 /dev/gpiochip0
crw------- 1 root root 254, 1 May 25 08:44 /dev/gpiochip1
Le programme ci-dessous permet d'afficher les informations de gpiochip0. Nous allons le mettre dans un fichier read_gpiochip.c:
#include <stdio.h> // pour EXIT_SUCCESS
#include <stdlib.h> // pour printf
#include <linux/gpio.h> // pour struct gpiochip_info
#include <fcntl.h> // pour open
#include <sys/ioctl.h> // pour ioctl
#include <string.h> // Pour memset
// Macro pour le nom du contrôleur
#define GPIO_CHIP "/dev/gpiochip0"
int main(int argc, char * argv[]){
// ouverture du contrôleur en lecture seule
int fd = open(GPIO_CHIP, O_RDONLY);
// création de la structure qui va contenir les informations
struct gpiochip_info chip_info;
// Initialisation de la structure avec des zéro (pour valgrind)
memset(&chip_info, 0, sizeof(struct gpiochip_info));
// Lecture des informations
ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chip_info);
// Affichage
printf("name = %s, label = %s, lines = %d\n", chip_info.name, chip_info.label, chip_info.lines);
return EXIT_SUCCESS;
}
Une fois compilé, ce programme nous apprend que le contrôleur possède 224 lignes:
gcc -o read_gpiochip.bin read_gpiochip.c
./read_gpiochip.bin
name = gpiochip0, label = 1c20800.pinctrl, lines = 224
Informations sur les broches
Pour avoir des informations sur les broches, le principe est le même, sauf que la structure utilisée est gpioline_info. Nous allons le mettre dans un fichier read_gpio.c:
#include <stdio.h> // pour EXIT_SUCCESS
#include <stdlib.h> // pour printf
#include <linux/gpio.h> // pour struct gpiochip_info
#include <fcntl.h> // pour open
#include <sys/ioctl.h> // pour ioctl
#include <string.h> // Pour memset
// Macro pour le nom du contrôleur
#define GPIO_CHIP "/dev/gpiochip0"
#define LINES 224
int main(int argc, char * argv[]){
// ouverture du contrôleur en lecture seule
int fd = open(GPIO_CHIP, O_RDONLY);
// Structure contenant les informations
struct gpioline_info info;
// Itération sur toutes les lignes
for (int offset = 0; offset < LINES; offset ++) {
// Initialisation de la structure avec des zéro (pour valgrind)
memset(&info, 0, sizeof(struct gpioline_info));
// Positionnement du numéro de la ligne à lire
info.line_offset = offset;
// Lecture des informations
ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &info);
// Affichage
printf(" %d: consommateur = %s, Direction = %s, Autres: %s %s %s %s\n",
info.line_offset, info.consumer,
info.flags & GPIOLINE_FLAG_IS_OUT ? "OUT" : "IN ",
info.flags & GPIOLINE_FLAG_ACTIVE_LOW ? "ACTIVE_LOW " : "ACTIVE_HIGH",
info.flags & GPIOLINE_FLAG_OPEN_DRAIN ? "OPEN_DRAIN" : "",
info.flags & GPIOLINE_FLAG_OPEN_SOURCE ? "OPEN_SOURCE" : "",
info.flags & GPIOLINE_FLAG_KERNEL ? "KERNEL" : "");
}
}
Une fois compilé, on peut afficher des informations sur les 224 broches du contrôleur gpiochip0:
gcc -std=c99 -o read_gpio.bin read_gpio.c
./read_gpio.bin
0: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
1: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
2: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
3: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
4: consommateur = , Direction = IN , Autres: ACTIVE_HIGH
5: consommateur = , Direction = IN , Autres: ACTIVE_HIGH
6: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
7: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
8: consommateur = , Direction = IN , Autres: ACTIVE_HIGH
9: consommateur = , Direction = IN , Autres: ACTIVE_HIGH
10: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
11: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
12: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
13: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
14: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
15: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
16: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
17: consommateur = orangepi:red:status, Direction = OUT, Autres: ACTIVE_HIGH KERNEL
18: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
19: consommateur = , Direction = OUT, Autres: ACTIVE_HIGH
20: consommateur = reg_vcc_wifi, Direction = OUT, Autres: ACTIVE_HIGH KERNEL
/..../
223: consommateur = , Direction = IN , Autres: ACTIVE_HIGH
On remarque qu'il nous manque l'état de la broche et il se récupère avec une autre structure: