Newsgroup: it.comp.os.linux.development
Titolo: Qt e polling

Salve a tutti,
mi trovo a dover fare polling di certo hardware all'interno del mio
programma Qt (che gira su una board ARM su una Debian embedded), e mi
chiedevo quale fosse il miglior modo di farlo. L'hardware in questione
si interfaccia via i2c, pensavo di avere un thread separato che altro
non fa che girare all'infinito e continuare a pingare la periferica
i2c in questione... il problema e' che cosi' mi occupa il 100% della
CPU :) d'altro canto ho bisogno di sapere subito quando la periferica
ha qualcosa da riportare (nel giro di millisecondi... insomma, appena
l'OS lo consente).
 
Fosse una seriale la collegherei ad un QSocketNotifier e mi farei
consegnare un segnale quando succede qualcosa e vivrei felice, ma per
i2c non credo esista un meccanismo simile...?
 
Idee?
 
Thx!


Non so nulla di i2c, ma forse si puo' usare una comune funzione select 
dentro al tuo thread separato come si fa di solito con i socket o le porte 
seriali.
 
Nicola.
 
-- 
chi va pian va san e va lontan

 
 
Dovrebbe essere lo stesso, se hai il file descriptor associato.
 
 
Ciao  Manlio

 Non conosco I2C, come fai il ping al momento?
 
Mi sa che per i2c non funziona, non so come funziona il driver ma dal
punto di vista elettrico la mia CPU e' il master e le periferiche sono
slave, e la comunicazione e' cominciata dal master (scrive certi bit
sul bus e aspetta che lo slave risponda).
Quindi dal punto di vista elettrico "deve" essere polling, non puo'
essere interrupt.  E quindi mi sa che non c'e' modo di aggirare il
problema: qualcuno (userland o kernel) deve continuare a pingare le
periferiche iniziando transazioni i2c.

 i2c.
 
Hai dato una occhiata a
http://www.kernel.org/doc/Documentation/i2c/
 
 
in particolare
http://www.kernel.org/doc/Documentation/i2c/dev-interface
 
 
 
Ciao  Manlio

 bus e aspetta che lo slave risponda).
 
Ok, forse ho capito meglio cosa vuoi fare.
La tua frase "ho bisogno di sapere subito quando la periferica
ha qualcosa da riportare" mi aveva confuso, e pensavo che la periferica 
restasse in attesa di un qualche evento e poi notificasse il master.
 
Nel tuo caso la soluzione migliore è usare un thread separato che fa il 
polling, avendo l'accortezza di chiamare sleep (va bene anche sleep(0)) 
dopo ogni richiesta al bus.
 
In alternativa puoi usare un timer (magari [1][2]).
Fai dei test per vedere quale delle due soluzioni è più efficiente.
 
 
[1] 
http://pubs.opengroup.org/onlinepubs/000095399/functions/
 
timer_create.html
[2] 
http://kernel.org/doc/man-pages/online/pages/man2/timer_create.2.html
 
 
 
Ciao  Manlio

 usare un interrupt o qualcosa di simile.
 
Beh, da quel che vedo su qualche pezzo di codice per l'i2c sembra che 
qualche driver preveda l'uso degli interrupt e qualche altro no.


 dopo ogni richiesta al bus.
 
Grazie dei link, credo che faro' cosi'.
Essendo nu programma in Qt non posso usare la solita sleep() , ma
QThread dovrebbe avere un metodo sleep, altrimenti penso si possa
ottenere lo stesso risultato con un QTimer.
Investighero'.
 
Thx again.

 restasse in attesa di un qualche evento e poi notificasse il master.
 
Continuo a non capire perché la select non va bene.


> Continuo a non capire perché la select non va bene.
 
Hai trovato del codice che usa quel metodo?  Se si postalo, mi
aiuterebbe a capire come funziona questa cosa.
 
Il fatto e' che non ho mai provato, ma non vedo come possa funzionare
dal punto di vista elettrico.
Faccio l'esempio seriale VS i2c (supponendo che la CPU e' il master e
la periferica e' il client/slave) : se ho capito bene, la seriale ha
un filo che e' fisicamente pilotato dallo slave (potrebbe essere CTS o
RTS), cosi' che la periferica puo' pilotare quel filo quando ha
qualcosa da trasmettere al master; la CPU vede il segnale e scatta un
interrupt che viene gestito dall'apposita routine.  i2c invece non ha
un meccanismo del genere: ha solo due fili (clock e dato) e la
comunicazione viene iniziata dal master, che manda un certo segnale
sulla linea dati (l'indirizzo della periferica a cui vuole accedere),
e il client risponde. Se il client ha qualcosa da mandare non puo'
fare nulla, non puo' comunicarlo al master, quindi non vedo come possa
esistere un meccanismo di interrupt che potrebbe essere sfruttato da
una select() sul descrittore dell'i2c.

 una select() sul descrittore dell'i2c.
 
Ho una qualche esperienza di master/client via rs485 ma non di i2c. Il 
master chiede qualcosa allo slave e questo dovrebbe rispondere. Nel momento 
in cui risponde, a livello elettrico non si sa se è il Master o lo Slave che 
comunica. 
Ripeto non so nulla di i2c e da quel poco che ho capito (wikipedia, n.d.r.) 
la cosa è un po' diversa: il Master controlla la linea SCL e SDA e lo slave 
solo la SDA. Tuttavia tanto come una comune seriale "qualcosa" legge la 
differenza di tensione (ah, è richiesto anche il filo di GND?) e quindi puo' 
generare un interrupt.
 
Molto IMHO: non credo ci possa essere un ostacolo elettrico 
all'implementazione degli interrupt nel protocollo i2c. 


 generare un interrupt.
 
Lo slave puo' generare un interrupt quando il master abbassa SDA, ma
e' il master che deve iniziare la comunicazione. Quindi il master non
puo' sapere se lo slave ha dati da mandargli finche' non inizia una
comunicazione, cioe', di fatto, fa un polling.


Ah, ok, ora ci sono arrivato anch'io.
Beh allora devi proprio fare il polling. Al limite per ottimizzare la select 
la puoi usare dopo aver fatto la richiesta allo slave, ma temo che non basti 
a ridurre decentemente i cicli della cpu.
