Changes between Version 4 and Version 5 of SujetTP2-2016


Ignore:
Timestamp:
Feb 3, 2016, 6:36:39 AM (9 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • SujetTP2-2016

    v4 v5  
    3939#define NBBP 1
    4040char led[NBLED];
    41 char btn[NBBP];
     41char bp[NBBP];
    4242 
    4343int main()
     
    5656      write( fd, led, NBLED);
    5757      sleep( 1);
    58       read( fd, btn, NBBTN);
    59    } while (btn[0] == '1');
     58      read( fd, bp, NBBP);
     59   } while (bp[0] == '1');
    6060   return 0;
    6161}
     
    6868Le module minimal se compose d'une fonction d'initialisation et d'une fonction de cleanup, dans le fichier `module.c`suivant:
    6969
    70 {{{
     70{{{#!c
    7171#include <linux/module.h>
    7272#include <linux/init.h>
     
    9292
    9393Ce fichier est cross compilé et copié sur la Raspberry Pi cible avec le fichier `Makefile` suivant:
    94 {{{
    95 CARD_NUMB       = 23
     94{{{#!make
     95CARD_NUMB       = 2X
    9696ROUTER          = 132.227.102.36
    97 LOGIN           = franck
     97LOGIN           = nom1-nom2
    9898LAB             = lab2
    9999
     
    101101
    102102CROSSDIR        = /users/enseig/franck/peri
    103 KERNELDIR       = $(CROSSDIR)/linux-rpi-3.18.y
     103KERNELDIR       = /dsk/l1/misc/linux-rpi-3.18.y
    104104CROSS_COMPILE   = $(CROSSDIR)/arm-bcm2708hardfp-linux-gnueabi/bin/bcm2708hardfp-
    105105       
     
    111111
    112112
    113  ||'''''Note:'''[[BR]]Ce Makefile a besoin des sources compilées du noyau. Si vous voulez le faire chez vous, il faut que vous preniez les sources de votre distribution. Vous pouvez suivre le tutoriel très clair [http://www.chicoree.fr/w/Compilation_crois%C3%A9e_d%27un_module_Linux_pour_Rasberry_Pi Compilation croisée d'un module linux pour Raspberry Pi]''.||
     113 ||'''''Note 1:'''\\ Ce Makefile a besoin des sources compilées du noyau. Comme elles sont volumineuses, elles sont copiées dans le répertoires `/dsk/l1/misc/linux-rpi-3.18.y`. Si vous voulez le faire chez vous, il faut que vous preniez les sources de votre distribution. Vous pouvez suivre le tutoriel très clair [http://www.chicoree.fr/w/Compilation_crois%C3%A9e_d%27un_module_Linux_pour_Rasberry_Pi Compilation croisée d'un module linux pour Raspberry Pi]''.||
     114
     115
     116 ||'''''Note 2:'''\\ Pour ne plus à avoir à taper le mot de passe, vous devez suivre la procédure décrite [[wiki:SujetTP1-2016#mdp]]||
    114117
    115118Sur votre compte enseignement, vous devez:
    116 * Créer ces fichiers et bien sûr, les comprendre.
    117 * '''changer la valeur des variables `CARD_NUMB`, `LOGIN`et `LAB` afin de les adapter respectivement au numéro de la carte choisie, au nom du répertoire créé par vous sur la raspberry et au nom du sous-répertoire créé par vous pour ce TP'''. Les répertoires et sous-répertoires doivent exister et vous devez donc commencer par vous logger sur votre carte Raspberry PI avec `ssh` pour les créer.
    118 * Compiler le module avec la commande `make`.
    119 * Copier sur la raspberry avec scp avec la commande `make upload`.
    120 
    121 Sur la carte Raspberry PI, vous devez:
     119* **Créer** ces fichiers et bien sûr, les comprendre.
     120* **changer la valeur des variables** `CARD_NUMB`, `LOGIN`et `LAB` afin de les adapter respectivement au numéro de la carte choisie, au nom du répertoire créé par vous sur la RaspberryPI et au nom du sous-répertoire créé par vous pour ce TP. Les répertoires et sous-répertoires doivent exister et vous devez donc commencer par vous logger sur votre carte RaspberryPI avec `ssh` pour les créer.
     121* **Compiler** le module avec la commande `make`.
     122* **Copier** sur la RaspberryPi avec scp avec la commande `make upload`.
     123
     124Sur la carte RaspberryPi, vous devez:
    122125* Dans le répertoire `$(LOGIN)/$(LAB)'(par exemple `franck/lab2`) où vous avez copié votre module
    123126
    124 {{{
     127{{{#!sh
    125128$ sudo insmod ./module.ko
    126129$ lsmod
     
    136139
    137140Votre driver devra être paramétré pour lui indiquer le numéro de ports utilisés pour les LEDS et les boutons.
    138 Dans un premier temps vous allez vous contenter d'indiquer le nombre de LED et de boutons pour le module de test, mais il faudra être plus précis pour le vrai driver.
     141Dans un premier temps vous allez vous contenter d'indiquer le nombre de LED et de bouton pour le module de test, mais il faudra être plus précis pour le vrai driver.
    139142
    140143Vous devez ajouter dans module.c (faite d'équivalent pour les boutons):
    141 {{{
     144{{{#!c
    142145static int led;
    143146module_param(LED, int, 0);
     
    152155}}}
    153156Le paramètre est défini au moment de l'insertion.
    154 {{{
     157{{{#!sh
    155158$ insmod ./module.o led=2
    156159}}}
     
    158161== Étape 3 : création d'un driver qui ne fait rien mais dans le noyau ==
    159162
    160 Votre driver va être intégré dans un module. Vous allez donc créer un module nommé `ledbtn` paramétré avec les numéros de ports pour les LEDS et les boutons. Vous utiliserez un nouveau répertoire. Vous modifierez le Makefile en conséquence.
     163Votre driver va être intégré dans un module. Vous allez donc créer un module nommé `ledbp` paramétré avec les numéros de ports pour les LEDS et le bouton. Vous utiliserez un nouveau répertoire. Vous modifierez le Makefile en conséquence.
    161164
    162165* Vous ajoutez dans le fichier `.c` du module:
    163166 
    164 {{{
    165 struct file_operations fops_ledbtn =
    166 {
    167     .open       = open_ledbtn,
    168     .read       = read_ledbtn,
    169     .write      = write_ledbtn,
    170     .release    = release_ledbtn
     167{{{#!c
     168struct file_operations fops_ledbp =
     169{
     170    .open       = open_ledbp,
     171    .read       = read_ledbp,
     172    .write      = write_ledbp,
     173    .release    = release_ledbp
    171174};
    172175static int
    173 open_ledbtn(struct inode *inode, struct file *file) {
     176open_ledbp(struct inode *inode, struct file *file) {
    174177    printk(KERN_DEBUG "open()\n");
    175178    return 0;
     
    177180
    178181static ssize_t
    179 read_ledbtn(struct file *file, char *buf, size_t count, loff_t *ppos) {
     182read_ledbp(struct file *file, char *buf, size_t count, loff_t *ppos) {
    180183    printk(KERN_DEBUG "read()\n");
    181184    return count;
     
    183186
    184187static ssize_t
    185 write_ledbtn(struct file *file, const char *buf, size_t count, loff_t *ppos) {
     188write_ledbp(struct file *file, const char *buf, size_t count, loff_t *ppos) {
    186189    printk(KERN_DEBUG "write()\n");
    187190    return count;
     
    189192
    190193static int
    191 release_ledbtn(struct inode *inode, struct file *file) {
     194release_ledbp(struct inode *inode, struct file *file) {
    192195    printk(KERN_DEBUG "close()\n");
    193196    return 0;
     
    196199* Vous allez enregistrer ce driver dans ce module en ajoutant la fonction d'enregistrement dans la fonction init du module. Vous devez aussi prendre en compte les paramètres. C'est à vous de décider comment.
    197200
    198 {{{
    199 int major = register_chrdev(0, "ledbtn" &fops_ledbtn); // 0 est le numéro majeur qu'on laisse choisir par linux
     201{{{#!c
     202int major = register_chrdev(0, "ledbp" &fops_ledbp); // 0 est le numéro majeur qu'on laisse choisir par linux
    200203}}}
    201204* Vous allez décharger le driver dans ce module en ajoutant dans la fonction exit du module:
    202205
    203 {{{
    204 unregister_chrdev(major, "ledbtn");
     206{{{#!c
     207unregister_chrdev(major, "ledbp");
    205208}}}
    206209
     
    211214
    212215{{{
    213 sudo mknod /dev/ledbtn c major 0
    214 sudo chmod a+rw /dev/ledbtn
     216sudo mknod /dev/ledbp c major 0
     217sudo chmod a+rw /dev/ledbp
    215218}}}
    216219
    217220Le test de votre driver peut se faire par les commandes suivantes (avant de faire un vrai programme):
    218221
    219 {{{
    220 $ echo "rien" > /dev/ledbtn
    221 $ dd bs=1 count=1 < /dev/ledbtn
     222{{{#!sh
     223$ echo "rien" > /dev/ledbp
     224$ dd bs=1 count=1 < /dev/ledbp
    222225$ dmesg
    223226}}}
     
    225228== Étape 4 : accès aux GPIO depuis les fonctions du pilote ==
    226229
    227 Pour vous aider, voici un code qui fait clignoter la LED du GPIO04 dans le module noyau.
     230Pour vous aider, voici un code qui fait clignoter la LED du `GPIO04` dans le module noyau.
    228231* Pour l'accès aux GPIOs vous voyez que l'on peut simplifier les calculs d'adresses en utilisant une structure représentant l'organisation des registres.
    229232* Vous noterez également que l'adresse physique de base des GPIO (ici 0x20200000) est mappé dans l'espace virtuel du noyau à l'adresse '''io_addresse'''.
     
    231234Inspirez-vous de code pour votre pilote.
    232235
    233 {{{
     236{{{#!c
    234237#include <linux/module.h>
    235238#include <linux/init.h>