Go Down

Topic: leOS - un semplice OS per schedulare piccoli task (Read 45158 times) previous topic - next topic

leo72


Altra cosa: ho iniziato a modificarlo..ho visto che c'è un bachetto(ci va sempre  :),se no che programma è?? )
il taskInterval è un unsigned long,che te limiti a essere <3600000(=1 ora)...però poi lo memorizzi in un vettore di unsigned int..
quindi la prima esecuzione del "processo" avviene dopo il tempo esatto,ma tutte le successive avvengono distanziate di al max 64 secondi :smiley-zipper:


Veramente plannedTasks è un unsigned long long. Che versione stai usando? Un paio di settimane fa ho messo online la 0.1.0.

PS:
sto rivedendo la libreria per usare i comuni unsigned long, ossia 32 bit, invece dei long long perché per gestire la matematica a 64 bit la libreria consuma 900 byte, esageratamente troppi.

leo72



domanda per Leo:
sbaglio o questa libreria non può funzionare contemporaneamente a swrtc?

Sembra non funzionare neanche in accoppiata alla softwareSerial se si lancia un mySerial.print all'interno di una funzione leOS :/

La softwareSerial usa i PCINT, che sempre di interrupt si tratta.

leo72


mi sa che il tunedDelay della software si appoggia anche al timer2..

tunedDelay ho visto che è un piccolo blocco di codice in assembly che, sinceramente, non so cosa faccia. Dal nome dovrebbe creare un intervallo di tempo ma non so come agisca perché non conosco il microcodice Atmel.  :smiley-sweat:

leo72


vedo che leo72 è andato in vacanza..buon per lui..  8)

Son finite, purtroppo  =( =(

m_ri



vedo che leo72 è andato in vacanza..buon per lui..  8)

Son finite, purtroppo  =( =(


mare,montagna..?


alla fine uso un altro approcio,dato che i miei sketch me lo permettono: alla fine di ogni loop,richiamo una funzione schedulatore()..
essa,guardando millis,guarda quali task lanciare ogni volta..è vero che è poco precisa,ma nel mio caso va bene..anche xkè x me in media un loop dura meno di 100 millisec..e soprattutto,lascio in pace interrupt e timer2..

leo72

Sono stato in Val Gardena  XD XD

PS:
se hai risolto in altro modo, meglio così :P

leo72

Nuova versione 0.1.1 (allegata al 1° post di questo thread).

Ho inserito la possibilità di scegliere fra la matematica a 32 e 64 bit.
Per far ciò basta commentare/decommentare la riga
Code: [Select]
//#define SIXTYFOUR_MATH

che ho aggiunto nel file leOS.h. La differenza in termini di consumo di risorse è notevole dato che per gestire i numeri a 64 bit il compilatore introduce diverse centinaia di byte in più nel firmware finale. Ad esempio, lo sketch "leOS_2_tasks" compilato con matematica a 64 bit occupa su un Amtega328 3544 byte mentre compilato con la matematica a 32 bit ne occupa solo 2392. Bisogna solo tener presente che con contatori a 32 bit si verifica un overflow dopo 49.7 giorni mentre cn quello a 64 bit dopo 584K anni. Ciò non è un grosso problema se gli intervalli sono limitati a pochi minuti o secondi, dato che situazioni atipiche si possono verificare solo nel caso in cui si modifichi il codice in modo da poter inserire intervalli così grandi che, sommati con il valore attuale del contatore dei millisecondi portino all'overflow con la conseguenza di avere un valore finale inferiore a quello rappresentato dal contatore, con l'ovvio salto dell'esecuzione di quel task.

m_ri

#187
Aug 01, 2012, 03:38 pm Last Edit: Aug 01, 2012, 03:47 pm by m_ri Reason: 1
proposta:potresti lasciare decidere all'utente,usando delle #define, se appoggiarsi al timer2 con gli interrupt oppure NON usare timer2,ma una funzioncina da mettere alla fine del loop..in questo modo,uno con la seconda modalità potrebbe usare tutto(serial software,delay,interrup...) senza farsi troppi problemi,sacrificando un po' di precisione come tempo di lancio..ovviamente sarebbe sconsigliato avere loop lenti..
la seconda modalità potrebbe appoggiarsi a millis(),e penso che sarebbe molto usata :)

leo72

Per fare ciò non serve uno schedulatore automatico, basta mettere una chiamata alla funzione prima di chiudere il codice del loop().

m_ri

#189
Aug 01, 2012, 05:50 pm Last Edit: Aug 01, 2012, 05:54 pm by m_ri Reason: 1
forse non mi sono spiegato bene  :)
se io volessi che un task viene eseguito ogni 1000 sec,x esempio,e il loop dura 0.3 sec,non posso chiamarlo ogni 0.3sec :)
quindi devo usare lo schedulatore..modifiche da apportare alla tua libreria(non sono molte) quando l'utente sceglie la modalità senza timer2:
-niente settaggi di interrupt
-dare alla funzione chiamata dall'interrupt di timer2 ogni millisec un nome umano(è da richiamare nel loop)
-al posto di usare il tuo contatore dei millis,appoggiarsi direttamente a millis(ed eventualmente gestire overflow)

