Comment créer un pilote de périphérique Linux intégré (2)

Deuxième fois: enregistrement des gestionnaires et des pilotes d'appels système (méthode statique)

À propos de cette série

Article HowTo pour développer des pilotes de périphériques Linux embarqués en tant que modules de noyau. Tout le contenu de cet article peut être exécuté sur Raspberry Pi.

Le code source complet qui apparaît dans cet article

https://github.com/take-iwiw/DeviceDriverLesson/tree/master/02_01

Contenu de cette époque

Autorisez les utilisateurs à accéder aux pilotes de périphériques à l'ancienne (?) Manière. La dernière fois, j'ai créé une chose semblable à Hello World qui ne fournit des gestionnaires que lorsqu'un module est chargé / déchargé (insmod / rmmod). Cette fois, ouvrez / fermez à partir du programme ou du shell réel afin que la valeur puisse être lue / écrite. Pour ce faire, implémentez le traitement des appels système tels que ouvrir / fermer / lire / écrire. De plus, l'utilisateur enregistre le périphérique dans le noyau afin d'accéder à ce pilote de périphérique en tant que fichier de périphérique (/ dev / XXX). Cette fois, l'appareil est enregistré de manière fixe de manière statique. Cette méthode est ancienne et semble être obsolète maintenant, mais je vais faire cette étape pour la comprendre.

Makefile pour build

Puisqu'il n'y a qu'un seul fichier, préparez le Makefile suivant. Créez MyDeviceModule.ko à partir du code source myDeviceDriver.c.

CFILES = myDeviceDriver.c

obj-m := MyDeviceModule.o
MyDeviceModule-objs := $(CFILES:.c=.o)

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean

Code source du pilote de périphérique

myDeviceDriver.c


#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/sched.h>
#include <asm/current.h>
#include <asm/uaccess.h>

#define DRIVER_NAME "MyDevice_NAME"
#define DRIVER_MAJOR 63

/*Fonction appelée à l'ouverture*/
static int myDevice_open(struct inode *inode, struct file *file)
{
	printk("myDevice_open\n");
	return 0;
}

/*Fonction appelée à la fermeture*/
static int myDevice_close(struct inode *inode, struct file *file)
{
	printk("myDevice_close\n");
	return 0;
}

/*Fonction appelée lors de la lecture*/
static ssize_t myDevice_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
	printk("myDevice_read\n");
	buf[0] = 'A';
	return 1;
}

/*Fonction appelée au moment de l'écriture*/
static ssize_t myDevice_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	printk("myDevice_write\n");
	return 1;
}

/*Table des gestionnaires pour divers appels système*/
struct file_operations s_myDevice_fops = {
	.open    = myDevice_open,
	.release = myDevice_close,
	.read    = myDevice_read,
	.write   = myDevice_write,
};

/*Route(insmod)Fonctions parfois appelées*/
static int myDevice_init(void)
{
	printk("myDevice_init\n");
	/*★ Enregistrez ce pilote dans le noyau*/
	register_chrdev(DRIVER_MAJOR, DRIVER_NAME, &s_myDevice_fops);
	return 0;
}

/*Décharger(rmmod)Fonctions parfois appelées*/
static void myDevice_exit(void)
{
	printk("myDevice_exit\n");
	unregister_chrdev(DRIVER_MAJOR, DRIVER_NAME);
}

module_init(myDevice_init);
module_exit(myDevice_exit);

Définition du gestionnaire pour l'appel système

Définissez une fonction de gestionnaire pour les appels système (ouvrir, fermer, lire, écrire) de l'utilisateur. Cette fois, pour le moment, je vais simplement sortir un journal ou renvoyer une valeur fixe. Stockez ces fonctions dans s_myDevice_fops.

Enregistrez le pilote dans le noyau

Lorsque le module est chargé (c'est-à-dire dans myDevice_init), la fonction register_chrdev enregistre ce pilote de périphérique dans le noyau en tant que périphérique de caractères. "Le numéro principal de ce pilote de périphérique est DRIVER_MAJOR (63) et le nom est DRIVER_NAME (" MyDevice_NAME "). La table des gestionnaires pour chaque appel système est dans s_myDevice_fops», dit-il. Le nombre majeur spécifié ici est un nombre très important utilisé pour identifier l'appareil.

À propos, les nombres majeurs 60-63, 120-127, 240-254 semblent être des numéros réservés aux expériences locales. Par conséquent, j'ai utilisé 63 cette fois.

Contrôle de fonctionnement

Construire et charger

Construisez et chargez avec la commande suivante.

make
sudo insmod MyDeviceModule.ko

Après cela, vérifiez la liste des appareils enregistrés. Ensuite, comme enregistré dans le code, vous pouvez voir que cet appareil ("MyDevice_NAME") est enregistré sous le numéro de mesure 63 à la place des appareils Character.

cat /proc/devices
Character devices:
  1 mem
réduction
 63 MyDevice_NAME

Créer un fichier de périphérique pour l'accès utilisateur

Les utilisateurs accèdent généralement aux pilotes de périphérique à l'aide de fichiers de périphérique. Je vais préparer le fichier de l'appareil. Utilisez la commande mknod pour cela. Le premier argument est le nom du fichier de périphérique. C'est OK avec n'importe quoi. Le deuxième argument est le type de périphérique. Cette fois, il s'agit d'un périphérique de caractères, alors définissez c. Le troisième argument est le numéro majeur du périphérique correspondant au fichier de périphérique à créer. Cela doit correspondre au numéro de pilote de périphérique que vous avez créé précédemment. Cette fois, c'était 63, alors précisez 63. Le quatrième argument est le nombre mineur. Il est utilisé pour distinguer lors de la création de plusieurs fichiers de périphérique pour le même périphérique. Mettez 1 pour le moment.

Après avoir créé / dev / myDevice avec mknod, modifiez le droit d'accès pour que tout le monde puisse y accéder.

sudo mknod /dev/myDevice c 63 1
sudo chmod 666 /dev/myDevice

ls -la /dev
crw-rw-rw-  1 root root    63,   1 Dec 17 23:08 myDevice

Essayez de lire et d'écrire à partir du shell

Pour vérifier l'opération, vous pouvez écrire du code C qui ouvre le / dev / myDevice créé cette fois, le lit / l'écrit et le ferme, mais par souci de simplicité, vérifiez-le depuis le shell.

Tout d'abord, vérifiez l'écriture avec la commande suivante

echo "a" > /dev/myDevice
dmesg

Si vous regardez le journal avec dmesg après avoir émis la commande, vous pouvez voir que la fonction d'écriture implémentée est appelée. Je pense qu'il est appelé deux fois à cause de "a" et "\ 0". En outre, ouvrir et fermer sont appelés automatiquement.

[11974.888831] myDevice_open
[11974.888934] myDevice_write
[11974.888944] myDevice_write
[11974.888968] myDevice_close

Ensuite, vérifiez la lecture avec la commande suivante.

cat /dev/myDevice

Si vous tapez cette commande, 'A' sera affiché à l'infini sur la console, veuillez donc l'arrêter avec Ctrl-c. En effet, la fonction myDevice_read renvoie toujours une valeur. En fait, il devrait renvoyer 0 lorsqu'il n'y a plus de valeurs à lire.

Terminer le traitement

Lorsque vous avez fini de l'utiliser, utilisez la commande suivante pour décharger le pilote de périphérique et supprimer le fichier de périphérique. Puisqu'il s'agit d'un pilote de périphérique, je ne pense pas que ce soit un cas d'utilisation réel pour finir de l'utiliser, mais je pense qu'il sera utilisé lors du débogage. Si vous créez un fichier de périphérique (/ dev / myDevice) une fois, le noyau appellera le pilote de périphérique nouvellement chargé tant qu'il a le même numéro majeur, quel que soit le nombre de pilotes de périphérique rmmod et insmod. Il semble qu'il sortira.

sudo rmmod MyDeviceModule
sudo rm /dev/myDevice

Recommended Posts

Comment créer un pilote de périphérique Linux intégré (11)
Comment créer un pilote de périphérique Linux intégré (1)
Comment créer un pilote de périphérique Linux intégré (4)
Comment créer un pilote de périphérique Linux intégré (7)
Comment créer un pilote de périphérique Linux intégré (2)
Comment créer un pilote de périphérique Linux intégré (3)
Comment créer un pilote de périphérique Linux intégré (6)
Comment créer un pilote de périphérique Linux intégré (5)
Comment créer un pilote de périphérique Linux intégré (10)
Comment créer un pilote de périphérique Linux intégré (9)
Comment créer un pilote de périphérique Linux intégré (12) (Terminé)
Comment faire reconnaître Yubico Yubikey par Manjaro Linux
Comment créer un outil CLI interactif avec Golang
Comment créer un serveur HTTPS avec Go / Gin
[Python] Comment créer une matrice de contiguïté / liste de contiguïté [Théorie des graphes]
Comment créer un laboratoire de piratage - Kali Linux (2020.1) VirtualBox 64 bits Partie 2-
Comment créer un laboratoire de piratage - Kali Linux (2020.1) VirtualBox 64-bit edition -
Comment créer un package Python (écrit pour un stagiaire)
Comment créer un fichier ISO (image CD) sous Linux
Comment faire une traduction japonais-anglais
Comment créer un bot slack
Comment installer VMware-Tools sur Linux
Comment créer un robot - Avancé
Comment créer une fonction récursive
Comment installer MBDyn (Linux Ubuntu)
[Blender] Comment créer un plug-in Blender
[Blender] Comment rendre les scripts Blender multilingues
Comment créer un robot - Basic
Comment créer un pilote de langage MongoDB C
Comment vérifier la version du système d'exploitation Linux
Comment transformer une chaîne en tableau ou un tableau en chaîne en Python
Comment obtenir le pilote d'imprimante pour Oki Mac sous Linux
Comment rendre les caractères de Word Cloud monochromatiques
Comment créer mon propre serveur Linux
Comment rendre le sélénium aussi léger que possible
[Linux] Comment subdiviser des fichiers et des dossiers
Comment créer un bot LINE à intelligence artificielle avec l'API de messagerie Flask + LINE
Comment installer aws-session-manager-plugin sur Manajro Linux
python3 Comment installer un module externe
Je veux savoir comment fonctionne LINUX!
[Linux] Comment utiliser la commande echo
Comment mettre à jour PHP sur Amazon Linux 2
Comment afficher des pictogrammes sur Manjaro Linux
Comment installer des packages sur Alpine Linux
[Cocos2d-x] Comment créer une liaison de script (partie 2)
Comment faire fonctionner Linux depuis la console
Comment installer le sous-système Windows pour Linux
Comment mettre hors tension de Linux sur Ultra96-V2
Comment mettre à jour la sécurité sur CentOS Linux 8
Je veux faire un programme d'automatisation!
Comment installer php7.4 sur Linux (Ubuntu)
Comment créer une clé USB à démarrage multiple (compatible Windows 10)
Comment créer un indicateur personnalisé Backtrader
Comment créer un plan de site Pelican