Changes between Version 1 and Version 2 of IOC_T02
- Timestamp:
- Feb 10, 2022, 7:50:38 PM (3 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
IOC_T02
v1 v2 5 5 = Objectif général 6 6 7 L'objectif de la séance est de commander les LEDS et le bouton poussoir (BP) et en passant par un (des) pilote(s)installé(s) dans le noyau sur la !RaspberryPi 1.7 L'objectif de la séance est de commander les LEDS et le bouton poussoir (BP) et en passant par des pilotes installé(s) dans le noyau sur la !RaspberryPi 1. 8 8 9 9 Vous savez déjà contrôler les LEDS et accéder au BP depuis l'espace utilisateur. Pour cela, vous avez dû mapper dans l'espace virtuel du processus utilisateur la zone de l'espace d'adressage physique permettant l'accès aux GPIO. Mais, il vous fallait avoir les droits du root. En passant par un pilote, les LED et le BP seront accessibles par un utilisateur standard. … … 29 29 * **Pour les LEDS** 30 30 * Le driver LED ne commande qu'une seule LED dont il reçoit le numéro au moment de l'enregistrement. 31 * On éteint la led si on écrit '0', on l'allume en écrivant '1' , les aut32 * Si le d river led est/dev/led0_XY31 * On éteint la led si on écrit '0', on l'allume en écrivant '1'. 32 * Si le device led est accessible par /dev/led0_XY 33 33 {{{#!c 34 34 char led = '0'; 35 fd = open("/dev/led0_XY", O_WR);35 int fd = open("/dev/led0_XY", O_WR); 36 36 write( fd, &led, 1); 37 37 }}} … … 40 40 * Quand le bouton est relâché, le pilote met le caractère `'0'`. 41 41 * Quand le bouton est enfoncé, le pilote met une valeur différente de `'0'`. 42 * Si le d river bp est/dev/bp_XY42 * Si le device bp est accessible par /dev/bp_XY 43 43 {{{#!c 44 44 char bp; 45 fd = open("/dev/bp_XY", O_RD);45 int fd = open("/dev/bp_XY", O_RD); 46 46 read( fd, &bp, 1); 47 47 }}} … … 194 194 $ sudo insmod ./module.ko btn=18 195 195 }}} 196 * Pour les numéros de GPIO de LEDs, comme il p eut y en avoir plusieurs, vous pouvez utiliser `module_param_array`.196 * Pour les numéros de GPIO de LEDs, comme il pourrait y en avoir plusieurs (si vous voulez commander les deux leds en même temps), vous pouvez utiliser `module_param_array`. 197 197 {{{#!c 198 198 #define NBMAX_LED 32 … … 224 224 === Création du driver 225 225 226 * Votre driver va être intégré dans un module. Vous allez donc créer un module **nommé `led bp`** (et non plus `module`) 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.227 * Vous ajoutez dans le fichier `.c` du module `led bp`:226 * Votre driver va être intégré dans un module. Vous allez donc créer un module **nommé `led`** (et non plus `module`) 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. 227 * Vous ajoutez dans le fichier `.c` du module `led`: 228 228 {{{#!c 229 229 … … 231 231 232 232 static int 233 open_led bp(struct inode *inode, struct file *file) {233 open_led_XY(struct inode *inode, struct file *file) { 234 234 printk(KERN_DEBUG "open()\n"); 235 235 return 0; … … 237 237 238 238 static ssize_t 239 read_led bp(struct file *file, char *buf, size_t count, loff_t *ppos) {239 read_led_XY(struct file *file, char *buf, size_t count, loff_t *ppos) { 240 240 printk(KERN_DEBUG "read()\n"); 241 241 return count; … … 243 243 244 244 static ssize_t 245 write_led bp(struct file *file, const char *buf, size_t count, loff_t *ppos) {245 write_led_XY(struct file *file, const char *buf, size_t count, loff_t *ppos) { 246 246 printk(KERN_DEBUG "write()\n"); 247 247 return count; … … 249 249 250 250 static int 251 release_led bp(struct inode *inode, struct file *file) {251 release_led_XY(struct inode *inode, struct file *file) { 252 252 printk(KERN_DEBUG "close()\n"); 253 253 return 0; 254 254 } 255 255 256 struct file_operations fops_led bp=257 { 258 .open = open_led bp,259 .read = read_led bp,260 .write = write_led bp,261 .release = release_led bp256 struct file_operations fops_led = 257 { 258 .open = open_led_XY, 259 .read = read_led_XY, 260 .write = write_led_XY, 261 .release = release_led_XY 262 262 }; 263 263 }}} … … 269 269 * et **dans la fonction d'initialisation du module**, vous ajoutez l'enregistrement du driver, 270 270 {{{#!c 271 major = register_chrdev(0, "led bp", &fops_ledbp); // 0 est le numéro majeur qu'on laisse choisir par linux271 major = register_chrdev(0, "led", &fops_led); // 0 est le numéro majeur qu'on laisse choisir par linux 272 272 }}} 273 273 * et **dans la fonction exit du module**, vous allez décharger le driver dans ce module en ajoutant : 274 274 {{{#!c 275 unregister_chrdev(major, "led bp");275 unregister_chrdev(major, "led"); 276 276 }}} 277 277 … … 281 281 * Vous allez chercher dans le fichier `/proc/devices` le numéro `major` choisi par linux. 282 282 * vous allez maintenant créer le noeud dans le répertoire `/dev` et le rendre accessible par tous. 283 Le numéro mineur est 0 car il n'y a qu'une seule instance. 283 * Dans les lignes qui suivent pensez à remplacer `major` par sa valeur ! 284 * Le numéro mineur est 0 car il n'y a qu'une seule instance. 285 284 286 {{{ 285 sudo mknod /dev/led bpc major 0286 sudo chmod a+rw /dev/led bp287 sudo mknod /dev/led0_XY c major 0 288 sudo chmod a+rw /dev/led0_XY 287 289 }}} 288 290 … … 292 294 * Le test de votre driver peut se faire par les commandes suivantes (avant de faire un vrai programme): dites ce que vous observez, en particulier, quelles opérations de votre driver sont utilisées. 293 295 {{{#!sh 294 $ echo "rien" > /dev/led bpXY295 $ dd bs=1 count=1 < /dev/led bp296 $ echo "rien" > /dev/led0_XY 297 $ dd bs=1 count=1 < /dev/led0_XY 296 298 $ dmesg 297 299 }}} … … 391 393 === Travail à faire 392 394 393 * Ecrivez le driver complet pour le 394 * Un script de chargement .395 * Ecrivez le driver complet pour les leds et le BP 396 * Un script de chargement (vu en cours) 395 397 * un programme de validation utilisant le driver.