Version 5 (modified by 10 years ago) (diff) | ,
---|
Premier pilote
Objectif
L'objectif de la séance est de commander les LEDS et les boutons poussoir en passant par un pilote. Lors de la dernière séance pour commander les LEDS et accéder aux boutons, vous aviez dû mapper dans l'espace virtuel de l'utilisateur la zone de mémoire permettant l'accès aux GPIO. Il vous fallait avoir les droits du root pour cela. Désormais, les LED et boutons seront accessibles en mode utilisateur.
Nous allons donc créer un pilote pour le périphérique LED+BoutonsPoussoir.
Ce pilote sera accessible dans par le pseudo-fichier /dev/ledbtn
(noter que vous serez peut-être obligé de changer un peu le nom pour éviter les conflits avec vos camarades).
Par exemple vous pourrez écrire cela dans un fichier test.c
ci-dessous. Ce que fait ce programme importe peu. Ce qui est important c'est que ce programme s'exécute entièrement en mode utilisateur.
Le comportement proposé ici du pilote est le suivant.
- Pour les LEDS, on envoie un tableau de caractère de 4 cases. La case 0 définit l'état de la LED 0 (
'0'
LED éteinte sinon LED allumée). - Pour les boutons, on propose un tableau de caractères de 2 cases. Le pilote lit l'état du bouton 0 et le met dans la case 0, et l'état du bouton 1 et le met dans la case 1. Quand le bouton est relâché, le pilote met le caractère
'0'
, quand le bouton est enfoncé, le pilote met la valeur'1'
.
C'est une proposition, vous pouvez faire comme bon vous semble.
#include <stdio.h> char led[4]; char btn[2]; int main() { int fd = open("/dev/ledbtn", O_RDWR); if (fd < 0) { fprintf(stderr, "Erreur d'ouverture du pilote LED et Boutons\n"); exit(1); } do { for ( i=0; i<4; i++) { memcpy( LED, "0000", 4); LED[i] = '1'; write( fd, LED, 4); sleep( 1); } read( fd, btn, 2); } while (btn[0] == '0'); return 0; }
Etape 1 : création et test d'un module noyau
La première étape consiste à créer un module noyau, l'insérer puis l'effacer du noyau.
Le module minimal se compose d'une fonction d'initialisation et d'une fonction de cleanup, dans le fichier module.c
suivant:
include <linux/module.h> #include <linux/init.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Charlie, 2015"); MODULE_DESCRIPTION("Module, aussitot insere, aussitot efface"); static int __init mon_module_init(void) { printk(KERN_DEBUG "Hello World !\n"); return 0; } static void __exit mon_module_cleanup(void) { printk(KERN_DEBUG "Goodbye World!\n"); } module_init(mon_module_init); module_exit(mon_module_cleanup);
Ce fichier est cross compilé et copié sur le raspberry cible avec le fichier Makefile
suivant:
CARD_NUMB = 23 ROUTER = 132.227.102.36 LAB = lab2 LOGIN = franck MODULE = module CROSSDIR = /users/enseig/franck/peri KERNELDIR = $(CROSSDIR)/linux-rpi-3.18.y CROSS_COMPILE = $(CROSSDIR)/arm-bcm2708hardfp-linux-gnueabi/bin/bcm2708hardfp- obj-m += $(MODULE).o default:; make -C $(KERNELDIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules clean:; make -C $(KERNELDIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) clean upload:; scp -P50$(CARD_NUMB) $(MODULE).ko pi@$(ROUTER):$(LOGIN)/$(LAB)
Vous devez créer ces fichiers et bien sûr, les comprendre.