Pages: 1 ... 21 22 [23] 24 25 ... 31   Go Down
Author Topic: leOS - un semplice OS per schedulare piccoli task  (Read 37368 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 329
Posts: 22770
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

con leOS il delay non influisce sui task, con looper influisce solo quando supera le tempistiche dei task (vediamo se leo mi bacchetta smiley)
In un certo senso è così.
All'atto pratico, ossia agli occhi di ciò che vede l'utente, l'unica differenza fra il leOS ed il looper pare essere appunto il non congelamento del looper rispetto al leOS. In realtà la differenza è molto più radicale. Il looper altro non è che una semplice che non fa altro che, quando viene richiamata, controllare se è passato l'intervallo di esecuzione di una funzione.
Con il leOS imposti un valore, allo scoccare del suo tempo il task in oggetto verrà eseguito. Punto.
Col looper puoi anche infilare dentro ad una funzione (non parliamo di task) delay e quant'altro. L'unica cosa che otterrai sarà il rallentamento generale ed il salto del tempo a cui erano stati programmati i richiami delle funzioni utente.

Quote
Io ho fato la tua stessa cosa del display con blinkwithout delay, prima che leo inventasse looper.
Ora mi chiedevo se e' piu' facile usare looper o il blinkwithout delay, leo che dici quale e' piu' intuitivo-userfriendly ?
Se devi eseguire 1 solo compito, puoi farlo col metodo del controllo del tempo basato su millis(), è ciò che fa il looper.
Se devi eseguire più di 1 compito, anche solo 2, allora il looper fa i controlli al posto tuo e tutto diventa semplificato. Immagina alla mole di if da inserire nel codice se devi ad esempio fare 10 azioni con tempistiche differenti.

Quote
Purtroppo ancora non e' stato inventato il "mio" mitico delay2() dove basterebbe scrivere delay2(1000) per avere un blinkwithoutdelay facile da usare.

Leo ma questa mi idea e' informaticamente irrealizzabile ?
Ma col leOS non hai più bisogno del delay2(1000).
Dimmi ad oggi dov'è il vantaggio di delay2(1000) quando fai un addTask(blink, 1000) ed hai risolto.  smiley-razz
Logged


Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

leo mi pare che leOS sia preemptive quindi sia possibile usare la delay(), giusto ?
No, nulla di tutto questo.  smiley-sweat
Il leOS semplicemente esegue una funzione richiamandola all'interno della ISR del timer 2 o del watchdog.
Il leOS è di tipo cooperativo, nel senso che il controllo allo scheduler viene reso dal task quando questo ha terminato la sua esecuzione. Quindi è una terminazione "volontaria".
Nei SO con prelazione (preemptive) quali FemtoOS, FreeRTOS ecc... è il SO che congela il task se questo è ancora in esecuzione terminato il tempo a sua disposizione.

Beh, mi sono espresso in modo un po' approssimativo, lo ammetto :-)
So bene che non si tratta di un OS né che è preeptive nel senso proprio del termine smiley
Tuttavia rispetto a robe come la SimpleTimer e tante altre simili che sono sostanzialmente la "librerizzazione" del blink without delay, ho notato che qui il task viene chiamato all'interno della timer2 ISR.
Con due blink task, uno ogni 1000ms e uno ogni 500ms, se in quest'ultimo metto un delay(1000) il lampeggio funziona comunque correttamente. Sembra quasi da alcuni esperimenti che delay() ritorni immediatamente...
Ma non voglio fare l'hijack del thread smiley-wink c'è un megatopic apposta per queste cose, vado a studiare smiley-grin

(edit: ma _siamo_ nel megatopic O_o )
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 329
Posts: 22770
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Tuttavia rispetto a robe come la SimpleTimer e tante altre simili che sono sostanzialmente la "librerizzazione" del blink without delay, ho notato che qui il task viene chiamato all'interno della timer2 ISR.
Sì i task sono richiamati all'interno della ISR, ecco perché dico sempre di farli il più snelli possibile, per non rallentare eccessivamente la CPU nell'esecuzione del codice principale.

Quote
Con due blink task, uno ogni 1000ms e uno ogni 500ms, se in quest'ultimo metto un delay(1000) il lampeggio funziona comunque correttamente. Sembra quasi da alcuni esperimenti che delay() ritorni immediatamente...
Non ho capito...  smiley-sweat

Quote
Ma non voglio fare l'hijack del thread smiley-wink c'è un megatopic apposta per queste cose, vado a studiare smiley-grin

(edit: ma _siamo_ nel megatopic O_o )
Sì, saremmo nel Megatopic  smiley-yell
Logged


Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Con due blink task, uno ogni 1000ms e uno ogni 500ms, se in quest'ultimo metto un delay(1000) il lampeggio funziona comunque correttamente. Sembra quasi da alcuni esperimenti che delay() ritorni immediatamente...
Non ho capito...  smiley-sweat

Non ho sotto mano una breadboard per fare delle prove con i led. Ho però uno shield con un LCD...

Code:
#include <leOS.h>
#include <LiquidCrystal.h>

leOS myOS;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);    // lcd pins for nuelectronics lcd+keypad shield
const short LCD_ROWS = 2;
const short LCD_COLS = 16;

