GNU/Linux >> Tutoriels Linux >  >> Linux

Pilote de périphérique Linux IOCTL

Le ioctl La fonction est utile pour implémenter un pilote de périphérique afin de définir la configuration sur le périphérique. par exemple. une imprimante disposant d'options de configuration pour vérifier et définir la famille de polices, la taille de police, etc. ioctl peut être utilisé pour obtenir la police actuelle ainsi que pour définir la police sur une nouvelle. Une application utilisateur utilise ioctl pour envoyer un code à une imprimante lui indiquant de renvoyer la police actuelle ou de définir la police sur une nouvelle.

int ioctl(int fd, int request, ...)
  1. fd est le descripteur de fichier, celui renvoyé par open;
  2. request est le code de requête. par exemple GETFONT obtiendra la police actuelle de l'imprimante, SETFONT définira la police sur l'imprimante ;
  3. le troisième argument est void * . Selon le deuxième argument, le troisième peut être présent ou non, par ex. si le deuxième argument est SETFONT , le troisième argument peut être le nom de la police tel que "Arial";

int request n'est pas qu'une macro. Une application utilisateur est nécessaire pour générer un code de demande et le module de pilote de périphérique pour déterminer avec quelle configuration sur le périphérique doit être joué. L'application envoie le code de requête en utilisant ioctl puis utilise le code de requête dans le module du pilote de périphérique pour déterminer l'action à effectuer.

Un code de requête comporte 4 parties principales

    1. A Magic number - 8 bits
    2. A sequence number - 8 bits
    3. Argument type (typically 14 bits), if any.
    4. Direction of data transfer (2 bits).  

Si le code de la requête est SETFONT pour définir la police sur une imprimante, la direction du transfert de données sera de l'application utilisateur au module de pilote de périphérique (l'application utilisateur envoie le nom de la police "Arial" à l'imprimante). Si le code de requête est GETFONT , le sens va de l'imprimante à l'application utilisateur.

Afin de générer un code de requête, Linux fournit des macros de type fonction prédéfinies.

1._IO(MAGIC, SEQ_NO) les deux sont 8 bits, 0 à 255, par ex. disons que nous voulons mettre l'imprimante en pause. Cela ne nécessite pas de transfert de données. Nous générerions donc le code de requête comme ci-dessous

#define PRIN_MAGIC 'P'
#define NUM 0
#define PAUSE_PRIN __IO(PRIN_MAGIC, NUM) 

et utilisez maintenant ioctl comme

ret_val = ioctl(fd, PAUSE_PRIN);

L'appel système correspondant dans le module du pilote recevra le code et mettra l'imprimante en pause.

  1. __IOW(MAGIC, SEQ_NO, TYPE) MAGIC et SEQ_NO sont les mêmes que ci-dessus, et TYPE donne le type du prochain argument, rappelle le troisième argument de ioctl est void * . W en __IOW indique que le flux de données va de l'application utilisateur au module de pilote. Par exemple, supposons que nous voulions définir la police de l'imprimante sur "Arial" .
#define PRIN_MAGIC 'S'
#define SEQ_NO 1
#define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)

plus loin,

char *font = "Arial";
ret_val = ioctl(fd, SETFONT, font); 

Maintenant font est un pointeur, ce qui signifie qu'il s'agit d'une adresse mieux représentée par unsigned long , d'où la troisième partie de _IOW mentionne le type en tant que tel. En outre, cette adresse de police est transmise à l'appel système correspondant implémenté dans le module de pilote de périphérique sous la forme unsigned long et nous devons le convertir au bon type avant de l'utiliser. L'espace noyau peut accéder à l'espace utilisateur et cela fonctionne donc. les deux autres macros de type fonction sont __IOR(MAGIC, SEQ_NO, TYPE) et __IORW(MAGIC, SEQ_NO, TYPE) où le flux de données ira de l'espace noyau à l'espace utilisateur et dans les deux sens respectivement.

N'hésitez pas à me faire savoir si cela vous aide !


Un ioctl , ce qui signifie que le "contrôle d'entrée-sortie" est une sorte d'appel système spécifique à l'appareil. Il n'y a que quelques appels système sous Linux (300-400), qui ne suffisent pas à exprimer toutes les fonctions uniques que les périphériques peuvent avoir. Ainsi, un pilote peut définir un ioctl qui permet à une application de l'espace utilisateur de lui envoyer des commandes. Cependant, les ioctls ne sont pas très flexibles et ont tendance à être un peu encombrés (des dizaines de "nombres magiques" qui fonctionnent simplement... ou pas), et peuvent également être peu sûrs, car vous passez un tampon dans le noyau - une mauvaise manipulation peut casser les choses facilement.

Une alternative est le sysfs interface, où vous configurez un fichier sous /sys/ et lire/écrire cela pour obtenir des informations de et vers le conducteur. Un exemple de configuration :

static ssize_t mydrvr_version_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", DRIVER_RELEASE);
}

static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);

Et pendant la configuration du pilote :

device_create_file(dev, &dev_attr_version);

Vous auriez alors un fichier pour votre appareil en /sys/ , par exemple, /sys/block/myblk/version pour un pilote de bloc.

Une autre méthode pour une utilisation plus intensive est netlink, qui est une méthode IPC (communication inter-processus) pour parler à votre pilote via une interface socket BSD. Ceci est utilisé, par exemple, par les pilotes WiFi. Vous communiquez ensuite avec lui depuis l'espace utilisateur en utilisant le libnl ou libnl3 bibliothèques.


Linux
  1. Linux - Signifié par le montage d'un périphérique sous Linux ?

  2. Linux :Comment trouver le pilote de périphérique utilisé pour un périphérique ?

  3. Linux – Comment trouver le pilote (module) associé à un périphérique sous Linux ?

  4. Comment créer un périphérique de bloc virtuel (périphérique de boucle/système de fichiers) sous Linux

  5. Comment écrire un pilote de périphérique de bloc linux en espace utilisateur?

Comment installer un pilote de périphérique sous Linux

Tout est un fichier sous Linux - Partie 1

Comment trouver le driver (module) associé à un périphérique sous Linux ?

Comprendre les pilotes de périphérique Linux de la webcam

setserial :impossible d'obtenir les informations de série :ioctl inapproprié pour l'appareil

Énumération cohérente des périphériques Linux