|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
|
[C++] un timer con ciclo while per lettura su porta seriale in linux
Salve a tutti...
sto impazzendo per fare una lettura sulla porta seriale vincolata ad un timer con un ciclo while. Il codice che ho usato è: Codice:
int Timeout = 3;
long endValue = clock()+CLOCKS_PER_SEC* Timeout;
//primo tentativo di lettura
int i = PollComport(Pnum,buffer);
//se non ha letto niente (i==0)
while (clock()<endValue || i>0){
i = PollComport(Pnum,buffer);
sleep(1);
}
Pertanto a me serve che questo ciclo finisca o perchè ha letto (quindi i è diventata diversa da zero) o perchè è finito il tempo di attesa, impostato a priori cioè 3 secondi. Perchè non funziona? Rimane bloccato.... Aiutatemi a capire il problema dove sta. Grazie anticipatamente a tutti quelli che mi risponderanno...
__________________
Come la chiami la chiami, la cocozza sempre cocozza è. |
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Jul 2005
Città: Vicenza
Messaggi: 1570
|
Quote:
|
|
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
|
Quote:
http://www.teuniz.net/RS-232/ tra le varie cose dice appunto di collegarla ad un timer...
__________________
Come la chiami la chiami, la cocozza sempre cocozza è. |
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jan 2007
Messaggi: 6192
|
Il problema è che per valutare il tempo trascorso stai usando clock().
http://linux.die.net/man/3/clock clock() restituisce il tempo di cpu usato dal programma, non il tempo "assoluto" che è trascorso. In pratica ti dice per quanto tempo il tuo programma ha usato cicli di clock della cpu ma nel frattempo la cpu potrebbe essere stata usata per eseguire altra roba (e quel tempo non viene messo in conto). Questa funzione è molto utile per misurare con buona approssimazione le prestazioni di un programma anche se c'è altra roba in esecuzione, ma è disastrosa in loop che attendono andando in sleep (smettendo di consumare tempo di cpu durante il "sonno"). Il tuo loop fa un check sulle condizioni di uscita (roba che richiede nanosecondi di tempo di cpu usato dal programma) prova a leggere dalla seriale (roba da microsecondi di tempo di cpu usato dal programma, visto che non resta in attesa continuando a rileggere) e poi va in sleep per 1 secondo di tempo reale (anche questo richiede microsecondi di tempo di cpu usato dal programma, perchè mentre il tuo programma è in attesa non "consuma" tempo sulla cpu). In pratica ad ogni ciclo si attende circa 1 secondo di tempo "assoluto", ma il tempo effettivamente speso ad eseguire istruzioni sulla cpu (quello misurato con clock() ) è tanto se è 10 microsecondi per ciclo. Significa che per "consumare" i 3 secondi di "tempo di cpu speso ad eseguire istruzioni del tuo programma" potrebbero servire tranquillamente 300000 secondi e passa di tempo "assoluto" (qualche giorno Semmai al posto di clock() usa clock_gettime() e le altre funzioni collegate ad essa: http://linux.die.net/man/2/clock_gettime Che invece restituisce il tempo "reale" trascorso. Ricordati anche di gestire il wrap-around del clock altrimenti ti causerà un altra situazione disastrosa di "attesa per giorni" quando "conteggio_timer_iniziale"+"intervallo di attesa" supera il valore massimo di conteggio del tempo restituito dalla funzione. |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
|
ma non c'è un modo alternativo per avere una gestione del genere? insomma, un timeout di 3 secondi massimo per una lettura?
La libreria che uso è quella che ho indicato...e dice che per la lettura conviene legarla ad un timer...ora, come lo faccio un timer del genere? Alla fine quello che mi serve che faccia è semplice, relativamente poco complicato credo rispetto a cicli molto più complessi... cosa posso usare invece di un while?
__________________
Come la chiami la chiami, la cocozza sempre cocozza è. |
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Jan 2007
Messaggi: 6192
|
Quote:
Codice:
int k;
.....
k= 3; // attendi per massimo tre volte
while (k>0 || i>0){
i = PollComport(Pnum,buffer);
sleep(1); // vai in sleep per circa 1 secondo
if (k>0) --k; // decrementa conteggio attesa
}
Ad esempio di solito quando si leggono dati dalla seriale, subito dopo PollComport() si dovrebbe verificare se sono arrivati tutti i dati ed uscire subito dal ciclo invece di attendere lo scadere del timeout. Anche a 9600 bit/s in un secondo fai in tempo ad esmepio a trasmettere circa 480 byte e riceverne di risposta 480 (ipotizzando una comunicazione master-slave). Quindi sarebbe conveniente ridurre il tempo di attesa per ciclo (usando ad esempio la funzione nanosleep ) in modo da poter uscire dal ciclo molto prima dello scadere del tempo di attesa massimo di 3 secondi. (es: con un ciclo che fa un attesa di 1/100 di secondo e itera per massimo 300 volte ). Inoltre, se i dati arrivano in più spezzoni, devi prenderli da buffer e copiarli altrove (appendendoli a quelli arrivati prima), altrimenti poi alla fine del ciclo hai solo l'ultimo spezzone arrivato ed avrai invece scartato quelli che avevi letto prima nelle iterazioni precedenti. Non sapendo che formato hanno i dati o che protocollo di comunicazione utilizzi (es: MODBUS) è difficile darti altre indicazioni, ma tieni conto di quanto detto sopra. Ci sarebbero metodi più sofisticati tipo usare i POSIX timer ecc. ecc. ma quelli te li dovrai studiare con calma per conto tuo (fai prima che a colpi di domande e risposte sul forum ed in rete si trova documentazione più che adeguata a riguardo). |
|
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
|
Quote:
__________________
Come la chiami la chiami, la cocozza sempre cocozza è. |
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Jul 2005
Città: Vicenza
Messaggi: 1570
|
Quote:
Per fare un esempio banale, il seguente codice, da quel che dici, non dovrebbe funzionare, invece se compilato attende proprio il tempo specificato (che poi è lo stesso bene o male che avevo consigliato a Domus). Codice:
#include <iostream>
#include <ctime>
#include <windows.h>
using namespace std;
int main()
{
int seconds = 3;
cout << clock() << endl;
clock_t endTime = clock() + seconds * CLOCKS_PER_SEC;
while (clock() <= endTime) {
Sleep(1);
}
cout << clock() << endl;
cin.get();
}
|
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Jan 2007
Messaggi: 6192
|
Quote:
Windows, non Linux. Solo perchè due funzioni hanno lo stesso nome e parametri compatibili non è detto che siano uguali in tutto e per tutto, specialmente se vengono linkate da librerie differenti. Visti i problemi di DomusP45 e la libreria (crossplatform) che utilizzava ho ipotizzato che stesse usando la clock() POSIX (Linux ha lo standard POSIX come riferimento per le funzioni di base del kernel e le librerie fondamentali). Da non confondere con la clock() della C library standard (nel senso di ISO/IEC 9899:1990 e ISO/IEC 9899:1990/DAM 1) o con la clock() di Visual C++ (ANSI 4.12.2.1), queste ultime due sono quasi uguali anche come funzionamento in esecuzione. Avendo già avuto a che fare con porting vari e con software crossplatform avevo già avuto modo di farmi le ossa con problemi simili. A volte non ci si rende manco conto di aver linkato librerie con "funzioni compatibili per nome e parametri" perchè magari si è azzeccato l'ordine di inclusione per puro caso, poi magari si cambia qualcosa in un header e dopo in esecuzione succedono cose strane a cascata in posti che manco ci si aspetta. Non è un caso che con il tempo sia diventato un fanatico di Qt (thread, timer, UI, I/O XML e SVG, ecc. ecc. tutto multipiattaforma e ben collaudato). |
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Jul 2005
Città: Vicenza
Messaggi: 1570
|
Quote:
Comunque ultimamente pure io, pur usando soprattutto windows, mi sto dedicando parecchio alle librerie QT. E' un framework a dir poco poderoso... Completo e affidabile... Ho solo qualche dubbio sul suo futuro dopo gli ultimi svolgimenti, ma spero che il C++ sarà ancora il fulcro di questo splendido framework. |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
|
Signori é sempre un piacere leggere come siete attenti alle problematiche di tutti,anche chi ne sa meno di voi (io Qt non so manco cos'é :-P )
Sono felice peró xké ne ho capito qualcosa in più,e a quanto pare con la modifica della variabile posticcia,sembra andare bene. Grazie davvero tanto per la vostra disponibilità!!
__________________
Come la chiami la chiami, la cocozza sempre cocozza è. |
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Jul 2005
Città: Vicenza
Messaggi: 1570
|
Quote:
Oltre ad essere un framework molto valido, presenta pure quella che secondo me è, insieme a Visual Studio, la miglior ide per il c++ (anche con progetti generici, e non solo QT). Oltre a questo ha il vantaggio di essere multipiatta, a differenza di Visual Studio... Prova a installarla e vedrai che non te ne pentirai. |
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
|
Non ne dubito...anzi,lo proverò di sicuro appena ho finito con sta classe per la pinza..che ormai é agli sgoccioli spero...
Ancora grazie e buona domenica!!
__________________
Come la chiami la chiami, la cocozza sempre cocozza è. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 04:11.




