//variables to control the LEDs
byte led1Status = 0;
byte led2Status = 0;
byte led3Status = 0;


void setup() {
    myOS.begin();
    lcd.begin(LCD_COLS, LCD_ROWS);
    lcd.clear();

    myOS.addTask(flashLed1, 500);
    myOS.addTask(flashLed2, 500);
}


//main loop
void loop() {
    lcd.setCursor(0, 0);
    lcd.print(led3Status ? '3' : ' ');
    led3Status ^= 1;   
    delay(1000);
}


//first task
void flashLed1() {
    lcd.setCursor(2, 0);
    lcd.print(led1Status ? '1' : ' ');
    led1Status^=1;
    delay(800);                // <<<<<<<<<<<<<<<< (*)
    lcd.setCursor(4, 0);
    lcd.print(led1Status ? '1' : ' ');
}


//second task
void flashLed2() {
    lcd.setCursor(6, 0);
    lcd.print(led2Status ? '2' : ' ');
    led2Status^=1;
}

Risultato:
A) il numero 3 in posizione 0, 0 lampeggia con T=2000

B) il numero 1 in posizione 2, 0 lampeggia con T=1000
C) il numero 1 in posizione 4, 0 lampeggia insieme a B), ma in controfase

D) il numero 2 in posizione 6, 0 lampeggia in fase con B, in controfase con C

Mi aspetterei invece che il delay (*) alterasse la frequenza dei lampeggi.
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 329
Posts: 22770
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sono a lavoro per cui anch'io non posso fare prove. Oggi a casa indagherò
Logged


0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

il mio problema è che devo aggiornare un display lcd, e lo vorrei fare non più velocemente di ogni secondo, perchè se no non si leggerebbe bene e non mi serve istantaneamente vedere le variazioni.
farò con il metodo blinkwithoutdelay, è una buona idea secondo te?

Secondo me la soluzione più semplice è quella di crearsi un buffer video e poi di riversare ogni xxx ms tale buffer sul display.
Cos'è un buffer video? E' una memoria tampone usata per scrivere le informazioni che poi devono essere visualizzate. Chi ha usato un Commodore ai tempi degli anni '80 sa di cosa parlo: lì esisteva una parte della RAM riservata alla memoria video suddivisa in 1024 byte per i dati e 1024 byte per gli attributi colore. L'utente poteva scrivere direttamente in quel buffer, era compito del chip video generare l'immagine video da spedire alla TV per la visualizzazione.
Tu puoi fare così, simulando appunto un buffer video in cui scrivi le tue informazioni.

Aggiungerei che nei sistemi moderni si usa un sistema a doppio buffer, uno si usa per disegnare e l'altro è quello che si manda al video. In questo modo piuttosto che inviare al video un'immagine mezza disegnata, si invia l'ultima immagine completa. Quando il buffer di disegno è completato, si mette il buffer di disegno nel buffer video e si può ricominciare a disegnare (in realtà la cosa si usa anche per semplificare un po' la gestione dei lock, normalmente il buffer video sulla scheda video, ed ad arginare eventuali picchi di "non cpu") .
Però se ho ben capito gli LCD possiedono questo buffer di disegno internamente, nel senso che se non ricevono nessun aggiornamento stampano l'ultima cosa inviata, ma non è il caso di TV e monitor
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Però se ho ben capito gli LCD possiedono questo buffer di disegno internamente

Una volta inviato un contenuto all'lcd, questo rimane visualizzato fino a nuovo ordine, quindi direi che il meccanismo è presente.
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

