PDA

Visualizza la versione completa : [C] Comunicazione seriale con uso di thread


UltraBeginner
25-05-2007, 16:02
Ciao a tutti,

sto riprendendo in mano l'applicazone, di cui gi scrissi tempo fa, che permette la comunicazione con la porta seriale.

Ora sto cercando di implementare un applicazione asincrona (overlapped), ovvero vorrei che leggesse dalla seriale solo quando arriva un carattere nel buffer della USART. Ho scritto il codice che riesce a soddisfare questo obiettivo, premetto che la prima volta che sbatto la testa con le strutture Overlapped.


while(1)
{
if ( !WaitCommEvent(Porta_Seriale, &buffer, &OverlapStruct))
{
if(GetLastError()== ERROR_IO_PENDING);
printf("I/O pending...");

}
if(WaitForSingleObject(OverlapStruct.hEvent,INFINI TE)==WAIT_OBJECT_0)
{
do
{
ReadFile( Porta_Seriale,&car,sizeof(car),&BytesRead,&OverlapStruct);
printf("%c",car);
Sleep(2);
}while (BytesRead > 0 );
}

ResetEvent(OverlapStruct.hEvent);

}



Il codice stato testato inviando dei dati da microcontrollore ed effettivamente, ogni volta che il micro trasmetteva, il programma stampava a video la stringa corretta.
Il mio problema nasce dal fatto che io vorrei anche scrivere sulla seriale, ma non saprei come fare. Devo forse creare un thread che si occupi dell'ascolto della porta, mentre il programma principale si occupa dell invio dei dati sulla stessa porta? Ci pu essere una soluzione alternativa all uso dei thread (argomento per ora da me mai trattato)?.
Qualcuno saprebbe darmi una traccia del percorso da seguire?

Grazie a tutti per l attenzione.

Saluti!



:ciauz: :ciauz:

billiejoex
26-05-2007, 13:12
Il mio problema nasce dal fatto che io vorrei anche scrivere sulla seriale, ma non saprei come fare.

Potresti creare una variabile "coda", inizialmente vuota, che controlli ad ogni ciclo compiuto dal while. Se la coda vuota continui come se nulla fosse, altrimenti prendi i dati in essa contenuti e li mandi. Lo stesso principio spesso applicato nei frameworks asincroni basati su select / poll / epoll ecc...

UltraBeginner
26-05-2007, 13:24
Originariamente inviato da billiejoex
Potresti creare una variabile "coda", inizialmente vuota, che controlli ad ogni ciclo compiuto dal while. Se la coda vuota continui come se nulla fosse, altrimenti prendi i dati in essa contenuti e li mandi. Lo stesso principio spesso applicato nei frameworks asincroni basati su select / poll / epoll ecc...

bella billie, ho implementato una cosa simile, solo che era ieri alle 1730 l ho provata e funzionnicchia. Al posto di aspettare INFINITE ho imposto un tempo di attesa di 3 secondi. In pratica vado a campionare la porta appunto ogni tre secondi per vedere se qualche carattere e arrivato. In ogni caso grazie per la rispo, aggiungo pero un altra domanda:

secondo te/voi, sarebbe possibile avere un programma con questa struttura

// Thread principale

// Thread Ascolto

Con il Thread Ascolto sempre in ascolto sulla seriale, ovvero

WaitForSingleObject(OverlapStruct.hEvent,INFINITE) ==WAIT_OBJECT_0)

Il mio dubbio e che, impostando infinito, il programma stia sempre nel thread Ascolto. Ci sarebbe un modo per far si che il Thread principale vada a campionare periodicamente il thread Ascolto?

Mi scuso per la spiegazione contorta, ovviamente resto a disposizione per chiarire il piu possibile!!



:ciauz: :ciauz:

billiejoex
26-05-2007, 13:34
bella billie, ho implementato una cosa simile, solo che era ieri alle 1730 l ho provata e funzionnicchia. Al posto di aspettare INFINITE ho imposto un tempo di attesa di 3 secondi. In pratica vado a campionare la porta appunto ogni tre secondi per vedere se qualche carattere e arrivato.
Tantissimo. Puoi tranquillamente mettere un timeout di molto inferiore (es: 0.01 secondi) senza che la CPU saturi.


secondo te/voi, sarebbe possibile avere un programma con questa struttura

// Thread principale

// Thread Ascolto

Con il Thread Ascolto sempre in ascolto sulla seriale, ovvero

WaitForSingleObject(OverlapStruct.hEvent,INFINITE) ==WAIT_OBJECT_0)

Il mio dubbio e che, impostando infinito, il programma stia sempre nel thread Ascolto. Ci sarebbe un modo per far si che il Thread principale vada a campionare periodicamente il thread Ascolto?

Non ho ben capito la tua domanda ma personalmente preferisco sempre l'approccio asincrono ai thread.
Nel tuo caso, oltretutto, l'utilizzo dei thread non mi sembra neanche giustificato dato che la seriale una soltanto. Puoi tranquillamente gestire il tutto all'interno del ciclo while dal quale, eventualmente, richiamare le funzioni del caso quando arrivano dati o accadono altri tipi di eventi.

UltraBeginner
26-05-2007, 13:36
Originariamente inviato da billiejoex
Tantissimo. Puoi tranquillamente mettere un timeout di molto inferiore (es: 0.01 secondi) senza che la CPU saturi.



Personalmente preferisco sempre l'approccio asincrono ai thread.
Nel tuo caso, oltretutto, l'utilizzo dei thread non mi sembra neanche giustificato dato che la seriale una soltanto. Puoi tranquillamente gestire il tutto all'interno del ciclo while dal quale, eventualmente, richiamare le funzioni del caso quando arrivano dati o accadono altri tipi di eventi.

Grazie billie! Allora seguir il tuo consiglio :) Magari lunedi ti posto il mio codice via messaggio privato e se hai tempo, ma sopratutto voglia :), puoi darci un occhiata perche come ti dicevo ho usato questo approccio ma funzionicchia (traquillo sono poche righe :D )

In ogni caso grazie mille per avermi tracciato il percorso!!! :)

Buon Week End e grazie ancora!! :ciauz: :ciauz:

billiejoex
26-05-2007, 13:37
Prego (non che abbia fatto poi molto). :)

Saluti

Loading