-+  Associazione
-+  Documenti
 |-  Modern Perl
 |-  Bibliografia
 |-  Articoli
 |-  Talk
 |-  Perlfunc
 |-  F.A.Q.
 |-  F.A.Q. iclp
-+  Eventi
-+  Community
-+  Blog
-+  Link
Corso di Perl



 


indietro

[10] Come leggo e scrivo su una porta seriale?

Ciò dipende dal sistema operativo su cui sta girando il vostro programma. Nel caso di Unix, le porte seriali saranno accessibili tramite i file in /dev; su altri sistemi, i nomi dei device saranno senz'altro diversi. Di seguito sono descritte molte tipologie di problemi comuni a tutti i tipi di interazione con i device:

  • lockfile

    Il vostro sistema potrebbe utilizzare dei lockfile per controllare gli accessi multipli. Assicuratevi di seguire il protocollo corretto. Se più processi leggono da uno stesso device nello stesso momento, il risultato può essere imprevedibile.

  • modo di open

    Se prevedete di effettuare sia operazioni di lettura che di scrittura sul device, dovrete aprirlo in modalità di aggiornamento (consultate perlfunc/"open" per maggiori dettagli). Potreste volerlo aprire senza incorrere nel rischio di blocco utilizzando sysopen() e O_RDWR|O_NODELAY|O_NOCITY dal modulo Fcntl (incluso nella distribuzione standard di perl). Consultate perlfunc/"sysopen" per maggiori informazioni su questo approccio.

  • fine linea

    Alcuni device si aspetteranno un "\r" alla fine di ciascuna linea al posto di di un "\n". In alcuni port di perl, "\r" e "\n" hanno valori diversi da quelli ASCII (Unix) usuali di "\012" e "\015". È possibile che dobbiate indicare direttamente i valori numerici, utilizzando gli ottali ("\015"), gli esadecimali ("0x0D"), o specificando un carattere di controllo ("\cM").

        print DEV "atv1\012"; # sbagliato, per alcuni device
        print DEV "atv1\015"; # corretto, per alcuni device

    Benché con i file di testo normali un "\n" vada benissimo, non c'è uno schema unificato per la terminazione delle righe che sia portabile tra Unix, DOS/Win, e Macintosh, a meno di non terminare TUTTE le linee con "\015\012", rimuovendo dall'output ciò di cui non avete bisogno. Ciò è valido in particolare per l'I/O da socket e per il flush [completamento delle operazioni di I/O, NdT] automatico, discusso di seguito.

  • flush dell'output

    Se prevedete che i caratteri raggiungano il vostro device quando li stampate con print(), vorrete certamente impostare il flush automatico per tale filehandle. Potete servirvi di select() e della variabile $| per controllare il flush automatico (consultate perlvar/$|) e perlfunc/select, oppure perlfaq5, "Come faccio a terminare le operazioni di I/O in corso o a privare del buffer un filehandle di output? Perché devo fare questo?"):

        $vecchioh = select(DEV);
        $| = 1;
        select($vecchioh);

    Troverete anche codice che fa ciò senza una variabile temporanea, come in

        select((select(DEV), $| = 1)[0]);

    Oppure, se vi va bene importare qualche migliaio di righe di codice solo perché avete paura di una piccola variabile $| :

        use IO::Handle();
        DEV->autoflush();

    Come indicato in precedenza, questo non funziona quando si utilizza un socket di I/O tra Unix e Macintosh. In quel caso dovrete indicare i terminatori di linea direttamente nel codice.

  • input che non blocca

    Se state eseguendo una read() o sysread() che blocca, dovrete fare in modo che un handler di un'allarme indichi un timeout (consultate perlfunc/alarm). Se avete una open che non blocca, probabilmente avrete una read che non blocca, il che significa che potreste dover utilizzare una select() con 4 argomenti per determinare se l'I/O è pronto su quel device (consultate perlfunc/"select").

Mentre tentava di leggere dal suo dispositivo per l'identificativo del chiamante, il famoso Jamie Zawinski <jwz@netscape.com>, dopo aver digrignato un bel po' i denti e combattuto con sysread, sysopen, tcgetattr di POSIX, e varie altre funzioni che si perdono nella notte, alla fine ha ottenuto quanto segue:

    sub apri_modem {
	use IPC::Open2;
	my $stty = `/bin/stty -g`;
	open2( \*MODEM_IN, \*MODEM_OUT, "cu -l$modem_device -s2400 2>&1");
	# l'avvio di cu elimina le impostazioni stty di /dev/tty, anche se
	# e` stato aperto su una pipe...
	system("/bin/stty $stty");
	$_ = <MODEM_IN>;
	chomp;
	if ( !m/^Connected/ ) {
	    print STDERR "$0: cu ha stampato `$_' al posto di `Connected'\n";
	}
    }

vedi in inglese

AUTORE E COPYRIGHT

Copyright (c) 1997, 1998, 1999, 2000, 2001 Tom Christiansen e Nathan Torkington. Tutti i diritti riservati.

Questa documentazione è libera; puoi ridistribuirla e/o modificarla secondo gli stessi termini applicati al Perl.

Indipendentemente dalle modalitè di distribuzione, tutti gli esempi di codice in questo file sono rilasciati al pubblico dominio. Potete, e siete incoraggiati a farlo, utilizzare il presente codice o qualunque forma derivata da esso nei vostri programmi per divertimento o per profitto. Un semplice commento nel codice che dia riconoscimento alle FAQ sarebbe cortese ma non è obbligatorio.

D:
Progetti e documenti in rilievo
Corso di Perl Progetto pod2it
D:
La ML di Perl.it
mongers@perl.it è la lista ufficiale di Perl Mongers Italia per porre quesiti di tipo tecnico, per rimanere aggiornato su meeting, incontri, manifestazioni e novità su Perl.it.
Iscriviti!
D:
Annunci Google