e ora sei liberissimo di mandarmi "in ferie" :D

EDIT:anzi,se stass piove implemento io le modifiche e poi guardi se ti piace..

m_ri

anzi,m'è venuta in mente un'altra idea:quando uno aggiunge task,specifca se è di passa o alta priorità:nel primo caso si appoggia al loop,nel secondo agli interrupt..in fase di compilazione l'utente specifica se ci saranno solo task di alta/bassa priorità,o entrambi..

leo72

Ho capito benissimo, ma ti rispondo che non è che non si possa fare, semplicemente non mi pare una cosa coerente con l'idea alla base del leOS. Il leOS esegue la tua routine indipendentemente da cosa succeda all'interno del loop, è uno schedulatore che gestisce il lancio delle routine utente in automatico ed in modo del tutto trasparente al codice principale. Uno schedulatore inserito nel loop è soggetto ai problemi che possono nascere nell'esecuzione del codice principale, come rallentamenti inattesi dovuti a cause esterne (ad esempio un dato che non arriva nel tempo previsto da un canale qualsiasi).

Potrei elencarti casi limite. Tu hai schedulato un compito che deve essere eseguito ogni 500 ms ma il loop principale arriva a durare 700 ms. Quando il loop finisce ed il sistema controlla le routine in attesa, trova quella in ritardo: che fa? La esegue comunque anche se in ritardo? La riprogramma per dopo, con il rischio di non eseguirla mai? Se poi prendiamo 2 routine in attesa i cui tempi di esecuzione si sommano, i problemi crescono.
Altro caso. Il loop dura 200 ms, sempre per cause esterne, e la tua routine è programmata per girare ogni 50 ms. Perdi 4 esecuzioni ogni giro.

Sulla tua seconda questione, dovrei far sì che l'utente scelga il tipo di schedulatore, se legato al loop o all'interrupt, per far sì che se attivo il primo non attivo il secondo o viceversa.

Si potrebbe pensare ad una soluzione: modificare la ruotine di gestione del timer 0 contenuta nel core dell'Arduino ed inserire in essa lo schedulatore del leOS ma in questo modo si andrebbe a toccare la gestione dei millis() così come viene fatta dal core stesso. Altra soluzione sarebbe quella di utilizzare il timer 1, lasciando libero il timer 2 nel caso questo sia richiesto da una terza libreria.

E' comunque una questione delicata.
Stasera provo a lavorarci un pochino.

leo72


leo72

@m_ri:
ecco qua:
http://arduino.cc/forum/index.php/topic,116883.0.html


Go Up