grazie dei consigli, però sia che aggiorni prima un buffer o che aggiorni direttamente il display leggendo i dati al momento, devo temporizzare comunque la print() sul display, quindi in pratica per la funzione per scrivere sul display devo per forza fare un controllo tipo il blinkwithoutdelay, o ho capito male?
Logged

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sì, devi fare attenzione a non superare con le print la velocità di refresh dell'LCD (o comunque le 30 vole al secondo) per evitare l'effetto sfarfallio
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 329
Posts: 22770
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@d407336:
sì, ovviamente i display LCD hanno il loro buffer (e non potrebbe essere altrimenti dato che devono mantenere i dati da visualizzare  smiley-wink) ma il vantaggio di un buffer software lato Arduino risiede nel fatto che non sei costretto a scrivere ogni singola modifica sul display ma aggiorni quest'ultimo solo ogni tot.

@tuxduino:
il seguente codice, che altro non è se non l'adattamento per l'uso coi LED del tuo sketch, blocca l'Arduino:
Code:
#include <leOS.h>

leOS myOS;


//variables to control the LEDs
byte led1Status = 0;
byte led2Status = 0;
byte led3Status = 0;
const byte LED1 = 7;
const byte LED2 = 8;
const byte LED3 = 9;

void setup() {
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
    pinMode(LED3, OUTPUT);
   
    myOS.begin();
    myOS.addTask(flashLed1, 500);
    myOS.addTask(flashLed2, 500);
}


//main loop
void loop() {
    digitalWrite(LED3, led3Status ? '3' : ' ');
    led3Status ^= 1;   
    delay(1000);
}


//first task
void flashLed1() {
    digitalWrite(LED1, led1Status ? '1' : ' ');
    led1Status^=1;
    delay(800);                // <<<<<<<<<<<<<<<< (*)
    digitalWrite(LED2, led1Status ? '1' : ' ');
}


//second task
void flashLed2() {
    digitalWrite(LED2, led2Status ? '2' : ' ');
    led2Status^=1;
}
Come fa a te a funzionare?
Logged


Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Come fa a te a funzionare?

E' quello che vorrei sapere anch'io  smiley-sweat

Può essere che c'entrino le chiamate all'lcd ? Non mi sembra un motivo plausibile a dire il vero, cmq stasera per scrupolo provo la tua versione con i led.
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

invece che aggiornare il buffer software ogni loop() non è più conveniente aggiornarlo solo nel momento in cui devo stamparlo sul display?
sul display devo stampare dei valori di alcune variabili e dei valori letti con analogRead(), quindi penso che sia inutile aggiornare di continuo il buffer, se poi lo stampo sul display solo una volta al secondo.
forse non ho capito quello che intendi?
Logged

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

certo, mai detto che il buffer lo fai ad ogni loop. il vataggio di avere i 2 buffer sotto mano, è anche quello di confrontarli, trovare le differenze ed aggiornare solo quelle. Il desktop KDE ha un bellissimo plugin che mostra di differenti colori le zone dello schermo in base a quando è stata l'ultima volta che è stata ridisegnata
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 329
Posts: 22770
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

invece che aggiornare il buffer software ogni loop() non è più conveniente aggiornarlo solo nel momento in cui devo stamparlo sul display?
sul display devo stampare dei valori di alcune variabili e dei valori letti con analogRead(), quindi penso che sia inutile aggiornare di continuo il buffer, se poi lo stampo sul display solo una volta al secondo.
forse non ho capito quello che intendi?
Come ha detto lesto, non devi aggiornare il display ad ogni loop.
Puoi farlo benissimo ogni tot, sarai tu a stabilire quanto far passare tra un aggiornamento ed il successivo.
Logged


Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 329
Posts: 22770
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Come fa a te a funzionare?

E' quello che vorrei sapere anch'io  smiley-sweat

Può essere che c'entrino le chiamate all'lcd ? Non mi sembra un motivo plausibile a dire il vero, cmq stasera per scrupolo provo la tua versione con i led.
Se parliamo della LiquidCrystal allegata all'IDE 1.0.2, gli ho dato un'occhiata ma non ho trovato cose eclatanti tipo manipolazioni dei timer od uso degli interrupt.
Logged


Pages: 1 ... 21 22 [23] 24 25 ... 31   Go Up
Jump to: