Go Down

Topic: looper - un semplice schedulatore senza timer/interrupt (Read 28212 times) previous topic - next topic

testato

Ma il delay standard perche dovrebbe essere toccato ? Quello resta, e se mi serve lo uso.
Cosa facciamo ora con millis ? If questo - quello = x allora fai questaltro Else vai avanti.
Se più avanti mi serve delay standard lo uso.
Non vedere la mia idea come sostituto del delay, ma come nuovo tipo di delay.
Io dico solo di nascondere sotto una nuova funzione di looper questo delay nuovo fatto con if e millis
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72

Mi spiace, io non riesco a capire questo tuo delay. Non riesco a capire proprio cos'è che vuoi fare.
Io ho inteso che quel che vuoi fare tu è ciò che ti ho spiegato nel precedente post. Tu però mi dici che ti serve un delay diverso. E che non riesco a focalizzare.  :~

testato

purtroppo io meglio di cosi' non posso spiegarmi, perche' non ne ho le capacita'.

tento di resettare almeno per portare a conclusione il discorso con un si o con un no:

l'attuale semplicissima funzione, integrata nel core di arduino, delay(1000) e' bloccante, ed e' giusto cosi', nessuno vuole eliminarla.
ora la domanda semplice:
potra' tecnicamente un domani esistere, creata dal team arduinico stesso ed integrato nel core, una newdelay(1000); che non sia bloccante ?
ripeto cosi' come l'ho scritta, cioe' senza dover includere librerie, senza dover richiamare schedulator, senza dover creare job o altre funzioni, intendo semplicemente mettere newdelay(1000); in un qualsiasi punto dello sketch ?

Se mi dici No, non e' tecnicamente possibile riuscire a gestire un delay non bloccante con questi pochi parametri a disposizione, cioe' il nome newdelay ed il parametro 1000, io mi metto l'anima in pace, e l'essere umano dovra' usare looper o la tecnica millis fino alla fine dei tempi.  :)

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

erpomata

Scusa ma non capisco neanche io.
Che dovrebbe ritardare(delay) questa nuova funzione?

nid69ita

#49
Apr 03, 2013, 04:36 pm Last Edit: Apr 03, 2013, 08:00 pm by nid69ita Reason: 1
Credo intenda che la nuova "newdelay" dovrebbe attendere come l'attuale delay ma senza bloccare gli interrupt.

Ho visto nel core.cpp che la delay si basa sulla micros() che internamente chiama cli(); quella cli()  ferma gli interrupt?

La delayMicroseconds invece è fatta in maniera molto diversa. Alla fine poi c'e' un pezzo in asm. Quella è bloccante rispetto agli interrupt?


La millis() anche lei momentaneamente blocca gli interrupt:
Code: [Select]

unsigned long millis()
{ unsigned long m;
uint8_t oldSREG = SREG;
// disable interrupts while we read timer0_millis or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_millis)
cli();
m = timer0_millis;
SREG = oldSREG;
return m;
}
my name is IGOR, not AIGOR

lestofante

Quote
ma senza bloccare ad esempio gli interrupt

non tirare inmezzo gli interrupt, questa librerira NON li usa. ed è per questo che ha creato la cosa leo.

Quote
m = timer0_millis;

questa è l'unica iustruzione per cui gli interrupt sono bloccati, poi li riattiva con
Quote
SREG = oldSREG;

quindi parliamo di una decina di clock, 20 a star larghi direi, andando a naso.

Quote
La delayMicroseconds invece è fatta in maniera molto diversa

non hai timer così precisi, quindi si basa sul fatto che sa che ad una certa frequenza di clock certe istruzioni impiegano tot clock, e quindi tot clock * frequenza = tempo.... e tanta imprecisione :)

Quote
potra' tecnicamente un domani esistere, creata dal team arduinico stesso ed integrato nel core, una newdelay(1000); che non sia bloccante ?

ni.
nel senso: la delay non bloccante come fa a sapere che codice deve eseguire al termine del 1000?
risposta: gli passi come parametro una funzione, che conterrà il codice da eseguire ogni tot.
e già esiste: looper(non usa interrupt quindi ogni tatnto devi chiamare scheduler(), meno preciso, ma permette funzioni lunghe) e leOS(interrupt, basta settare il dalay e la funzione ed eventualmente il tempo di ripetizione, ma essendo la funzione eseguita in interrupt ha i classici svantaggi)

Ora, tu dici creata dal team. io ti dico: perché la SoftSerial attuale è esterna, e poi integrata nel core perchè considerata "degno sostituto". Lo stesso POTREBBE avvenire con il leOS o lo sheduler.

Quote
senza dover includere librerie

Anche la delay che usi è una libreria.. solo che la include in automatico arduino IDE. Quindi si può fare, ma ci vuole una ottima ragione.

Quindi risposta generale:
NO: se non chiami sheduler (come leOS), allora sei bloccato dalle limitazioni interrupt. Se usi looper() e metti sheduler() nel main(nascosto) dell'arduino a fine di ogni loop ( come per SerialEvent() )se il tuo loop() è pieno di delay non avrai mai i task eseguiti con la giusta tempistica.
Quindi non esiste un testatoDelay() come lo intendi.. niente "silver bullet".
A meno che non si riesca a creare un VERO scheduler con due thread: uno per la loop e uno, con priorità superiore, per task schedulati, cche magari lancia ogni sotto-task in un thread a parte. Però a questo punto... che thread a precedenza sugli altri?
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

nid69ita


Quote
ma senza bloccare ad esempio gli interrupt

non tirare inmezzo gli interrupt, questa librerira NON li usa. ed è per questo che ha creato la cosa leo.


A quale libreria ti riferisci, non capisco!? La delay del core o quella di @leo ?
my name is IGOR, not AIGOR

lestofante

Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

nid69ita

#53
Apr 03, 2013, 08:30 pm Last Edit: Apr 03, 2013, 08:38 pm by nid69ita Reason: 1
Ho scritto:
>>Credo intenda che la nuova "newdelay" dovrebbe attendere come l'attuale delay ma senza bloccare gli interrupt.
Ovvero rispondevo per @Testa, vorrebbe una newdelay non bloccante rispetto agli interrupt cosa che invece fa la delay attuale.
Lo sò anche io che la libreria di @Leo NON è bloccante neppure per gli interrupt.

@Testa, veramente non ha senso quello che chiedi. Solo un discorso di non bloccare gli interrupt può avere senso.
Una newdelay(1000) o è bloccante, oppure che senso ha?
Con la millis() tu, ripeto tu, scrivi del codice che viene eseguito nel mentre conti i millis, per fare la stessa cosa dovresti avere una newdelay che come dice @Leo dovrebbe richiamare una funzione da eseguire mentre la newdelay conta.
E' come se tu chiedessi di poter fare "qualcosa" (istruzioni decise da te) mentre che sò, chiami la digitalWrite() (anche lei è una funzione che ha una serie di istruzioni)
my name is IGOR, not AIGOR

lestofante

bhe ma da quel punto di vista anche quella di leo usa la millis() quindi è bloccante.. ma è davvero definibile bloccante qualcosa che blocca gli interrupt per 10 clock? io per bloccante per interrupt intendo qualcosa che blocca li interrupt per TUTTA la sua esecuzione.
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

nid69ita

Scusa, ma che c'entra una o più mills chiamate in una serie di istruzioni rispetto a una delay() che blocca gli interrupt per tutto il tempo t che hai passato come parametro?

Domanda mia però. Ma veramente la delay è così bloccante per gli interrupt?
Code: [Select]

void delay(unsigned long ms)
{ uint16_t start = (uint16_t)micros();
 while (ms > 0) {
if (((uint16_t)micros() - start) >= 1000) {
ms--;
start += 1000;
}
 }
}


La delay richiama più volte la micros() che internamente chiama cli() ma poi all'uscita rimette a posto SREG.
my name is IGOR, not AIGOR

lestofante

Quote
Domanda mia però. Ma veramente la delay è così bloccante per gli interrupt?

NO! La delay non è bloccante per gli interrupt, da dove salta fuori?

forse c'è stata fonfusione su questa affermazione:


Credo intenda che la nuova "newdelay" dovrebbe attendere come l'attuale delay ma senza bloccare gli interrupt.

Ho visto nel core.cpp che la delay si basa sulla micros() che internamente chiama cli(); quella cli()  ferma gli interrupt?


che come spiegato poi blocca sì gli interrupt, ma solo per una decina di clock.

Quote
Una newdelay(1000) o è bloccante, oppure che senso ha?

quando testato parla di bloccante non intende per i delay, intende una cosa tipo
Code: [Select]
testatoDelay(millisecondiDqaAttenderePrimaDiEseguire, funzioneDaEseguire);
che però come già detto è quello che fa già il looper e il leOS, che però hanno le loro limitazioni a cui non si può scappare, credo(come detto prima dipende dall'architettura del micro, che credo non lo conseta prorpio)
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

testato

Finalmente ho capito, grazie a tutti  :) (karma per tutti)

x nid69ita: per bloccante non intendo rispetto agli interrupt, ma vista la mia strana richiesta tu giustamente hai pensato a quelli.

credo che la risposta definitiva e che mi ha fatto capire e' quella di Leo
Quote
la delay non bloccante come fa a sapere che codice deve eseguire al termine del 1000?


giustamente con il delay ufficiale e' facile, blocchi tutto il micro e via, alla fine del tempo prefissato riparti con l'istruzione successiva, mentre con una ipotetica newDelay non bloccante, senza passare per looper o altro, come fa il micro a sapere cosa deve gestire ?

grazie per avermi aperto la mente  :)
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

nid69ita

#58
Apr 03, 2013, 11:43 pm Last Edit: Apr 03, 2013, 11:54 pm by nid69ita Reason: 1
Potrebbe piacerti questa schifezzuola di codice, molto poco ortodosso, nascondo tutta la millis con delle define (IDE Arduino compila ma non ho provato):
Code: [Select]

#define CONCAT_IMPL( x, y ) x##y
#define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y )
#define BEGINDELAY(t,v) unsigned long MACRO_CONCAT(prev,v)=0; unsigned long MACRO_CONCAT(curr,v)=millis(); if(MACRO_CONCAT(curr,v)-MACRO_CONCAT(prev,v)<(t)) {
#define ENDDELAY(v) MACRO_CONCAT(prev,v)=MACRO_CONCAT(curr,v);}

void setup()
{ }

void loop()
{ BEGINDELAY(500,1)
   // qui metti codice per eseguire mentre conta il primo delay
 ENDDELAY(1)
 BEGINDELAY(600,2)
   // qui metti codice per eseguire mentre conta il secondo delay
 ENDDELAY(2)
}


oppure
Code: [Select]

#define CONCAT_IMPL( x, y ) x##y
#define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y )
#define BEGINDELAY(t,v) unsigned long MACRO_CONCAT(prev,v)=0; unsigned long MACRO_CONCAT(curr,v)=millis(); if(MACRO_CONCAT(curr,v)-MACRO_CONCAT(prev,v)<(t)) { MACRO_CONCAT(prev,v)=MACRO_CONCAT(curr,v);
#define ENDDELAY }

void setup()
{ }

void loop()
{ BEGINDELAY(500,1)
   // qui metti codice per eseguire mentre conta il primo delay
 ENDDELAY
 BEGINDELAY(600,2)
   // qui metti codice per eseguire mentre conta il secondo delay
 ENDDELAY
}


P.S. vietato tirarmi sassi o qualsiasi materiale contundente, valgono solo gli insulti
my name is IGOR, not AIGOR

lestofante

nel secondo credo che

Code: [Select]
#define ENDDELAY(v) }

debba essere

Code: [Select]
#define ENDDELAY }

:smiley-mr-green:

edit: buon debug!
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

Go Up