Obligement - L'Amiga au maximum

Vendredi 23 mai 2025 - 15:57  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Gestion d'un périphérique logique
(Article écrit par Iliak et extrait de GuruMed.net - décembre 2002)


Voilà un vaste sujet de discussion et d'étude ! Dans un premier temps, nous allons voir ce qu'est un périphérique logique (alias "device") et ce qu'il apporte au système.

1. Présentation

Un périphérique logique est simplement un programme qui permet de communiquer avec le matériel de l'Amiga. Ainsi, pour jouer un bruit, utiliser la manette, utiliser l'imprimante, le port série, le presse-papiers, et bien d'autres encore, il vous faut passer par les périphériques logiques. Ainsi, chaque périphérique logique gère son propre périphérique. De manière plus pratique, un périphérique logique est un programme à qui on envoie des commandes et des données, qui les interprète en les transmettant au matériel concerné en effectuant une opération d'entrée/sortie (I/O operation). Ce programme tourne de manière autonome par rapport au système. Une fois l'opération effectuée, le périphérique logique vous renvoie les informations que vous avez demandées. Ce système de communication est basé sur le système de messagerie Exec. Ainsi, les périphériques logiques comprennent deux types de commandes, celles de base et celles spécifiques au périphérique logique.

Un "READ" sur le serial.device ou sur le trackdisk.device sera donc compris par ce périphérique logique, mais cela ne veut pas dire que vous allez obtenir le même genre d'information ! En revanche, si vous utilisez une commande "MOTOR" du trackdisk.device sur le serial.device, vous obtiendriez une erreur.

Avant de s'attaquer à l'ouverture même d'un périphérique logique, recensons les principaux périphériques logiques mise à notre disposition par le système :
  • Device Audio - contrôle le son.
  • Device Clipboard - contrôle le presse-papiers.
  • Device Console - contrôle la sortie de texte.
  • Device Gameport - contrôle la souris et la manette.
  • Device Input - "Super" périphérique logique qui gère le gameport.device et le keyboard.device.
  • Device Keyboard - contrôle le clavier.
  • Device Narrator - contrôle la synthèse vocale.
  • Device Parallel - contrôle le port parallèle.
  • Device Printer - contrôle l'imprimante.
  • Device SCSI - contrôle le matériel "Small Computer Standard Interface".
  • Device Serial - contrôle le port série.
  • Device Timer - contrôle du temps.
  • Device Trackdisk - contrôle du lecteur de disquette.
Voici donc les principaux périphériques logiques du système. En fonction de votre système et de votre matériel, d'autres fichiers se nommant ".device" sont dans votre répertoire "Devs:". En effet, ceux-ci gèrent un matériel spécifique. Ainsi, "ahi.device" permet de mieux gérer le son, "x-surf.device" dans "Devs:Networks" permet de gérer la carte réseaux X-Surf, etc.

1.1 Device Audio

L'Amiga est équipé de quatre canaux audio, deux canaux à droite et deux canaux à gauche. Au total, et si cela est bien géré, il possède donc deux sorties stéréo. Étant donné l'architecture multitâche du système, il faut obéir à certaines règles pour que tous les programmes cohabitent bien. C'est ainsi que l'audio.device gère l'accès et régularise les demandes.

1.1.1 La définition des commandes de base :
  • ADCMD_ALLOCATE : alloue un ou plusieurs canaux.
  • ADCMD_FINISH : annule la requête CMD_WRITE actuelle.
  • ADCMD_FREE : libère un ou plusieurs canaux.
  • ADCMD_LOCK : bloque un ou plusieurs canaux.
  • ADCMD_PERVOL : change la période et le volume.
  • ADCMD_SETPREC : change la priorité d'un son.
  • ADCMD_WAITCYCLE : attend la fin d'une commande CMD_WRITE.
  • CMD_FLUSH : purge la mémoire.
  • CMD_READ : pointeur vers la structure d'entrée/sortie qui écrit actuellement.
  • CMD_RESET : réinitialise un ou plusieurs canaux à leur état initial.
  • CMD_START : (re)lance une commande CMD_WRITE.
  • CMD_STOP : arrête le son.
  • CMD_WRITE : écrit un son.
ADCMD_ALLOCATE : cette commande permet d'allouer un ou plusieurs canaux audio. Il faut définir le champ ioa_Data de la structure IOAudio avec les canaux voulus.

Canal 3 (droite) Canal 2 (gauche) Canal 1 (droite) Canal 0 (gauche) Valeur décimale
0 0 0 0 0
0 0 0 1 1
0 0 1 0 2
0 0 1 1 3
0 1 0 0 4
0 1 0 1 5
0 1 1 0 6
0 1 1 1 7
1 0 0 0 8
1 0 0 1 9
1 0 1 0 10
1 0 1 1 11
1 1 0 0 12
1 1 0 1 13
1 1 1 0 14
1 1 1 1 15

Ainsi, si vous voulez réserver un mode stéréo, passez la valeur 3, 5, 10 ou 12.

1.2 Device narrator (par Victorien Ferry)

Le narrator.device est un programme de génération de synthèse vocale intégré dans le système de l'Amiga. La synthèse vocale est l'art très difficile de reproduire une voix compréhensible, phonème par phonème en générant des sons similaires.

Ces fonctions ont été présentes jusqu'à la version 2.04 d'AmigaOS (Translator version 37.1, 1991) et a disparu avec les premières versions 3.x (A1200, A4000 de 1992) pour des raisons contractuelles, car il était sous-traité par la société SoftVoice (qui a réalisé des variantes pour C64 et Mac dans les années 1980).

Cependant, quiconque possède les dernières versions peut réinstaller tout cela sur des versions plus récentes du système d'exploitation comme la version 3.9. Cela fonctionne toujours. Ce n'est pas étonnant, car l'implémentation de cette fonctionnalité dans AmigaOS est particulièrement réussie, et tient dans ces trois fichiers :
  • devs:narrator.device. Le narrator.device gère une pile de phrases à prononcer. On lui rajoute des phrases en entrée dans le périphérique logique où on lui spécifie la fréquence (note) de la voix, les canaux audio à allouer, des options d'informations à renvoyer en retour, et bien sûr la phrase elle-même, qui est une chaîne ASCII classique terminée par un zéro mais... écrite en ARPABet. L'ARPABet est une version ASCII de l'écriture phonétique utilisée par les linguistes. Cette abstraction phonétique fait la force de ce périphérique logique car elle lui permet potentiellement de prononcer tous les accents !
  • libs:translator.library. La translator.library ne fournit qu'une fonction, qui traduit une phrase écrite en anglais vers sa traduction en ARPABet. Sa facilité d'utilisation contraste avec sa puissance. En effet, 700 règles de traductions sont utilisées pour permettre une lecture correcte des mots anglais, mais aussi des signes. "9" est traduit par "nine" en phonétique, et l'intonation de la phrase est aussi traduite en ARPABet. A noter qu'il existe sur Aminet des versions de substitution permettant d'autres accents par un outil de préférence.
  • c:say. Cette commande DOS permet juste la prononciation d'une phrase en anglais :

    say "I am a good little doggy"
    

    Son code est très minimal puisqu'elle contient juste un appel à la translator.library puis au narrator.device.
1.2.1 Les trésors cachés

Il est possible, par option lors de la construction du message d'entrée/sortie vers le périphérique logique, de demander le retour d'informations en temps réel sur la phrase en train d'être prononcée (le narrator.device s'utilise en asynchrone). Ainsi, on peut connaître la largeur et la hauteur de la bouche virtuelle qui prononce la phrase, et rediriger cette information vers le visage d'un personnage animé par exemple. On peut également demander des évènements chaque fois qu'un mot commence à être prononcé.

1.2.2 Bon d'accord mais comment on programme ça ?

Il existe dans le CD Amiga Developer 2.1 un exemple particulièrement intéressant puisqu'un ".c" contient des fonctions init et close génériques pour utiliser le narrator.device et la translator.library. Inclure ce ".c" à votre projet est une bonne idée pour une intégration rapide.

1.3 Device trackdisk

Ce périphérique logique permet de gérer de manière très précise les lecteurs de disquette.

1.3.1 Présentation

Le trackdisk.device gère directement les lecteurs de disquette (quatre au maximum sur Amiga : Df0:, Df1:, Df2:, Df3:). En temps normal, vous n'avez pas besoin d'y accéder si vous voulez écrire ou lire des données car ce périphérique logique est dit de "bas niveau". En effet, le système accède à celui-ci directement et par aucun autre moyen. En plus des commandes classiques des périphériques logiques, celui-ci en possède deux privées :
  • TD_GETGEOMETRY : obtient des informations sur le disque.
  • TD_EJECT : éjecte le disque.
La disquette standard pour l'Amiga est la disquette 3,5 pouces. Elle est formée de 80 cylindres qui contiennent chacun deux têtes. Sur une tête est lue une piste. Une piste comprend 11 (NUMSECS) secteurs de 512 (TD_SECTOR) octets plus 16 (TD_LABELSIZE) octets d'en-tête. Le nombre de pistes est obtenue en utilisant la commande "TD_GETNUMTRACKS". Attention, le nombre de secteurs (NUMSECS) peut changer d'une disquette à l'autre !

Il faut utiliser "TD_GETGEOMETRY" pour déterminer le nombre de secteurs (le résultat retourné est le nombre de pistes et non le nombre de cylindres).

1.3.2 Les commandes

Voici la liste des commandes reconnues par ce périphérique logique :
  • CMD_CLEAR : marque la piste invalide et force la piste à être relue.
  • ETD_CLEAR : vérifie l'insertion d'une nouvelle disquette.
  • CMD_READ : lit un ou plusieurs secteur(s) d'une disquette.
  • ETD_READ : lit l'en-tête de secteur et vérifie l'insertion d'une nouvelle disquette.
  • CMD_UPDATE : vide le tampon mémoire et écrit la piste si nécessaire.
  • ETD_UPDATE : vérifie l'insertion d'une nouvelle disquette.
  • CMD_WRITE : écrit une ou plusieurs piste(s).
  • ETD_WRITE : écrit l'en-tête de secteur et vérifie l'insertion d'une nouvelle disquette.
  • TD_ADDCHANGEINT : ajoute une interruption à chaque insertion de disquette.
  • TD_CHANGENUM : retourne le nombre d'insertions de disquette utilisé par les commandes "ETD_".
  • TD_CHANGESTATE : indique si une disquette est présente ou non.
  • TD_EJECT : éjecte la disquette.
  • TD_FORMAT : formate une piste avec les données fournies.
  • ETD_FORMAT : initialise aussi le "sector label area".
  • TD_GETDRIVETYPE : retourne le type de disquette dans le lecteur.
  • TD_GETGEOMETRY : retourne la table de géométrie de la disquette.
  • TD_GETNUMTRACKS : retourne le nombre de pistes utilisables sur la disquette.
  • TD_MOTOR : allume ou éteint le moteur du lecteur.
  • ETD_MOTOR : vérifie l'insertion d'une nouvelle disquette.
  • TD_PROSTATUS : indique si la disquette est protégée ou non.
  • TD_RAWREAD : lit une piste de données brutes.
  • ETD_RAWREAD : vérifie l'insertion d'une nouvelle disquette.
  • TD_REMCHANGEINT : enlève une interruption précédemment installée.
  • TD_SEEK : bouge la tête de lecture à une position spécifique.
  • ETD_SEEK : vérifie l'insertion d'une nouvelle disquette.
Ce périphérique logique utilise deux types de requêtes d'entrée/sortie, "IOStdReg" et "IOExtTD" et deux types de commandes, les standards et les étendues. Une structure étendue est nécessaire pour l'utilisation des requêtes étendues (celles commençant par "ETD_"), mais celles-ci peuvent toutefois être utilisées pour les requêtes standard. Ainsi, il est recommandé de n'utiliser que des structures "IOExtTD" pour la gestion du trackdisk.device. Voici les structures IOStdReg() et IOExtTD() :

struct IOStdReq
{
	struct	Message io_Message;
	struct	Device *io_Device;	/* Pointeur vers le périphérique logique */
	struct	Unit *io_Unit;		/* Unité (spécifique au périphérique logique)*/
	UWORD	io_Command;		/* Commande du périphérique logique */
	UBYTE	io_Flags;
	BYTE	io_Error;		/* Numéro de l'erreur */
	ULONG	io_Actual;		/* Nombre d'octets actuellement transféré */
	ULONG	io_Length;		/* Nombre d'octets demandé */
	APTR	io_Data;		/* Pointeur vers la zone mémoire */
	ULONG	io_Offset;		/* Décalage */
};

struct IOExtTD
{
	struct	IOStdReq iotd_Req;	/* Structure standard */
	ULONG	iotd_Count;		/* Nombre de changements de disquette */
	ULONG	iotd_SecLabel;		/* En-tête de secteur */
};

2. Ouverture d'un périphérique logique

Pour communiquer avec un périphérique logique, vous devez, dans un premier temps, pourvoir votre programme d'un port de communication. Grâce à celui-ci, le système peut envoyer et recevoir des informations. Une fois cela fait, vous devez initialiser un bloc de mémoire qui servira de "navette" entre votre programme et le périphérique logique. C'est dans ce bloc que vous mettrez toutes les informations nécessaires pour que le périphérique logique vous comprenne. En retour, cette mémoire sera remplie des informations que vous avez demandées. La dernière étape est d'ouvrir le fameux périphérique logique. Une fois le travail fini, vous devez tout refermer afin de ne pas perdre les blocs mémoire utilisés. Attention, vous devez libérer une à une les allocations dans l'ordre inverse de leur ouverture. Pour plus de détails, reportez-vous plus bas.

Pour établir le port de communication, vous avez besoin de la commande "CreateMsgPort()" qui va ouvrir un port de communication ou de message (MsgPort) dans votre programme en initialisant la structure suivante :

struct MsgPort
{
	struct	Node mp_Node;
	UBYTE	mp_Flags;
	UBYTE	mp_SigBit;
	void	*mp_SigTask;
	struct	List mp_MsgList;
};

Après, vous devez créer une structure IORequest. Cela peut être fait de différentes manières, mais la plus simple est celle de laisser au système le soin de s'en occuper. Pour cela, on fait appel à la fonction "CreateIORequest()". La structure suivante sera initialisée :

struct IORequest
{
	struct	Message	io_Message;
	struct	Device	*io_Device;	/* Pointeur vers le périphérique logique */
	struct	Unit	*io_Unit;	/* Unité                    */
	UWORD	io_Command;		/* Commande à effectuer     */
	UBYTE	io_Flags;
	BYTE	io_Error;		/* Erreur                   */
};

Une fois cela fait, on ouvre le périphérique logique avec un "OpenDevice()". Nous avons dit plus haut que l'utilisation des périphériques logiques se fait de manière générique, c'est-à-dire qu'une instruction est comprise par de multiples périphériques logiques. En revanche, l'ouverture d'un périphérique logique est spécifique à lui-même, ainsi, on ne va pas ouvrir le trackdisk.device de la même manière que l'input.device. Voici une explication de l'ouverture d'un périphérique logique.

Erreur = OpenDevice(Nom, Unité, RequêteIO, Drapeaux)
  • Nom : nom du périphérique logique. Voir les chapitres 1.x ci-dessus pour les périphériques logiques classiques.
  • Unité : par défaut 0. Cela est vraiment spécifique au périphérique logique. Ainsi, pour le trackdisk.device, ce chiffre correspondra au numéro du lecteur de disquette. Pour le timer.device, cinq unités sont disponibles ! Renseignez-vous bien sur le périphérique logique avant d'utiliser l'unité.
  • RequêteIO : structure IORequest obtenue via "CreatIORequest()". Attention, là aussi, certains périphériques logiques nécessitent des structures IORequest spécifique, tel que l'audio.device.
  • Drapeaux : valeur à passer à certains périphériques logiques qui le gèrent. Par défaut NULL.
  • Erreur : code de retour. Attention, l'ouverture d'un périphérique logique réussi se matérialise toujours par un retour d'erreur NULL !
Maintenant que nous savons ouvrir un périphérique logique, il serait intéressant de savoir le refermer. Tout d'abord, il faut savoir que cela va toujours de pair par rapport à l'ouverture. Ainsi, on ferme en premier ce que l'on a ouvert en dernier. En effet, si l'on ferme d'abord le port de communication (MsgPort) et ensuite la structure de requête (IORequest), attendez-vous à avoir de la mémoire perdue ou au pire à planter le système. Dans un premier temps, on ferme le périphérique logique avec "CloseDevice()". Cela fait, on libère la structure IORequest avec un "DeleteIORequest()" et en dernier lieu, on fait un "DeleteMsgPort()".

3. Utilisation d'un périphérique logique

