Comment utiliser le port parallèle

Comment utiliser le port parallèle n'est pas un problème Gambas, mais un problème du noyau Linux.

Le noyau empêche n'importe quel programme de faire de vilaines choses comme l'accès direct au matériel. À la place, vous devez utiliser les périphériques, c'est-à-dire les fichiers spéciaux situés dans le répertoire /dev, qui vous permettent d'accéder au matériel sous le contrôle du noyau.

Vous pouvez accéder au port parallèle en utilisant les fichiers de périphérique comme /dev/lp0.../dev/lpN. Mais si vous avez besoin de plus de contrôles, c'est-à-dire si vous voulez être capable d'écrire sur les ports d'entrées/sorties x86, vous utilisez un fichier de périphérique nommé /dev/port.

Vous trouverez plus d'explications à cette adresse :

http://www.faqs.org/docs/Linux-mini/IO-Port-Programming.html

(NDT : L'association Traduc.org a publié une traduction de ce document sous le nom "Petit guide de programmation des ports d'entrées / sorties sous Linux".

Elle est disponible à l'adresse suivante : http://traduc.org/Guides_pratiques/Suivi/IO-Port-Programming/Document)

Le chapitre 2.2 dit ceci:

2.2 An alternate method: /dev/port

Another way to access I/O ports is to open() /dev/port (a character device,
major number 1, minor 4) for reading and/or writing (the stdio f*() functions have internal buffering, so avoid them). Then lseek() to the appropriate byte in the file (file position 0 = port 0x00, file position 1 = port 0x01, and so on), and read() or write() a byte or word from or to it.

Naturally, for this to work your program needs read/write access to /dev/port.
This method is probably slower than the normal method above, but does not
need compiler optimisation nor ioperm(). It doesn't need root access either,
if you give a non-root user or group access to /dev/port --- but this is a
very bad thing to do in terms of system security, since it is possible to
hurt the system, perhaps even gain root access, by using /dev/port to access
hard disks, network cards, etc. directly.

You cannot use select(2) or poll(2) to read /dev/port, because the hardware does not have a facility for notifying the CPU when a value in an input port changes.

Traduc.org a proposé la traduction suivante :
Une méthode alternative : /dev/port

Un autre moyen d'accéder aux ports d'entrées / sorties est d'ouvrir en lecture ou en écriture le périphérique /dev/port (un périphérique en mode caractère, numéro majeur 1, mineur 4) au moyen de la fonction open(). Notons que les fonctions en f*() de la bibliothèque stdio font appel à des tampons mémoires internes, il vaut donc mieux les éviter. Il suffit ensuite, comme dans le cas d'un fichier, de se positionner sur l'octet approprié au moyen de la fonction lseek() (l'octet 0 du fichier équivaut au port 0x00, l'octet 1 au port 0x01, et cætera) et d'en lire (read()) ou écrire (write()) un octet ou un mot.

Il est évident que l'application doit avoir la permission d'accéder au périphérique /dev/port pour que cette méthode fonctionne. Cette façon de faire reste certainement plus lente que la première, mais elle ne nécessite ni optimisation lors de la compilation ni appel à ioperm(). L'accès aux privilèges de super-utilisateur n'est pas impératif non plus, si vous donnez les permissions adéquates à un utilisateur ou un groupe pour accéder à /dev/port (cela reste tout de même une très mauvaise idée du point de vue de la sécurité du système, puisqu'il devient possible de porter atteinte au système, peut-être même d'obtenir le statut de root en utilisant /dev/port pour accéder directement aux disques durs, cartes réseaux, et cætera).

Il n'est pas possible d'utiliser les fonctions select(2) ou poll(2) pour lire /dev/port puisque l'électronique du système n'a pas la possibilité d'avertir le microprocesseur qu'une valeur a changé sur un port d'entrée.

Donc, en tant que super-utilisateur (root), vous pouvez faire ce qui est expliqué ci-dessus : ouvrir /dev/port avec OPEN et lire/écrire à un endroit spécifique.

Exemple

Dim hPort As File
Dim iPortNumber As Integer
Dim iValue as Byte
   
' Envoie  42 au port 1
iPortNumber = 1
iValue = 42
    
hPort = Open "/dev/port" For Read Write
Seek #hPort, iPortNumber
Write #hPort, iValue
    ...

Il y a une autre solution basée sur la bibliothèque C nommée 'parapin'. Vous trouverez plus d'informations sur http://parapin.sourceforge.net/

Voir aussi