Forum Moderator
Italy
Online
Brattain Member
Karma: 219
Posts: 16546
Don't know what I do
|
 |
« Reply #225 on: September 12, 2012, 05:45:45 pm » |
Il weekday ?  No!  Bel lavoro  Grazie.  Sono quel genere di cose che si fanno per passare il tempo.... 
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 219
Posts: 16546
Don't know what I do
|
 |
« Reply #226 on: September 16, 2012, 04:37:38 am » |
Ho aggiornato il leOS alla versione 0.1.3. Ho aggiunto un paio di sketch di esempio per mostrare le funzionalità di questo scheduler nonché ho aggiunto una nuova funzionalità: la possibilità di aggiungere un task in modalità "pausa", che non viene cioè eseguito immediatamente dopo l'aggiunta ma solo quando l'utente lo riattiva esplicitamente col metodo restartTask(). Questa funzionalità è a mio avviso molto utile per aggiungere ad esempio un task che possa manifestare immediatamente la sua attività, ad esempio pilotando un LED o un transistor. Ciò si può ottenere aggiungendo la parola chiave PAUSED ai parametri passati al metodo addTask. Esempio: myOS.addTask(funzione, intervallo, PAUSED); Per avviare il task basta dare: myOS.restartTask(funzione); quando lo si ritiene opportuno. Ricordo che la sintassi di addTask è: addTask(nomeFunzione, intervallo[, stato]) stato è opzionale e può assumere 3 valori predefiniti: PAUSED: per aggiungere un task con esecuzione sospesa SCHEDULED: opzione di default, aggiunge un task con esecuzione attiva ONETIME: aggiunge un task attivo da eseguire solo 1 volta Uno dei 2 nuovi sketch di esempio serve a mostrare la nuova funzionalità. L'altro mostra invece una cosa carina che può fare il leOS, ossia attivare/disattivare un task da un altro task. N.B.: Il leOS 0.1.3 è disponibile da adesso solo sul mio sito. Ho tolto il download dal 1° post del thread per avere un contatore globale dei download e perché spesso mi dimenticavo di aggiornare il pacchetto su uno dei 2 posti dov'era pubblicato (il forum o il mio sito).
|
|
|
|
|
Logged
|
|
|
|
|
Sicily
Offline
Newbie
Karma: 0
Posts: 48
|
 |
« Reply #227 on: September 17, 2012, 08:06:46 am » |
Ciao Leo
complimenti per l'ottima libreria
leggendo un po tutto il thread e le info postate da te ho visto che usi il timer2 per far funzionare la tua libreria,
io ho fatto un test ho utilizzato l'esempio lesos2task con i tre led a questo ho aggiunto un task che dovrebbe colleagarsi ad un sensore colleato attraverso il protocollo i2c e inviare il risultato sulla serieale.
lo sketch si carica ma si blocca subito al primo ciclo
mi chieso se pure l'I2C si basa sul timer2 io possiedo un arduino mega e mi chiedevo se potevo far funzionare il leos con il timer4 e constatare il funzionamento
inoltre non sarebbe carico far scegliere all'utente quali timer far utilizzare?!
che dritta potresti darmi per risolvere il mio problema :-) :-P di sicuro sbaglio qualcosa....
ti ringrazio in anticipo e complimenti per il lavoro ben fatto
saluti
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 219
Posts: 16546
Don't know what I do
|
 |
« Reply #228 on: September 17, 2012, 09:37:35 am » |
Ciao Leo
complimenti per l'ottima libreria
leggendo un po tutto il thread e le info postate da te ho visto che usi il timer2 per far funzionare la tua libreria,
La libreria si basa su un timer del microcontrollore. Sull'Atmega328 uso il timer 2 perché è un timer ad 8 bit e mi risulta facile gestirlo dato che si manipola 1 registro contatore da 8 bit al posto di quelli a 16 bit del timer 1. Il timer 0, anch'esso ad 8 bit, è usato dall'Arduino per la funzione millis(). Su altri microcontrollori uso i timer che sono disponibili. io ho fatto un test ho utilizzato l'esempio lesos2task con i tre led a questo ho aggiunto un task che dovrebbe colleagarsi ad un sensore colleato attraverso il protocollo i2c e inviare il risultato sulla serieale.
lo sketch si carica ma si blocca subito al primo ciclo
mi chieso se pure l'I2C si basa sul timer2
L'I2C sul 328 e sul Mega2560 è integrato nell'hardware ma è gestito da un'interfaccia software basata sugli interrupt. Se tenti di leggere o spedire dati via I2C da dentro ad un task, è normale che si blocchi tutto perché ogni task viene eseguito all'interno dell'ISR (Internet Service Routine) che viene attivata dall'overflow del contatore del timer ed ogni ISR è atomica, ossia non può essere interrotta da un'altra ISR. Parlo però per ipotesi perché senza analizzare il codice non so esattamente cosa stai facendo. io possiedo un arduino mega e mi chiedevo se potevo far funzionare il leos con il timer4 e constatare il funzionamento
Sul Mega2560 uso il timer 2. Hai qualche particolare necessità per dover usare il timer 4? inoltre non sarebbe carico far scegliere all'utente quali timer far utilizzare?!
Carina come idea ma non so se hai dato un'occhiata al file leos.cpp, nella parte finale. La funzione setTimer() imposta i timer e, come vedi, non è proprio stato semplice trovare i valori giusti per impostare tutti i registri per impostare i timer  Spostare poi lo scheduler su un altro timer cambia poco, sempre un timer perdi. che dritta potresti darmi per risolvere il mio problema :-) :-P di sicuro sbaglio qualcosa....
Beh, intanto posta il codice per capire dove sta il problema  ti ringrazio in anticipo e complimenti per il lavoro ben fatto
saluti
Grazie a te per l'interesse
|
|
|
|
|
Logged
|
|
|
|
|
Sicily
Offline
Newbie
Karma: 0
Posts: 48
|
 |
« Reply #229 on: September 17, 2012, 10:43:11 am » |
ciao Leo ecco il codice con cui stavo facendo i test http://pastebin.com/7LX1dFDZthanks in anticipo
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 219
Posts: 16546
Don't know what I do
|
 |
« Reply #230 on: September 17, 2012, 01:08:23 pm » |
E' come pensavo. Hai messo l'uso dell'I2C all'interno di un task, è per questo che ti si blocca. Anche la Serial non va bene gestirla in un task. In un task devono starci operazioni computazionalmente poco gravose o che utilizzino l'HW in maniera diretta. Hai 2 strade: 1) rivedi il codice facendo in modo di lasciare al di fuori del 3° task tutto quello che utilizza interrupt, oppure 2) provi ad usare il looper: è uno schedulatore software. Puoi ovviamente intervallare l'esecuzione dei task anche se perdi in precisione assoluta nella loro esecuzione ma dentro ad un task puoi infilarci tutto quello che ti pare, dato che si tratta in pratica di una semplice funzione che richiama altre funzioni eseguita all'interno del loop principale.
|
|
|
|
|
Logged
|
|
|
|
|
Sicily
Offline
Newbie
Karma: 0
Posts: 48
|
 |
« Reply #231 on: September 17, 2012, 03:37:00 pm » |
E' come pensavo. Hai messo l'uso dell'I2C all'interno di un task, è per questo che ti si blocca. Anche la Serial non va bene gestirla in un task. In un task devono starci operazioni computazionalmente poco gravose o che utilizzino l'HW in maniera diretta.
non ci sarebbe un modo per gestire I2C(e la Serial) in maniera diretta? Hai 2 strade: 1) rivedi il codice facendo in modo di lasciare al di fuori del 3° task tutto quello che utilizza interrupt, oppure 2) provi ad usare il looper: è uno schedulatore software. Puoi ovviamente intervallare l'esecuzione dei task anche se perdi in precisione assoluta nella loro esecuzione ma dentro ad un task puoi infilarci tutto quello che ti pare, dato che si tratta in pratica di una semplice funzione che richiama altre funzioni eseguita all'interno del loop principale. le due soluzioni che giustamente hai sottolineato le ho provate entrambe ed ovviamente funzionano se dovessi optare per il looper non ci sarebbe un modo anche utilizzando un RTc esterno per migliorare la precisione dell'esecuzione dei task? scusami per tutte queste domande :-P grazie per le delucidazioni
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 83
Posts: 8243
:(){:|:&};:
|
 |
« Reply #232 on: September 17, 2012, 03:57:33 pm » |
forse si può usare in maniera diretta, ma bisogna modificare pesantemente le librerie per renderle non bloccanti. E' un lavoro con cui mi sono cimentato, funziona ma sarebbe da riscrivere per essere fatto apposta e non un brutale hack, devi sostituire la libreria originale Wire e sottocartella utils con questo codice https://github.com/lestofante/arduinoSketch/tree/master/asincI2Ctest2_asinc, trovi anche un esempio di utilizzo.
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 219
Posts: 16546
Don't know what I do
|
 |
« Reply #233 on: September 17, 2012, 04:26:17 pm » |
non ci sarebbe un modo per gestire I2C(e la Serial) in maniera diretta?
Ti ha risposto lesto. Effettivamente ha modificato tempo fa la Wire per renderla non bloccante. Ma qui lascio a lui la parola perché non ho seguito il progetto. se dovessi optare per il looper non ci sarebbe un modo anche utilizzando un RTc esterno per migliorare la precisione dell'esecuzione dei task?
Tutto dipende da cosa fa il tuo loop. Mi spiego: se programmi un intervallo di 500 ms tra un'esecuzione e l'altra, il task prende 50 ms ed il loop 100 ms, hai un tempo di esecuzione di 150 ms su un intervallo di 500 ms. Quindi sei a posto: il tuo task sarà sempre eseguito secondo quanto stabilito. Ma se mettiamo che tu abbia programmato un intervallo di 100 ms, allora il tuo task sarebbe eseguito sempre con 50 ms di ritardo. E' in questo che difetta il looper dal leOS. scusami per tutte queste domande :-P
grazie per le delucidazioni
Figurati.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 6
Posts: 462
|
 |
« Reply #234 on: September 18, 2012, 11:26:21 am » |
non per sminuire il lavoro di leo(nell'80% dei casi va più che bene  ),ma se hai esigenze particolari ti direi di cercare "freertos arduino"..è un SO minimale realtime per arduino..e direi che puoi farci cose avanzate..
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 219
Posts: 16546
Don't know what I do
|
 |
« Reply #235 on: September 18, 2012, 11:40:42 am » |
E' vero, ci sono tanti RTOS in circolazione che funzionano molto meglio del leOS... ma a che prezzo? Avete dato un'occhiata alla complessità del codice necessario per fare un semplice blink, ad esempio con freeRTOS? Posto il codice di UNOBlink: //////////////////////////////////////////////////////// //////////////////////////////////////////////////////// //// main.c //////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
#include <stdlib.h> #include <stdbool.h> #include <string.h>
#include <avr/io.h>
/* Scheduler include files. */ #include <FreeRTOS.h> #include <task.h> #include <queue.h> #include <semphr.h>
/* serial interface include file. */ #include <lib_serial.h>
/* LCD (Freetronics 16x2) interface include file. */ #include <hd44780.h>
/*-----------------------------------------------------------*/ /* Create a handle for the serial port. */ xComPortHandle xSerialPort;
static void TaskBlinkRedLED(void *pvParameters); // Main Arduino Mega 2560, Freetronics EtherMega (Red) LED Blink
static void TaskBlinkGreenLED(void *pvParameters); // Main Arduino Uno 328p (Green) LED Blink /*-----------------------------------------------------------*/
/* Main program loop */ int16_t main(void) __attribute__((OS_main));
int16_t main(void) {
// turn on the serial port for debugging or for other USART reasons. xSerialPort = xSerialPortInitMinimal( 115200, portSERIAL_BUFFER, portSERIAL_BUFFER); // serial port: WantedBaud, TxQueueLength, RxQueueLength (8n1)
avrSerialPrint_P(PSTR("\r\n\n\nHello World!\r\n")); // Ok, so we're alive...
xTaskCreate( TaskBlinkRedLED , (const signed portCHAR *)"RedLED" // Main Arduino Mega 2560, Freetronics EtherMega (Red) LED Blink , 256 // Tested 9 free @ 208 , NULL , 3 , NULL ); // */
xTaskCreate( TaskBlinkGreenLED , (const signed portCHAR *)"GreenLED" // Main Arduino Uno 328p (Green) LED Blink , 256 // Tested 9 free @ 208 , NULL , 3 , NULL ); // */
avrSerialPrintf_P(PSTR("\r\n\nFree Heap Size: %u\r\n"),xPortGetFreeHeapSize() ); // needs heap_1 or heap_2 for this function to succeed.
vTaskStartScheduler();
avrSerialPrint_P(PSTR("\r\n\n\nGoodbye... no space for idle task!\r\n")); // Doh, so we're dead...
}
/*-----------------------------------------------------------*/
static void TaskBlinkRedLED(void *pvParameters) // Main Red LED Flash { (void) pvParameters;; portTickType xLastWakeTime; /* The xLastWakeTime variable needs to be initialised with the current tick count. Note that this is the only time we access this variable. From this point on xLastWakeTime is managed automatically by the vTaskDelayUntil() API function. */ xLastWakeTime = xTaskGetTickCount();
int8_t i; uint8_t j;
lcd_Init();
DDRB |= _BV(DDB7);
while(1) {
PORTB |= _BV(PORTB7); // main (red IO_B7) LED on. EtherMega LED on vTaskDelayUntil( &xLastWakeTime, ( 10 / portTICK_RATE_MS ) );
lcd_Locate (0, 0); lcd_Printf_P(PSTR("HighWater @ %u"), uxTaskGetStackHighWaterMark(NULL)); lcd_Cursor (1);
#if _USE_FUEL lcd_Locate (1, 0); lcd_PutFuel (--i, 0); if (i < 0) i = 6; #endif
#if _USE_BAR lcd_Locate (1, 2); lcd_PutBar (j++, 14, 2); #endif
PORTB &= ~_BV(PORTB7); // main (red IO_B7) LED off. EtherMega LED off vTaskDelayUntil( &xLastWakeTime, ( 40 / portTICK_RATE_MS ) );
// xSerialPrintf_P(PSTR("RedLED HighWater @ %u\r\n"), uxTaskGetStackHighWaterMark(NULL)); }
}
/*-----------------------------------------------------------*/ static void TaskBlinkGreenLED(void *pvParameters) // Main Green LED Flash { (void) pvParameters;; portTickType xLastWakeTime; /* The xLastWakeTime variable needs to be initialised with the current tick count. Note that this is the only time we access this variable. From this point on xLastWakeTime is managed automatically by the vTaskDelayUntil() API function. */ xLastWakeTime = xTaskGetTickCount();
DDRB |= _BV(DDB5);
while(1) { PORTB |= _BV(PORTB5); // main (red PB5) LED on. Arduino LED on vTaskDelayUntil( &xLastWakeTime, ( 100 / portTICK_RATE_MS ) );
PORTB &= ~_BV(PORTB5); // main (red PB5) LED off. Arduino LED off vTaskDelayUntil( &xLastWakeTime, ( 400 / portTICK_RATE_MS ) );
xSerialPrintf_P(PSTR("GreenLED HighWater @ %u\r\n"), uxTaskGetStackHighWaterMark(NULL)); } } /*-----------------------------------------------------------*/
Questo è il codice di leOS_BlinkWithoutMillis: //include the OS #include "leOS.h"
leOS myOS; //create a new istance of the class leOS
//variables to control the LEDs byte led1Status = 0; const byte LED1 = 13;
//program setup void setup() { myOS.begin(); //initialize the scheduler pinMode(LED1, OUTPUT); //add the tasks at the scheduler myOS.addTask(flashLed1, 1000); }
//main loop void loop() { //empty }
//flashing task void flashLed1() { led1Status^=1; digitalWrite(LED1, led1Status); }
leOS è limitato ma è semplicissimo da usare.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 6
Posts: 462
|
 |
« Reply #236 on: September 18, 2012, 12:35:42 pm » |
son d'accordo che non è facilissimo da implementare..anche se per la maggior parte dei casi basta un po' di copia e incolla..
dipende dalle tue necessità: se hai bisogno di avere tempi precisi con funzioni che usano interrupt,puoi o usare leOS + wire non bloccante(xò se tu volessi anche usare la seriale?),o RTOS.. altrimenti usi il looper,è semplice da usare,non ha problemi con interrupt,ma non garantisce tempi brevi..
|
|
|
|
« Last Edit: September 18, 2012, 12:43:22 pm by m_ri »
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 219
Posts: 16546
Don't know what I do
|
 |
« Reply #237 on: September 18, 2012, 02:59:09 pm » |
In tanti anni che programmo ho imparato una cosa, che cioè il risultato ottimale è quello che ha il miglior rapporto prezzo/prestazioni. Fare un codice semplicistico comporta un costo in termini di impegno di progettazione veramente minimo ma, per contro, hai prestazioni anch'esse minime. L'altra faccia della medaglia è un codice esageratamente ricercato, con un costo di progettazione molto elevato e prestazioni anch'esse al top. Alla fine, il risultato finale è identico: ognuno dei due programmi eseguirà il compito assegnato.
Vale la pena usare freeRTOS o FemtoOS per modificare un paio di porte in background? Non credo proprio. Vale la pena usare il leOS per gestire un multitasking preemptivo? Non credo proprio. Come dici giustamente tu, ognuno deve scegliere gli strumenti pensando al miglior rapporto per il proprio progetto.
|
|
|
|
|
Logged
|
|
|
|
|
Sicily
Offline
Newbie
Karma: 0
Posts: 48
|
 |
« Reply #238 on: September 19, 2012, 04:39:48 pm » |
ragazzi scusate la mia assenza, dopo diversi test ecco i primi risultati:
ho utilizzato le librerie: 1. leos 2. asincI2Ctest2_asinc (non bloccante)
devo dire che questa accoppiata funziona egregiamente.
La semplicità della realizzazzione dei task di leo, e l'utilizzo asincrono della wire di lesto possono dare nuovi spunti a chi vuole realizzare sitemi anche complessi.
In questi giorni ho avuto modo di studiare e testare anche i sistemi RTOS (chibios e freertos), questi ultimi nonostante le loro caratteristiche importanti che si basano sui sistemi operativi real time, non risultano essere semplici nell'utilizzo, inoltre come accennato anche da leo ad esempio per scrivere un banale blick_led bisogna scrivere ben 4 volte il numero di righi di codice rispetto all'esempio di leos.
Certo ancora manca da implementare semafori, code ed altre logiche... ecc ecc A mio avviso già questo è un passo avanti ed il lavoro di leos non ha nulla da invidiare ai sistemi RTOS
questo è il mio umile giudizio
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 219
Posts: 16546
Don't know what I do
|
 |
« Reply #239 on: September 19, 2012, 06:01:34 pm » |
Certo ancora manca da implementare semafori, code ed altre logiche... ecc ecc A mio avviso già questo è un passo avanti ed il lavoro di leos non ha nulla da invidiare ai sistemi RTOS
questo è il mio umile giudizio
 Grasssie PS: sto usando il leOS su un Attiny85, è un progettino a cui sto lavorando da 2 giorni a questa parte (ecco perché sono un po' latitante, oltre agli impegni di lavoro): 3 task che fermo e riavvio, con intervalli differenti, abbinati alla gestione di un segnale PWM, a 2 letture analogiche e sleep/risveglio. E funziona tutto perfettamente. Siccome i 3 task dovevano girare "intrecciati" tra di loro e con il resto del codice, l'uso del leOS mi ha semplificato non poco la stesura del codice.
|
|
|
|
|
Logged
|
|
|
|
|
|