Une fois tout initialisé, il ne reste plus qu'à communiquer. Il existe deux modes de communication :
  • Le mode synchrone : vous envoyez une commande et le périphérique logique ne vous rend la main que lorsque votre ordre est terminé. La fonction est "DoIO()".
  • Le mode asynchrone : vous envoyez une commande, le périphérique logique vous rend la main de suite et c'est à la charge du programme de revenir chercher la réponse. Ici, il cohabite deux fonctions "SendIO()" et "BeginIO()".
Voici une description de ces trois commandes :
  • DoIO() : méthode la plus simple. Vous envoyez une commande, le périphérique logique ne vous rend la main que lorsque la fonction est terminée.
  • SendIO() : vous retrouvez de suite la main. En contre-partie, vous devez revenir chercher la réponse à la commande. De plus, l'action peut s'effectuer bien plus tard par rapport à l'envoi de l'ordre. Certains périphériques logiques ne gèrent pas cette commande et ne vous rendent la main que lorsque l'action est terminée.
  • BeginIO() : cette fonction est un peu spéciale. En effet, elle permet, si le drapeau "IOF_QUICK" est défini dans le champ "io_Flags" de la requête, de "sauter" des étapes. Cette fonction est équivalente à "SendIO()" sauf que le champs "io_Flags" n'est pas vide. A réserver aux connaisseurs des périphériques logiques !
Nous vous recommandons d'utiliser seulement les deux premières fonctions. Pour de plus amples informations à propos de quelle fonction choisir, reportez-vous au chapitre 4 suivant.

Maintenant que nous connaissons les commandes à utiliser pour communiquer, il nous faut connaître quoi remplir dans la structure "IOStdReq". Voici à quoi elle ressemble :

struct IOStdReq
{
	...
	struct	Device	*io_Device;	/* Pointeur vers le périphérique logique */
	struct	Unit	*io_Unit;	/* Unité                                 */
	UWORD	io_Command;		/* Commande                              */
	UBYTE	io_Flags;		/* IOF_QUICK ou non                      */
	BYTE	io_Error;		/* Erreur                                */
	ULONG	io_Actual;		/* Nombre d'octets transféré              */
	ULONG	io_Length;		/* Nombre d'octets à transférer           */
	APTR	io_Data;		/* Pointeur vers la zone mémoire         */
	...
};

Il faut remplir le champ "io_Command" avec la commande à effectuer, "io_Lenght" avec la longueur total du nombre d'octets à transférer, "io_Data" avec le pointeur vers la zone mémoire ou commencent les données. Voici la liste des commandes Exec par défaut :
  • CMD_CLEAR : purge le tampon mémoire du périphérique logique.
  • CMD_READ : commande de lecture.
  • CMD_STOP : arrête l'activité du périphérique logique.
  • CMD_FLUSH : vide la file d'attente des commandes.
  • CMD_RESET : réinitialise un périphérique logique.
  • CMD_WRITE : commande de lecture.
  • CMD_INVALID : crée une erreur.
  • CMD_UPDATE : met à jour le périphérique logique.
  • CMD_START : redémarre le périphérique logique.
Reportez-vous quand même à la documentation du périphérique logique avant de les utiliser !

4. Synchrone ou asynchrone ?

Pourquoi existe-t-il des commandes synchrones (qui ne vous rendent la main que lorsque la commande est terminée) et des commandes asynchrones (qui rendent la main de suite) ? Voici un petit tableau récapitulant les avantages et les inconvénients des deux fonctions :

  Avantages Inconvénients
DoIO() Pas de vérification nécessaire Pas de retour immédiat
SendIO() Retour immédiat Vérification nécessaire du retour de la commande
  On peut envoyer d'autres commandes, même si on a pas reçu de message de retour (*) On ne peut pas toucher aux données utilisées par le device tant que l'on a pas de message de retour

(la commande BeginIO() est explicitement ignorée)

Comme vous pouvez le voir, les deux fonctions se valent. En fait, tout dépend du type d'application que vous créez.

(*) Si vous voulez envoyer plusieurs requêtes au même périphérique logique avec la commande "SendIO()", vous devez mettre en place une certaine technique. En effet, si vous n'avez toujours pas reçu de message de retour de votre précédente commande et que vous devez réutiliser ce périphérique logique, vous devez alors créer une deuxième structure "IORequest" et y recopier la première structure dedans. Ainsi, vous pourrez envoyer plusieurs commandes en même temps au même périphérique logique.

