Pages: [1] 2 3 ... 31   Go Down
Author Topic: leOS - un semplice OS per schedulare piccoli task  (Read 30432 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Siccome in questi giorni ho lavorato facendo il turno di notte, le sere erano lunghe, quindi per ammazzare il tempo ho scritto il leOS.  smiley-yell

Il leOS, da little embedded Operating System, è un semplice sistema operativo in tempo reale (RTOS). Usa il timer 2 per gestire i task dell'utente e, ovviamente, fa perdere le funzionalità PWM sui pin 3 e 11. Il leOS può eseguire semplice task che non richiedano gravosi impegni di CPU però può risultare carino in tutti quei casi in cui si deve gestire un compito ripetitivo che si vuole rendere indipendente dal loop principale del programma.

Per testare il leOS basta scaricare il pacchetto allegato e scompattarlo. Dentro trovate una cartella denominata /leOS che dovete copiare all'interno della cartella /libraries contenuta nella cartella dei vostri sketch. Di solito è /home/utente/sketchbook/libraries per gli utenti Linux e /Documenti/Arduino/libraries per gli utenti Windows.

Per usare il leOS basta includere la libreria e creare una nuova istanza della classe leOS:

Code:
#include "leOS.h"
leOS myOS;

A questo punto va chiamato nel setup() il metodo begin, che prepara lo schedulatore del leOS, e dopo si possono aggiungere i propri task col metodo .addTask(). Ecco un esempio:

Code:
void setup() {
  myOS.begin();
  myOS.addTask(miaFunzione, intervallo[, stato]);
  ....
}

Con miaFunzione indicata la funzione che volete schedulare, con intervallo un numero non più grande di 1000 (potete modificare questo valore nel file leOS.cpp) che indica ogni quanti ms volete far ripetere la vostra funzione. stato indica invece allo scheduler lo stato del task. Può essere: PAUSED, ed il task viene aggiunto ma in modalità "pausa", ossia non parte finché non viene avviato esplicitamente dall'utente con restartTask(); SCHEDULED (opzione predefinita), che indica lo stato normale di un task, che viene eseguito non appena aggiuntO; ONETIME, che viene eseguito solo una volta.

Per provare il leOS ho allegato diversi sketch dimostrativi.
Per usarlo collegate (con le debite resistenze) 3 led rispettivamente ai pin 7, 8 e 9 e poi caricate lo sketch.
Vedrete che ogni led lampeggia con una frequenza differente! Il led collegato al pin 8 è quello gestito dal loop principale, a dimostrazione che ogni task è indipendente dal loop e che nessun task ferma il programma.

Al momento il leOS può solo aggiungere task, metterò a breve i metodi per cancellare i task schedulati.

Buon divertimento e fatemi sapere che ne pensate  smiley-lol smiley-lol

DOWNLOAD:
l'ultima versione aggiornata delle libreria è disponibile sulla pagina del leOS sul mio sito personale

STORICO:
v. 0.0.3:
questa versione introduce la gestione dei task aggiunti allo scheduler. Nello specifico ho introdotto 3 nuovi metodi:

Code:
myOS.removeTask(nomeFunzione);
myOS.pauseTask(nomeFunzione);
myOS.restartTask(nomeFunzione);

I metodi hanno nomi autoesplicativi ma riassumo brevemente. removeTask serve a rimuovere permanentemente un task dallo scheduler. pauseTask serve a mettere in pausa un task, mentre restartTask serve a farlo ripartire.
Lo sketch allegato fa comunque vedere l'uso di questi ultimi due task.

L'utente è tenuto a scrivere il suo codice affinché lo stato del task al momento della messa in pausa, della ripartenza o della sua rimozione sia coerente e/o compatibile con il resto del codice e con il circuito collegato. Mi spiego: se al posto di un led, si pilota ad esempio un transistor che alimenta un altro dispositivo bisogna prevedere il fatto che se il pin resta alto ed il transistor in conduzione, che tale stato sia compatibile con il circuito ed il restante codice. Ma mi sembra logico.

v. 0.0.4:
introdotto l'uso di un contatore interno a 64 bit per cui lo schedulatore andrà in overflow dopo 584.942.417 anni!

v. 0.0.5:
corretti alcuni bug, ottimizzato il codice e ridotto l'uso della memoria del programma compilato.

v. 0.0.7:
implementata la gestione dei task one-time, ossia un tak che deve essere eseguito solo 1 volta. Comodo per impsotare lavori da eseguire dopo un certo periodo di tempo dall'avvio dell'Arduino.

v. 0.1.1:
aggiunta la possibilità di scegliere fra la matematica a 32 e 64 bit. 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.

v. 0.1.2:
sistemato un bug nella gestione dei task one-time

v. 0.1.3:
adesso è possibile aggiungere un task impostandolo come "PAUSED" in modo che sia inserito nello scheduler ma che non venga eseguito immediatamente. Per far partire il task basta usare il metodo restartTask(). Aggiunti anche due nuovi sketch di esempio.

v. 0.1.4:
ho riscritto il core usando le Struct per tenere più ordinata la gestione dei parametri dei task

v. 0.1.5:
introdotto il supporto all'Atmega344

v. 1.0.0:
prima versione stabile. Introdotto anche un nuovo metodo per verificare lo stato di un task:
Code:
myOS.taskIsRunning(nomeFunzione)
Viene restituito PAUSED, SCHEDULED o ONETIME

v. 1.0.1:
introdotto un fix per eliminare il problema dell'overflow del contatore interno quando si usa la matematica a 32 bit permettendo, rispetto all'uso dei registri a 64 bit, una maggior compattezza del codice generato (diverse centinaia di byte in meno) senza il rischio di incorrere in comportamenti strani dopo 49,7 giorni.

v. 1.0.1a:
il metodo taskIsRunning è stato rinominato in getTaskStatus.


« Last Edit: October 28, 2012, 02:03:55 pm by leo72 » Logged


Arezzo, Toscana
Offline Offline
Jr. Member
**
Karma: 2
Posts: 99
Clones Must Die!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Forse sono riuscito a capire...
Con questa librera posso eseguire operazioni a ripetizione senza sfruttare il loop?
Quindi potrei utilizzare il loop per eseguire altre operazioni.

Bella idea! smiley-grin

Quote
Usa il timer 2 per gestire i task dell'utente e, ovviamente, fa perdere le funzionalità PWM sui pin 3 e 11.

Non so se ho capito bene qui...  Utilizzi un RTC?

Ciao e bel lavoro! smiley-wink
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 103
Posts: 6579
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Complimenti per il lavoro.
Ma se non ricordo male era stato creato un piccolo kernel anche da un'altro utente, credo per una tesi.  smiley-roll

EDIT: Leo, che differenze ci sono tra la tua libreria e questa? -->http://arduino.cc/playground/Code/TimedAction
« Last Edit: June 26, 2012, 05:21:29 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
Edison Member
*
Karma: 24
Posts: 2032
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mi sa che usa il timer interno di arduino  smiley-mr-green carino io quando non ho nulla da fare per lo più progetto,tu sei molto piu creativo  smiley-lol
Logged

"Due cose sono infinite: l'universo e la stupidità umana, ma riguardo l'universo ho ancora dei dubbi..." Albert Einstein

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 103
Posts: 6579
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

EDIT: Leo, che differenze ci sono tra la tua libreria e questa? -->http://arduino.cc/playground/Code/TimedAction

Mi rispondo da solo.
La TimedAction usa la funzione millis per stabilire l'intervallo di tempo e quindi eseguire il task.
La TimedAction viene bloccata in caso di delay.

La libreria di Leo invece usa un timer interno per richiamare la funzione puntata e quindi non è soggetta al resto del codice. Non si blocca quindi neanche durante un delay.

Una domanda: il timer2 potrebbe andare in conflitto con altre periferiche interne al micro, tipo I2C, SPI o Seriale?
« Last Edit: June 26, 2012, 05:40:47 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Arezzo, Toscana
Offline Offline
Jr. Member
**
Karma: 2
Posts: 99
Clones Must Die!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, gente, si è risolto il dubbio! smiley-cool
Logged

Monselice PD Italy
Offline Offline
Faraday Member
**
Karma: 25
Posts: 5480
фон Крыса
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Leo complimenti, ti stai superando, appena riesco lo provo smiley
Logged

Se corri veloce come un fulmine, ti schianterai come un tuono.

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Forse sono riuscito a capire...
Con questa librera posso eseguire operazioni a ripetizione senza sfruttare il loop?
Sì è scritta apposta per semplificare la stesura del loop ed evitare tutte quelle operazioni che spesso si eseguono usando millis().

Quote
Quindi potrei utilizzare il loop per eseguire altre operazioni.

Bella idea! smiley-grin
Nel loop ci va il programma principale.
I task che puoi far gestire a leOS sono operazioni ripetitive e semplici che però spesso ingarbugliano il codice, come ad esempio l'attivare un pin ogni tot.

Quote
Quote
Usa il timer 2 per gestire i task dell'utente e, ovviamente, fa perdere le funzionalità PWM sui pin 3 e 11.

Non so se ho capito bene qui...  Utilizzi un RTC?

Ciao e bel lavoro! smiley-wink
No. Il micro ha 3 contatori interni che si chiamano appunto timer. Il timer 0 viene usato da Arduino per la millis(), gli altri 2 sono liberi.
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Complimenti per il lavoro.
Ma se non ricordo male era stato creato un piccolo kernel anche da un'altro utente, credo per una tesi.  smiley-roll
Ce ne sono tanti. A parte quello da te citato, e che non ritrovo perché non mi ricordo neanche l'utente che lo pubblicò, c'è ad esempio FemtoOS, un RTOS moooooolto più sofisticato del mio. Il mio più che un RTOS è uno schedulatore, se vogliamo proprio dirla tutta perché non ha nessuno strumento degli RTOS per la gestione dei task. A cominciare dal fatto che non è un SO di tipo preemptive per cui se un task si blocca, si blocca tutta la baracca  smiley-lol
Ma siamo alla versione 0.0.1, io dico che qualcosa si può ancora fare  smiley-razz

Quote
EDIT: Leo, che differenze ci sono tra la tua libreria e questa? -->http://arduino.cc/playground/Code/TimedAction
Mi pare implementi i protothread e sceduli tutto con la millis().
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

mi sa che usa il timer interno di arduino  smiley-mr-green carino io quando non ho nulla da fare per lo più progetto,tu sei molto piu creativo  smiley-lol
Beh, ogni tanto mi passano queste bischerate per la testa  smiley-lol
Era qualche giorno che ci pensavo. Ieri pomeriggio a casa ho scritto il core centrale, poi a lavoro ieri sera ho fatto un po' di debug e le ultime cose le ho corrette stamattina.
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

EDIT: Leo, che differenze ci sono tra la tua libreria e questa? -->http://arduino.cc/playground/Code/TimedAction

Mi rispondo da solo.
La TimedAction usa la funzione millis per stabilire l'intervallo di tempo e quindi eseguire il task.
La TimedAction viene bloccata in caso di delay.

La libreria di Leo invece usa un timer interno per richiamare la funzione puntata e quindi non è soggetta al resto del codice. Non si blocca quindi neanche durante un delay.
Esatto. Come puoi vedere dall'esempio allegato, i 2 led pilotati dai 2 task continuano il loro lampeggio nonostante nel loop principale ci sia un delay per governare il lampeggio del 3° led.
Questo perché ho creato un contatore di ms interno al timer 2 ed uso quello per controllare il trascorrere del tempo.

Quote
Una domanda: il timer2 potrebbe andare in conflitto con altre periferiche interne al micro, tipo I2C, SPI o Seriale?
Io ho provato la stampa su seriale dopo aver aggiunto i 2 task ed ha funzionato. Però tutto quello che viene gestito da interrupt può influenzare il leOS, così come tutto quello che è gestito da interrupt si influenza attualmente. Pensa che la gestione dell'I2C è fatta via interrupt così come la seriale, eppure nessuno lo nota né si lamenta  smiley-wink
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Leo complimenti, ti stai superando, appena riesco lo provo smiley
Ma va, dai  smiley-sweat smiley-sweat
Logged


Offline Offline
Edison Member
*
Karma: 24
Posts: 2032
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mi sa che usa il timer interno di arduino  smiley-mr-green carino io quando non ho nulla da fare per lo più progetto,tu sei molto piu creativo  smiley-lol
Beh, ogni tanto mi passano queste bischerate per la testa  smiley-lol
Era qualche giorno che ci pensavo. Ieri pomeriggio a casa ho scritto il core centrale, poi a lavoro ieri sera ho fatto un po' di debug e le ultime cose le ho corrette stamattina.
Complimenti, bel lavoro.
Conosco questi "ingrippi" vengono spesso anche a me e finchè non relizzo la cosa che ho in testa non sto in pace con me stesso  smiley-mr-green
Logged

"Due cose sono infinite: l'universo e la stupidità umana, ma riguardo l'universo ho ancora dei dubbi..." Albert Einstein

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi ero dimenticato di dire una cosa, che non suonerà nuova a chi ha già dato un'occhiata al file .cpp.
L'OS dovrebbe girare su tutti i micro attualmente supportabili dall'IDE in maniera più o meno ufficiale, ossia gli Atmega8/88/168/328, i Mega1280/2560 (quindi girare anche sulle Arduino MEGA), i Tiny25/45/85 e 24/44/84, i Tiny2313/4313 ed i Mega644/1284.

Per mancanza di tempo NON ho potuto fare i test su nessun chip diverso dal 328 (ho usato la mia Arduino UNO) per cui se qualcuno ha voglia di provare, mi faccia sapere come va.  smiley-wink
Soprattutto sui Tiny sarebbe interessante sapere l'impatto in termini di prestazioni su micro con clock inferiori ai 16 MHz dell'Arduino.
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

PS:
vi svelo una cosa.... leOS non sta solo per "little embedded Operating System". Siccome sono molto egocentrico, è anche un gioco di parole sul mio nome "leo"  smiley-sweat smiley-sweat leoS però si capiva troppo, quindi ho scelto leOS.
Modesto, vero?  smiley-razz
Logged


Pages: [1] 2 3 ... 31   Go Up
Jump to: