Newsgroup: it.comp.lang.c
Titolo: Accesso alla porta seriale

Salve,
avrei necessita' di leggere e scrivere dati dalla porta seriale. Dove
posso trovare esempi di codice C per ambiente Dos/Unix o tutorial, che
possano darmi l'input per risolvere questo problema?
Grazie.

...

Dipende molto dall'ambiente, ma in generale vi si accede con le normali
funzioni di I/O (open()/read()/write()/close()/ioctrl()) utilizzando un
nome file opportuno.
Unix:
Le porte seriali vengono gestite con l'I/O standard. Vedi 'man termio' per
l'impostazione del protocollo. Il nome del device puo' cambiare da sistema
a sistema (/dev/ttya su SUN OS 4: int comm=open("/dev/ttya"))
Win95 (VC++ 5.0):
Come in Unix, vi si accede piu' o memo con le stesse funzioni di accesso ai
file: CreateFile(). Con lineGetId() lineSet/GetDevConfig(). Non ho mai
provato ad usarle. C'e un progetto di esempio (fornisce una classe
CSerialPort) su C++Warriors:
http://www.geocities.com/SiliconValley/Foothills/6336
 pagina
Download/Commtest.zip
DOS:
Puoi usarle tramite la stdlib con open(), ecc., specificando un mome di
file particolare che contiene anche il protocollo (velocita', ecc.) ma non
mi ricordo il formato e mi sembra che siano limitate a 9600 baud dal BIOS.
Io uso una libreria free per il DJGPP che accede direttamente al device
(inport, outport): DZCOMM - Non riesco piu' a trovare il link dovrebbe
essere rintracciabile da qualche parte su 
http://www.delorie.com/djgpp

a sistema (/dev/ttya su SUN OS 4: int comm=open("/dev/ttya"))
Ti ringrazio per le informazioni.
A me interesserebbe accedere alla seriale in ambiente Unix. Ho letto
sul manuale la documentazione sulla funzione termio(). In pratica si
tratta di copiare i dati della porta in una struttura di tipo
'termio', modificarli e quindi settare la porta tramite la funzione
ioctl(). Ho pero' delle difficolta' perche' i parametri sono 'troppi'
per cui se qualcuno fosse in grado di indicarmi un esempio di
utilizzo, sarebbe per me un vero aiuto.
Grazie.

 
Non ho esempi a disposizione, ma, per impostare una gestione grezza (senza
nessun pre/post processing automatico) devi procedere come segue:
1. apri la seriale
2. richiedi l'uso esclusivo (man 'flock'), da rimuovere al termine del
programma
3. salva lo stato attuale, da ripristinare al termine (intercetta i vari
signal in modo da poter ripristinare sempre lo stato della seriale)
3. Imposta i seguenti parametri:
struct termios {
  c_iflag = IGNBRK | // ignora i break
            INPCK;   // abilita check di parita'
  c_oflag = 0;		// nessu processing in output
  c_cflag = B38400 |		// Baud rate a piacere (tx speed = rx speed)
            CS8    |		// 8 bit di dati
            CREAD  |		// Abilita lettura
            PARENB |		// Abilita parita' (even)
            CLOCAL;		// local line (niente modem)
  c_lflag = 0;			// Disabilita tutti i preprocessing (non canonical input)
  c_line  = 0;                // niente modem
  c_cc[]  =
    [VINTR..VLXLEN]=0;		// Ignora tutti i caratteri di controllo
    [VMIN] = X;			// numero minimo di caratteri da leggere
    [VTIME]= Y;			// Time out in lettura
 
}
VMIN e VTIME sono i parametri per gestire l'input: usa la combinazione
giusta per la tua applicazione (modificando questi parametri cambi solo la
modalita' con cui i dati vengono passati alla tua applicazione: Unix
bufferizza comunque l'input).
Se vuoi leggere un carattere alla volta:
VMIN = 1, VTIME=0;		// Bloccante!
VMIN = 1, VTIME=x;		// con timeout= x*0.1 sec
Se non vuoi fermarti:
VMIN=0, VTIME=0;
Fai atenzione alla scelta di VMIN,VTIME perche potressi generare un busy
wait occupando tutto il tempo macchina:
VMIN=0, VTIME=0
while((n=fread(fd, buffer, sizeof(buffer)<=0)); // dusy wait, cpu usage =
100%!!!!


Grazie molte per le informazioni. Provo a seguire i tuoi consigli e
poi ti faccio sapere l'esito.
Saluti,
Michele