Afin de savoir quand un retour de commande est arrivé, le système nous donne deux méthodes. La première met la tâche en attente jusqu'à ce que le périphérique logique réponde. Pour cela, nous pouvons utiliser "WaitIO()", "Wait()" ou "WaitPort()". Étant donné que la tâche attend un retour du périphérique logique, il est préférable d'utiliser l'autre méthode. La seconde méthode utilise la fonction "CheckIO()". Celle-ci regarde juste si, par rapport à une requête, la réponse est arrivée et n'attend pas. Dans tous les cas, vous devrez manuellement enlever la requête de réponse de la file d'attente du port de communication.

Maintenant que nous avons une réponse du périphérique logique, il faut l'analyser. Dans un premier temps, il faut vérifier que l'opération s'est bien déroulée en regardant le code d'erreur (io_error). Une valeur NULL indique un succès, en revanche une autre valeur signifie qu'une erreur est survenue durant l'exécution de la commande. Il existe deux types d'erreur, les erreurs d'entrée/sortie d'Exec et les erreurs spécifiques au périphérique logique (voir la documentation du périphérique logique).

En cas d'erreur (et selon le type d'application), vous pouvez renvoyer votre commande, car à un moment donné, il se peut très bien que la commande échoue et la tentative suivante s'avère fructueuse (exemple : l'allocation de canaux audio). Il peut s'avérer que vous désiriez quitter et annuler toutes les communications avec le périphérique logique. Il ne faut surtout pas fermer le périphérique logique tant que vous n'avez pas eu un message de retour de toutes vos commandes. Pour annuler une commande, utilisez la fonction "AbortIO()". Cette fonction n'est pas gérée par tous les périphériques logiques, donc veuillez bien lire la documentation du périphérique logique. Avec cette fonction, vous n'avez qu'annulé la commande elle-même, il vous reste donc à libérer tout ce qui a été alloué.

Pour vous aider, voici un petit pense-bête de ce qu'il faut faire pour quitter un programme qui utilise un périphérique logique :
  • Annuler toutes les commandes en cours avec un AbortIO().
  • Attendre le retour des commandes avec un WaitIO() (ou un autre précédemment vu).
  • Fermer le périphérique logique avec un CloseDevice().
  • Libérer la structure IORequest (ou IOStdReq) avec un DeleteIORequest().
  • Effacer le port de communication avec un DeleteMsgPort().
5. Exemple

Maintenant, voici un petit programme qui ouvre le serial.device (port série) et demande le statut du port et affiche le résultat (NDLR : attention, il manque sans doute les "#include").

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/io.h>
#include <devices/serial.h>

#include <stdio.h>

int main(void)
{
	struct MsgPort	*SerialMP;	/* Pointeur vers notre "Message Port" */
	struct IOExtSer	*SerialIO;	/* Pointeur vers notre "I/O Request"  */

	/* Crée port de communication  */
	if (SerialMP=CreateMsgPort())	
	{
		/* Crée la requête d'E/S */
		if (SerialIO = CreateIORequest(SerialMP,sizeof(struct IOExtSer)))
		{
			/* Ouvre le serial.device */
			if (OpenDevice(SERIALNAME,0,(struct IORequest *)SerialIO,0L))
				printf("Erreur: %s n'a pu être ouvert !\n",SERIALNAME);
			else
			{
				/* On envoie une commande */
				SerialIO->IOSer.io_Command  = SDCMD_QUERY;
				if (DoIO((struct IORequest *)SerialIO))
				{
					/* La commande a raté */
					printf("Query échoué. Erreur - %d\n",SerialIO->IOSer.io_Error);
				}
				else
				{
					/* On affiche le résultat */
					printf("Statut du serial.device : %x\n\n",SerialIO->io_Status);
				}

				/* On ferme le serial.device */
				CloseDevice((struct IORequest *)SerialIO);
			}
			/* On efface la requête d'E/S */
			DeleteIORequest(SerialIO);
		}
		else
			/* On a échoué */
			printf("Erreur: Ne peut pas créer la requête d'E/SE !\n");

		/* On efface le port de communication */
		DeleteMsgPort(SerialMP);
	}
	else
		/* Pas de port de communication */
		printf("Erreur: Ne peut pas créer le port de communication !\n");

	return(0);
}



[Retour en haut] / [Retour aux articles]