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

Io ho anche spocificato che a prescindere dal jump questa riga nella tua lib
//wdt_reset(); //<<<<<<<<<<<<<<<<<<<<QUESTA lo fa schiantare ancora prima di arrivare al ("jmp 0x000000"); e non è nemmo una questione di tempi secondi o ms, si blocca prima di arrivarci.
Questa riga serve per resettare il contatore del WDT. Diciamo che era una precauzione in più per disattivare completamente il watchdog. La sequenza completa era:
1) disattivazione globale di tutti gli interrupt (in modo da non avere nulla che bloccasse il resto del codice)
2) reset del timer del Watchdog
3) disattivazione del Watchdog

Dopo la tua segnalazione, ho tolto dalla lib "wdt_reset", che è l'istruzione che resettava il timer.

Quote
Però non hai risposto alla mia domanda, questo salto glielo fa fare il programma sulla flash o no?
A questo avevo risposto giorni fa:
Ok, ho in test uno sketch, appena termina carico il tuo.

Io lo avevo caricato per curiosità e ho notato il blocco, per la verità non so nemmeno a cosa serva  smiley-lol smiley-lol
Un po' come con le cose nuove, si spacchettano, si attacca la spina, si premono un po' di bottoni e poi si leggono le istruzioni  smiley-wink

ciao
E' una caratteristica secondo me molto interessante, che si può anche utilizzare in altri ambiti, ossia anche come semplice funzione anti-freeze (se uno non ha nessun task da far eseguire in background).

Nella sua essenza originale tale funzione serve a controllare se un task si sia bloccato. Ogni volta che il watchdog va in overflow viene lanciato un segnale di reset. La ruotine che intercetta il reset controlla se c'è un task in esecuzione. Se c'è, decrementa un contatore che rappresenta il timeout passato dall'utente in fase di setup. Se tale timeout va a zero prima che il task termini la sua esecuzione, significa che si è bloccato ed ha conseguentemente bloccato tutto il micro. A questo punto, il watchdog lancia un reset e pone fine al problema  smiley-wink

Però possiamo usarla anche come antiblocco del codice principale. Prendiamo ad esempio un task lanciato ogni secondo che controlla se una certa variabile di sistema è su un determinato valore. Se la trova ad esempio su false, la rimette a true ed esce mentre se la trova a true resetta il micro.
Nel loop principale l'utente la imposta a false ad ogni ciclo. Va da sé che se il loop si blocca, tale variabile non può essere impostata a false. Quindi il task di controllo, vedendola a true, resetta il micro.

Logged


Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3389
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Niente non va più, ho provato mettendo i define, togliendoli, usando 0x0000 opp 0x000000, lo stacca attacca resetta, incrocia le braccia mouse-reset mi ha sfinito  smiley-grin

ma __asm__ __volatile__ ("jmp 0x0000"); non dovrebbe resettare anche la tua scheda se nel tuo sketch metti define ....MEGA?  potresti provare se l'instradamento è corretto e le definizioni pure

Comunque la spiegazione che avevi dato
Quote
E' una caratteristica secondo me molto interessante, che si può anche utilizzare in altri ambiti, ossia anche come semplice funzione anti-freeze (se uno non ha nessun task da far eseguire in background).
l'avevo capita.
In qualche posto avevi spiegato che esiste un timer autonomo indipendente dai timer che controllano l'esecuzione dello sketch (se uso qualche termine scorretto chiedo venia), quindi se questo timer non viene azzerato in tempo va in overflow inviando un reset alla baracca.

Ora quello che non mi è chiaro è: se il controllo lo fai via software tramite librerie e si inchioda il software come può essere eseguito un reset. Da qualche parte attivi il controllo del timer "se TIMER WTD va in overflow" fammi un reset?

Quindi quello che ti ho chiesto prima è : "questo salto glielo fa fare il programma sulla flash tramite jump o lo fa il sistema autonomo?"
se usiamo un jump 0x0000 che è un comando software (soggetto a schianto e quindi non eseguito in caso di crash) perchè lo usiamo?

Non so se mi sono capito  smiley-eek

Inoltre visto che io non posso provarlo, tu hai mai provato a prendere un buffer e riempirlo di byte fino a quando l'MCU non è più in grado di gestirlo saturando la memoria, si dovrebbe inchiodare tutto, lo fa il reset?

Hai provato a simulare un problema di comunicazione sull ICSP di solito si inchioda, lo fa il reset?
 
« Last Edit: January 05, 2013, 08:35:50 am by pablos » Logged

no comment

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

Niente non va più, ho provato mettendo i define, togliendoli, usando 0x0000 opp 0x000000, lo stacca attacca resetta, incrocia le braccia mouse-reset mi ha sfinito  smiley-grin
Ti faccio una domanda. Hai scaricato uno zip oppure 2 file .cpp e .h singoli?
Perché ti chiedo questo? Perché avevo messo i 2 file modificati ma poi mi ero accorto di non aver messo un'istruzione ed ho rimodificato la lib. La nuova versione è contenuta in uno zip.

Quote
ma __asm__ __volatile__ ("jmp 0x0000"); non dovrebbe resettare anche la tua scheda se nel tuo sketch metti define ....MEGA?  potresti provare se l'instradamento è corretto e le definizioni pure
L'instradamento è corretto e jmp 0x0000 resetta il micro della mia Arduino. Il test l'avevo già fatto prima di pubblicare la nuova versione. Ho poi messo infatti anche l'azzeramento dello stato dei registri per i motivi che ti ho spiegato.
Però attendo che tu mi confermi se hai usato la lib zippata oppure no.

Quote
Ora quello che non mi è chiaro è: se il controllo lo fai via software tramite librerie e si inchioda il software come può essere eseguito un reset. Da qualche parte attivi il controllo del timer "se TIMER WTD va in overflow" fammi un reset?
Ok. Stiamo parlando di uno scheduler. Lo scheduler viene chiamato 1 volta ogni 16 ms circa e controlla se c'è un task da eseguire. Se c'è, lo lancia. Se invece c'è un task attivo, ne controlla lo stato. Se si accorge che un task è bloccato, inizia il conto alla rovescia di una variabile. Il valore di questa variabile è il timeout scelto dall'utente. Se il task non restituisce il controllo allo scheduler, si è piantato tutto per cui viene resettato il micro.
Come ti ho spiegato, puoi anche controllare tramite un task che il codice principale "giri" mettendo un flag. Se il flag resta su un dato valore per troppo tempo, il loop si è inchiodato.

Quote
Quindi quello che ti ho chiesto prima è : "questo salto glielo fa fare il programma sulla flash tramite jump o lo fa il sistema autonomo?"
se usiamo un jump 0x0000 che è un comando software (soggetto a schianto e quindi non eseguito in caso di crash) perchè lo usiamo?

Non so se mi sono capito  smiley-eek
 
Il jmp $0000 viene chiamato dallo scheduler in questa versione modificata. Nella leOS2 originale, invece, il reset hardware viene generato dal circuito del watchdog, che mette a LOW la linea di reset del microcontrollore. In questo caso si ha una vera reinizializzazione del micro, con il jmp $0000 si ha solo una ripartenza dall'inizio del programma.
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3389
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sisi avevo preso lo zip al « Reply #420 on: Today at 11:17:48 AM »

Facciamo così ... appena mi è possibile prendo un altro arduino e cambio il bootloader
« Last Edit: January 05, 2013, 08:59:15 am by pablos » Logged

no comment

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

sisi avevo preso lo zip al « Reply #420 on: Today at 11:17:48 AM »
OK

Quote
Facciamo così ... appena mi è possibile prendo un altro arduino e cambio il bootloader
Ultima prova. Sostituisci nel #define RESET_MCU che c'è all'inizio del file header l'istruzione __asm__ __volatile__ ("jump 0x000000");
con quella che avevi postato tu: ((void (*)())0x000000)();
Logged


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

@pablos:
hai fatto poi questo test?  smiley-sweat
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3389
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No Leo, lo faccio domani promesso smiley

ciao
Logged

no comment

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

Ok.
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3389
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eccomi, non è che mi ricordo molto di quello che avevo fatto...

Allora ricapitoliamo, ho preso l'ultimo zip e sostituito i 2 file nella cartella Leos2-2.2.0.

le linee originali leOS2.h
Code:
#define RESET_MCU SREG |= (1<<SREG_I);\
 wdt_disable();\
 DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;\
 DDRG = 0; DDRH = 0; DDRJ = 0; DDRK = 0; DDRL = 0; PORTA = 0;\
 PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;\
 PORTG = 0; PORTH = 0; PORTJ = 0; PORTK = 0; PORTL = 0;\
 EIND = 0;\
 __asm__ __volatile__ ("jmp 0x0000");
#else

deve diventare così.. giusto?
Code:
#define RESET_MCU SREG |= (1<<SREG_I);\
 wdt_disable();\
 DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;\
 DDRG = 0; DDRH = 0; DDRJ = 0; DDRK = 0; DDRL = 0; PORTA = 0;\
 PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;\
 PORTG = 0; PORTH = 0; PORTJ = 0; PORTK = 0; PORTL = 0;\
 EIND = 0;\
          
 ((void (*)())0x000000)();  
                                  //__asm__ __volatile__ ("jmp 0x0000");
#else

così si inchioda ancora  smiley-cry

« Last Edit: January 10, 2013, 04:54:47 pm by pablos » Logged

no comment

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

A parte che sto notando ora una cosa che non mi torna.
Questo è sbagliato:
Code:
SREG |= (1<<SREG_I)

Dovrebbe essere
Code:
SREG &= ~(1<<SREG_I)
Perché devo disattivare gli interrupt, non attivarli.
A parte ciò, pare quindi che neanche così si aggiri il bootloader della MEGA.
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3389
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Notavo che prima di fare il reset metti tutti i pin in INPUT e poi li azzeri tutti
Code:
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;\
DDRG = 0; DDRH = 0; DDRJ = 0; DDRK = 0; DDRL = 0; PORTA = 0;\
PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;\
PORTG = 0; PORTH = 0; PORTJ = 0; PORTK = 0; PORTL = 0;\

perchè lo fai?
Io ho uno shield sopra collegato a ICSP che col tuo sketch non lo impegno, ma alcuni pin fanno da enable/disable dello shield, mi sembra di aver letto anche che i 2 reset non sono contemporanei, uno dei 2 è leggermente ritardato rispetto all'altro, parliamo di quello HW. Inotre  quei DDR e PORT non inacasinano tutto prima di arrivare alla linea di reset?

ciao
« Last Edit: January 11, 2013, 05:10:07 am by pablos » Logged

no comment

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

Ricordati che il jmp $0000 NON è un reset, ma solo un riavvio del programma. Tutto il resto dell'integrato resta nello stato originale, comprese periferiche interne e pin esterni. Se tu hai qualcosa che viene inizializzato all'avvio dallo sketch, quel qualcosa mantiene lo stato in cui era quando hai chiamato il jmp.
Ecco perché resetto lo stato di tutti i pin prima di riavviare lo sketch, per riportarli allo stato flottante che hanno quando dai alimentazione alla scheda.
Logged


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

@pablos:
grazie a ibba abbiamo trovato un bootloader per la MEGA esente dal bug del WDT.
http://www.desert-home.com/2012/05/arduino-mega2560-wrapping-up-bootloader.html?m=1
Potresti provare a flasharlo sulla scheda ed a verificare se il leOS2 2.1.0 (quella pre-reset SW) funziona correttamente? Se va tutto liscio, aggiorno anche il mio sito e consiglio appunto il nuovo bootloader per le schede MEGA.
Logged


0
Online Online
Faraday Member
**
Karma: 46
Posts: 5857
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hai letto questo commmento sul sito da te indicato ?
Quote
AnonymousJanuary 2, 2013 2:28 AM
You can put a 470K resistor between the AREF and A1 to fix the watchdog timer issue.

Se e' vero e' utile per chi vuole lasciare la scheda con il BL originale
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

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

hai letto questo commmento sul sito da te indicato ?
Quote
AnonymousJanuary 2, 2013 2:28 AM
You can put a 470K resistor between the AREF and A1 to fix the watchdog timer issue.

Se e' vero e' utile per chi vuole lasciare la scheda con il BL originale
E come risolverebbe la cosa, questa R?
Logged


Pages: 1 ... 27 28 [29] 30 31   Go Up
Jump to: