Newsgroup: it.comp.os.linux.development
Titolo: C e parallela "lenta"...

Salve, mi sono costruito un piccolo circuitino per comandare un motore
passopasso.
Il circuitino ha 2 ingressi: un bit per la direzione e un bit per il passo
da compiere. Ogni volta che il bit va a zero e ritorna a 1 il motore va 
avanti di un passo.
Il problema e' che e' tutto moolto lento, per fargli fare un giro, 200
passi, ci mette 3 secondi !!
il ciclo while che uso per farlo avanzare e' :
ioperm(0x378,1,1);
while(i<x) 		/* x = numero di passi che il motore deve fare */
{
outb(254,0x378);
outb(0,0x378);
i++;
}
Il problema e' nel "ioperm" che deve aspettare il permesso dal SO ?
C'e' un metodo piu' veloce per scrivere un bit su 0x378 ?
grazie per l'interessamento..
							MaxDamage 

No, credo che una volta ottenuti, i privilegi, non debbano essere
ulteriormante confermati dal sitema.
E se fosse troppo veloce (cioe' non sente il cambiamento di livello)?
Prova a inserire usleep(1000) dopo ciascun outb(). Se funziona prova a
sostituire l'usleep con un inb() a vuoto, giusto per perdere un un po' meno
tempo.
Ciao
Alessandro Staltari.
P.S. Che ci devi fare con il motore passo-passo le gare di macchinine? ;-)

,

Grazie per l'aiuto, adesso il mosfet di potenza si accende e si spegne nel
modo corretto , solo che anche mettendo usleep(1) e' troppo lento.
Forse e' il mosfet che e' lento.. mmh...
pero' mi pare strano perche' per fare il ciclo while da 0 a 200 ci mette 2
secondi..
il motore ( in realta' saranno 3...) mi serve per costruire un piccolo robot
di tipo SCARA.. :-) 
mi serve per tagliare del polistirolo partendo da un file cad e ottenere
cosi' una specie di "prototipo".
								MaxDamage
 

C'e' un metodo piu' veloce per scrivere un bit su 0x378 ?
Quel ciclo puo' commutare quasi cinquantamila volte al secondo.
Il problema infatti secondo me e' questo... i bits commutano prima che i
componenti pilota abbiano digerito l'impulso. E il motore perde passi.
Fammi sapere. C'era un'altra soluzione piu' cattiva, realizzata pero' da
un mio collega...
Leonardo
".signature": bad command or file name

 un mio collega...
Addirittura più cattivo di te è questo collega? :P
Ciao,
Fabio Alemagna


SCARA? Cos'e una sigla? Perdonami l'ignoranza ma questa mi manca.
Comunque il concetto generale credo di averlo capito :-)
Ciao
Alessandro

 ma questa e' un'altra storia...
Non è questo il vero problema, il problema è che i PC di solito hanno un
clock che spacca il centesimo di secondo, non il millionesimo.
Ciao,
Fabio Alemagna

 completamente padrone :-).
Tutti i clock che si rispettino possono causare interrupts, gli
interrupts esistono proprio per evitare "l'appesantimento".
Ciao,
Fabio Alemagna

 Alessandro
scara e' un robot a 3 gradi di liberta', immaginati di muovere in un piano
orizzontale la tua mano utilizzando solamente i movimenti della spalla e 
del gomito e di tenere in mano un asta che puo' andare su e giu'.
Sei diventato uno scara ! :-))
Comunque quando risco a far funzionare qualcosa metto su una homepage 
col progettino.. avendo usato tutte info ( hardware e software.. ) free
trovate su internet mi pare il minimo ! :-)
intanto grazie delle info !
						MaxDamage

 Leonardo
Ho risolto con un ciclo while che fa una sottrazione per 8000 volte tra un
outb() e l'altro. Pero' mi interessa sapere quale e' la soluzione cattiva,la
risposta di Fabio Alemagna sulla tua cattiveria mi incuriosice ! :-))
grazie per l'aiuto !
						MaxDamage

secondi..
C'e' qualcosa di TRAGICAMENTE sbagliato nella gestione dell'I/O, o forse
hai un modulo in conflitto (lp.o? zip? Boh).
Sul mio Pentium:
int main(void)
{
        int i;
        if(ioperm(0x378,2,1))
        {
                printf("Errore.\n");
                return -1;
        }
        for (i=0; i < 200; i++)
        {
                outb(0xF0, 0x378);
                outb(0x00, 0x378);
        }
        ioperm(0x378,2,0);
        return 0;
}
www:/usr/src/keypad # time ./testpar
real    0m0.009s
user    0m0.000s
sys     0m0.010s


 Fabio Alemagna
Questo non mi risulta. I PC sono in grado di misurare intervalli di tempo
molto piu' piccoli del centesimo di secondo, ma normalmente i sistemi
operativi non ne tengono conto perche' altrimenti si appesantirebbe troppo
il loro lavoro (l'espressione e' un po' semplicistica, ma non so se e' il
caso che mi perda in dettagli tecnici di cui, tra l'altro, non sono
completamente padrone :-).
Ciao,
Alessandro Staltari

 Fabio Alemagna
Ciao
Alessandro

 sistema operativo aumenta.
Gli interrupts servono ad evitare che il sw debba fare "polling", ovvero
debbe stare a controllare piů o meno frequentemente se una certa
condizione č vera oppure no. Quando arriva l'interrupt viene chiamata la
routine che lo gestisce: questo č il modo piů efficiente in cui si puň
fare questa cosa. 
Saluti,
Fabio Alemagna

 Fabio Alemagna
Ciao
Alessandro.


...ecco cosa ho trovato:
Il chip 8253 che genera il timer di sistema ha una frequenza di base di
1193181 Hz, che puo' essere divisa per un valore arbitrario tra 1 e 65536
(vine usato un registro a 16 bit assumendo la convenzione che 0 valga
65536).
Nel caso di DOS viene utilizzato il valore 65536 e quindi il tick di sistema
vale 1193181/65536=18,2 tick al secondo. Per Linux il divisore e'
probabilmente 11932 per cui  si hanno 100 tick al secondo.
Se si usasse 1 si avrebbero 1193181 tick (interrupts) al secondo, ma il
sistema probabilmente non li reggerebbe.
Le estensioni real time di Linux modificano dinamicamente le impostazioni
del chip per ottenere temporizzazioni piu' precise senza destabilizzare il
sistema.
Ciao
Alessandro.

[snip]
Allora è come dici tu. Fatto sta che su linux non puoi utilizzare una
maggiore precisione (e servirebbe molto anche a me).
Ciao,
Fabio Alemagna

Addirittura più cattivo di te è questo collega? :P
Si'. Quando qualcosa non funziona, io dico "Fanculo, dove sono i
sorgenti?". Lui dice "Fanculo, passatemi un saldatore."
Quando si lavorava assieme, ci chiamavano i Nazzareni: io curavo
i malati, e lui resuscitava i morti :-)
Leonardo "be', diciamo una volta su due"


Prenditi i patch di KURT, la pagina e':
http://www.ittc.ukans.edu/kurt/
Ciao
-- 
Simone Piccardi
Microsoft is NOT the answer. Microsoft is the Question.
The answer is: "NO!"


Non per avere interrupts. Ma se il problema e' ottenere delay di 
qualche microsec puoi usare nanosleep/usleep, che pero' hanno  
l'inconveniente di funzionare correttamente solo come root e con 
delay di max 2 msec, altrimenti il processo viene schedulato e 
come risultato hai un delay di almeno 10-20 msec 
(vedi /usr/src/linux/kernel/sched.c fn sys_nanosleep) e questo 
mi pare fosse il problema di MaxDamage (2 sec per 200 cicli).
In alternativa, se usi un pentium, puoi usare il suo contatore
interno, che viene incrementato alla frequenza con cui lavora
il processore, e questo risulta in una risoluzione inferiore al 
microsec. 
L'istruzione assembly e' rdtsc e il risultato e' messo in EDX:EAX. 
rdtsc puo' essere usata dai normali processi.
Da /usr/src/linux/include/asm-i386/msr.h
#define rdtsc(low,high) \
      __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
e la chiamata (da /usr/src/linux/include/asm-i386/timex.h)
	unsigned long eax, edx;
        rdtsc(eax,edx);
 
La frequenza del processore la trovi naturalmente in /proc/cpuinfo.
Ciao
Bruno