leOS - un semplice OS per schedulare piccoli task

Madwriter:
Ciao Leo72,
Volevo chiederti una cosa il tuo leOS per funzionare si basa su, un timer interno ma se tu ti basassi su un timer hw esterno di precisione non risolveresti tutti i problemi di incompatibilita con altre liberie?

Sicuramente si può fare, e ci sono altri sistemi, uno è quello detto da m_ri. Però così fai tutto senza componenti esterni. Inoltre considera che il leOS gira anche sull'Attiny85: se su quel micro, che ha solo 5 pin utili, gliene levi 1, lo depauperi del 20% delle sue capacità di I/O :wink:
Inoltre il leOS risulta incompatibile con alcune librerie per via dell'uso del timer 2, ma usando un timer esterno potrebbe risultare incompatibile con tanti shield, visto che dovresti togliere un pin a quelli usabili. Insomma, è un cane che si morde la coda :stuck_out_tongue_closed_eyes:

m_ri:
come vorresti farlo(lo so di non essere leo :slight_smile: ) programmi un timer esterno per cambiarti lo stato di un pin dell'arduino ogni millisecondo(o ogni 10..),e intercetti l'interrupt del cambio stato del pin?

cmq,la comodità è che non richiede componenti esterne..

ma per una componente esterna di 20 cent puoi tranquillamente usare i timer interni per le librerie più standard,si pensavo ad una cosa del genere ma non so se è realizzabile.

Vi aggiorno sugli... aggiornamenti del leOS :sweat_smile:

Con la versione 1.0.0 ho introdotto un nuovo metodo per sapere lo stato di un task.

myOS.taskIsRunning(nomeFunzione)

Esso restituisce PAUSED, SCHEDULED o ONETIME. La cosa è utile se ad esempio un task modifica lo stato di un altro task, indipendentemente dal codice dell'utente.

Con la versione 1.0.1 ho invece sistemato il problema dell'overflow del contatore a 32 bit. Ciò significa che dopo 49,7 giorni non si verificano situazioni strane. Si può così evitare di utilizzare i contatori a 64 bit, che comportano un aggravio di centinaia di byte di flash occupata in più, cosa utile soprattutto sui piccoli micro con poca memoria.

L'ultima versione della lib è scaricabile come sempre dal mio sito (link in calce alla mia firma).

Ciao, se posso permettermi esprimo un dubbio sul nome della funzione.

Se tale funzione mi servisse per sapere se un task è "running" o no, la chiamaerei isTaskRunning(). Ma poiché non ritorna un booleano ma una tra diverse possibili costanti simboliche, secondo me è meglio chiamarla getTaskState() (o status).

my 2 cents :slight_smile:

Uhm... detta così ha una sua logica :wink:

EDIT:
la versione 1.0.1a, da poco online, ha il metodo rinominato in getTaskStatus.

per la serie,facciamo i rompic*****ni, una teorica funzione taskIsRunning dovrebbe (quasi) sempre restituire false,dato che non c'è esecuzione parallela.. :grin:

(tanto leo non sai dove abito..)

m_ri:
per la serie,facciamo i rompic*****ni, una teorica funzione taskIsRunning dovrebbe (quasi) sempre restituire false,dato che non c'è esecuzione parallela.. :grin:

Bast.... :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes:

(tanto leo non sai dove abito..)

Sei fortunato perché non me lo ricordo più :stuck_out_tongue:

m_ri:
per la serie,facciamo i rompic*****ni, una teorica funzione taskIsRunning dovrebbe (quasi) sempre restituire false,dato che non c'è esecuzione parallela.. :grin:

(tanto leo non sai dove abito..)

Ti prendo sul serio: un task è running quando il suo stato ha quel valore. Stai confondendo lo stato di un task con il fatto che in dato istante stia occupando la CPU.

tuxduino:

m_ri:
per la serie,facciamo i rompic*****ni, una teorica funzione taskIsRunning dovrebbe (quasi) sempre restituire false,dato che non c'è esecuzione parallela.. :grin:

(tanto leo non sai dove abito..)

Ti prendo sul serio: un task è running quando il suo stato ha quel valore. Stai confondendo lo stato di un task con il fatto che in dato istante stia occupando la CPU.

ti contraddisco: quando si parla di stati di schedulatori,tra i tanti stati c'è ready(pronto per l'esecuzione,ma NON in esecuzione) e running(in esecuzione in quel preciso momento)..sono due stati diversi..i pcb(process control block,o i tcb) vengono poi spostati da uno all'altro a seconda delle politiche usate..

prima di contraddire leo,penso 2 volte a quello che scrivo.. :wink:
altrimenti qualcuno mi sputt.....bbe per l'eternità,ti pare? ]:smiley:

Ops... "Ready", come scordarsi di te ? :cold_sweat:

:wink:

Leo, hai visto questa discussione? --> http://arduino.cc/pipermail/developers_arduino.cc/2012-October/007211.html

No, non l'avevo vista. Non sono iscritto alle mailing-list.
Se hai modo di rispondere, fagli presente che esiste già uno schedulatore :wink: XD

Ne vogliono mettere uno nella futura release dell'IDE, modificando il delay e delaymicrosecond in modo che, mentre si aspetta gli altri task proseguano.

Esempio --> Added general yield()-hook for cooperative scheduling development · cmaglie/Arduino@107c192 · GitHub

Lo sai che in questi giorni stavo pensando proprio a modificare il timer che sugli Atmega ed Attiny gestisce millis per integrare il leOS lì, in modo da non consumare timer extra né interferire con altre librerie? :wink:

È una buona idea far fare tutto il lavoro a delle funzioni richiamate con leOS e lasciare il loop() vuoto se non serve eseguire in continuazione il codice o è meglio lasciare la parte principale in loop() e mettere un delay alla fine?

il famoso Delay2, di cui rivendico la paternita' dell'idea, sara' la funzione piu' importante di Arduino
cioe' se ti serve un delay bloccante userai delay() se ti serve uno non bloccante useray delay2()
senza dover mettere in campo millis ed i suoi giri contorti (per un non programmatore)

a proposito Leo, complimenti per il lavoro pubblicato sull'overflow di millis,
potresti chiedere di modificare il blinkwithoutdelay aggiungendo la tua idea per superare i famosi 50giorni
sarebbe comunque molto bello avere il tuo nome in uno sketch che viene inserito ufficialmente negli esempi dell'IDE

p.s. ma oltre all'articlo sul tuo blog c'e' hai aperto anche una discussione sul forum ?

d407336:
È una buona idea far fare tutto il lavoro a delle funzioni richiamate con leOS e lasciare il loop() vuoto se non serve eseguire in continuazione il codice o è meglio lasciare la parte principale in loop() e mettere un delay alla fine?

I task dovrebbero essere compiti semplici, che occupano poco tempo CPU, in modo da non rallentare l'esecuzione delle altre funzioni basate su interrupt. Se il tuo caso ricade in questo esempio, puoi anche inserire tutto in task e lasciare il loop vuoto. Se hai un compito che invece è molto gravoso, conviene inserirlo nel loop (e qui puoi rallentarne l'esecuzione con un delay).

Testato:
a proposito Leo, complimenti per il lavoro pubblicato sull'overflow di millis,

Grazie :wink:

potresti chiedere di modificare il blinkwithoutdelay aggiungendo la tua idea per superare i famosi 50giorni
sarebbe comunque molto bello avere il tuo nome in uno sketch che viene inserito ufficialmente negli esempi dell'IDE

Non credo che lo faranno mai :stuck_out_tongue_closed_eyes:

p.s. ma oltre all'articlo sul tuo blog c'e' hai aperto anche una discussione sul forum ?

No.

PaoloP:
Leo, hai visto questa discussione? --> http://arduino.cc/pipermail/developers_arduino.cc/2012-October/007211.html

Oggi ho studiato un po' la cosa, ed è una funzione molto più complessa della mia. Essa sfrutta un modulo presente nel SAM3X, il SysTick, un contatore indipendente dai timer del micro a cui hanno agganciato un gestore di task. Ogni task ha un suo tempo computazionale, ed il tutto è gestito dallo scheduler proprio tramite i tick, anche il delay segue lo stesso principio: usano un task che genera i millis, che poi leggono per i ritardi. Insomma, una cosina più raffinata che ovviamente non è replicabile sui Mega perché appunto utilizzano dell'HW dedicato.

PS:
in teoria si potrebbe agganciare il leOS ad un INT esterno o ad un PCINT, ma in questo modo si perderebbe un pin.