Pages: 1 2 3 [4] 5 6 ... 8   Go Down
Author Topic: Ram+Seriale+Overflow  (Read 7399 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sarebbero da disassemblare i 2 firmware creati ma mi pare una cosa un po' pacco per un problema così banale, si mette unsigned long e siamo tutti felici  smiley-wink
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9172
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

leo ha testato questo con successo, quindi il casting avviene, bisognerebbe capire se esistono casi particolari

Non è vero che funziona, o meglio ti funziona su Arduino che non ti fa vedere le warning, se provi a compilare una cosa simile con AvrStudio ottieni subito una bella warning sul cast e una sulla if stessa, viene compilato lo stesso, ma è una forzatura e lo fai a tuo rischio e pericolo, ovvero poi non lamentarti se il programma fa cose strane  smiley
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9172
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

siete tutti bocciati per il semplice fatto che nell'embedded i cast NON si devono MAI fare!

In embedded il cast si usa eccome, anzi è uno degli strumenti messi a disposizione dal C e non c'è alcun motivo per non usarlo.
Ovviamente tocca ricordarsi di accendere il cervello quando si utilizza il cast perché è facile creare casini immensi se usato male, ma la stessa cosa si applica a maggior ragione ai puntatori, alle strutture/unioni etc.
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9172
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

mega rofl, adesso il Misra e' inutile perche' lo dice astro.

Dove direbbero le regole del MISRA C che non si deve usare il casting ? A me risulta che dicono come e quando deve essere impiegato il cast e quando non deve essere impiegato e che deve essere sempre esplicito, ovvero non usare mai il cast implicito dei compilatori che è una cosa ben diversa dal non usarlo in assoluto.
Logged

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ci mancava il troll di turno, ma questo e' sempre il solito ?
devo segnalarlo ai moderatori  smiley

tornando alla questione mi fa piacere che con un mio semplice esempio abbia montato tutta sta storia, quindi una domanda secca
- visto che non e' che vi seguo molto, nel senso che l'argomento e' per me difficile, usare nel mio esempio due unsigned long, sia per Time che per ScrollTime, evita problemi ? nel senso che l'overflow che comunque avverra' piu' in la nel tempo, non mi blocchera' lo scroll del display ?

il mio dubbio deriva da questo, cosi' come la INT diventa magicamente negativa e poi il cast fa casino, perche' non dovrebbe avvenire anche quando la unsigned long diventa negativa, il cast la inverte ecc ecc ?

non e' che si sposta solo il problema piu' avanti ?
« Last Edit: April 27, 2012, 01:41:17 pm by Testato » Logged

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

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ci mancava il troll di turno, ma questo e' sempre il solito ?
devo segnalarlo ai moderatori  smiley

ho segnalato il tuo intervento molesto ed  offensivo, oltre al fatto che e' detto a sproposito perche' ci sono tutta una serie di ragioni che non cito dietro all'intervento di prima, pero' tu mi hai confermato che ho fatto bene a cancellarlo segno che ho valutato per me non interessante ulteriori discussioni.
quote cautelativo:)
Logged

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

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

il mio dubbio deriva da questo, cosi' come la INT diventa magicamente negativa e poi il cast fa casino, perche' non dovrebbe avvenire anche quando la unsigned long diventa negativa, il cast la inverte ecc ecc ?

non e' che si sposta solo il problema piu' avanti ?

"unsigned" vuol dire proprio SENZA segno, come può diventare negativa?!
Logged

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

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

il dubbio mi viene perche' leo dice:

Usando l'unsigned int con il codice di Testato va in blocco dopo un po'

quindi credo sia lecito chiedersi chi mi tutela con unsigned long ?
infatti ho provato anche io, ed entrambi si bloccano,
con INT si blocca dopo una 30ina di secondi, e con UNSIGNED INT dopo 1 minuto.

se con unsigned long non si blocca vuol dire che c'e' un bug solo su int ed unsigned int ?

« Last Edit: April 27, 2012, 02:14:14 pm by Testato » Logged

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

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21269
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...
Usando l'unsigned int con il codice di Testato va in blocco dopo un po'
...
Questo effetto é logico perché un Unsigned int ha la possibilitá di memorizzare un numero positivo quasi 2 volte piú grande di un int. (16 bit contro 15 bit).
Ciai Uwe
Logged

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

...
Usando l'unsigned int con il codice di Testato va in blocco dopo un po'
...
Questo effetto é logico perché un Unsigned int ha la possibilitá di memorizzare un numero positivo quasi 2 volte piú grande di un int. (16 bit contro 15 bit).
Ciai Uwe
Appunto.
Logged


0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

appunto, ma non e' questo il punto  smiley

mi sembra che lesto dica che gli Unsigned, non avendo segno, dovrebbero regolarmente andare in overflow, e ripartire da zero, cosa che io mi aspettavo, invece non lo fa.
si incarta sia con int che con unsigned int, perche' con unsigned long non si blocca ?

Sia unsigned int che unsigned long vanno in overflow, se si comportano allo stesso modo dovrebbero :
- O funzionare entrambi, semplicemente andado in overflow in momenti diversi e ripartendo da zero
- Oppure bloccarsi entrambi nel momento dell'overflow, che capitera' in momenti diversi

l'attuale situazione invece e' che Unsigned Int blocca il codice all'overfow, Unsigned Long non lo blocca mai, nemmeno dopo l'overflow
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: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

appunto, ma non e' questo il punto  smiley

mi sembra che lesto dica che gli Unsigned, non avendo segno, dovrebbero regolarmente andare in overflow, e ripartire da zero, cosa che io mi aspettavo, invece non lo fa.
si incarta sia con int che con unsigned int, perche' con unsigned long non si blocca ?

Sia unsigned int che unsigned long vanno in overflow, se si comportano allo stesso modo dovrebbero :
- O funzionare entrambi, semplicemente andado in overflow in momenti diversi e ripartendo da zero
- Oppure bloccarsi entrambi nel momento dell'overflow, che capitera' in momenti diversi

l'attuale situazione invece e' che Unsigned Int blocca il codice all'overfow, Unsigned Long non lo blocca mai, nemmeno dopo l'overflow
E' il casting. Avevo ragione io. Ed anche lesto aveva visto bene con la storia del complemento a 2.

Ho usato questo codice:
Code:
unsigned long Tempo;
int  ScrollTime;
const byte LED=13;
boolean stato=true;
unsigned long secondi;

void setup () {
    delay(2000);
    pinMode(LED, OUTPUT);
    digitalWrite(LED, stato);
    Serial.begin(19200);
    Serial.println("Partito");
    secondi=seconds();
}

void loop () {
Tempo=millis();

    if (secondi!=seconds()) {
        secondi=seconds();
        Serial.println(ScrollTime + 300, DEC);
    }
    if (Tempo > ScrollTime + 300) {
        stato ^= true;
        digitalWrite(LED, stato);
        ScrollTime = millis();
    }
}

(usa la funzione seconds() che ho presentato alcuni giorni fa).
Dopo una trentina di secondi sul terminale compare SEMPRE il valore -32527.

Usando questo codice, con unsigned int ScrollTime si ha un risultato inatteso.
Code:
unsigned long Tempo;
unsigned int  ScrollTime;
const byte LED=13;
boolean stato=true;
unsigned long secondi;

void setup () {
    delay(2000);
    pinMode(LED, OUTPUT);
    digitalWrite(LED, stato);
    Serial.begin(19200);
    Serial.println("Partito");
    secondi=seconds();
}

void loop () {
Tempo=millis();

    if (Tempo > ScrollTime + 300) {
        Serial.println(ScrollTime, DEC);
        stato ^= true;
        digitalWrite(LED, stato);
        ScrollTime = millis();
    }
}
Dopo circa 60 secondi, durante i quali la stampa è cadenzata a circa 0,3s di intervallo, il codice arriva a passare 65535 (il max valore di un unsigned int) e sul terminale l'Arduino comincia a stampare TUTTI i valori di ScrollTime. In pratica entra infinite volte nel ciclo, dando l'apparenza di essere bloccato (perché il Led è acceso fisso) ma in realtà ne cambia lo stato talmente in fretta che l'occhio umano non riesce a distinguere il passaggio.
Logged


0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Confermo i due test, invece del led ho usato lo scroll di un display, con int si blocca e con unsigned int lo scroll parte a razzo ed il display e' illeggibile.

Non ho capito ancora se questi comportamenti sono normali, e perché con unsigned long non capita.

3 variabili, 3 comportamenti diversi in zona overflow
Logged

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

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, mi avete fatto tirare fuori l'arduino.

Prima di tutto una cosa che centra nulla ma volevo testare:

con Serial.print(' '); lo skecth misura 2888byte: invece con Serial.print(" "); misura 2896 byte! quindi se scrivete un solo carattere privilegiate l'apice singolo!
certo una differenza di 8byte è tanta.. bha

comunque le sto provando tutte e effettivamente non riesco a capire cosa diavolo succeda.

il mio test per ora... ora proseguo per capire se per caso c'è una flag(o bug) assegnata ad ogni variabile che ne identifica l'overflow e rende sempre veri gli if

Code:
unsigned long Tempo;
unsigned int  ScrollTime;
const byte LED=13;
boolean stato=true;
unsigned long tempo2;
unsigned int *p;

void setup () {
    delay(2000);
    pinMode(LED, OUTPUT);
    digitalWrite(LED, stato);
    Serial.begin(115200);
    Serial.println("Partito");
}

void loop () {
  Tempo=millis();

    if (Tempo > (unsigned long)(ScrollTime + 50)) {
      tempo2 = ScrollTime+50;
//      ScrollTime = tempo2;
/*
      Serial.print(tempo2, DEC);
      Serial.print(' ');
      Serial.print(tempo2, BIN);
      Serial.print(' ');

      Serial.print(ScrollTime + 50, DEC);
      Serial.print(' ');
      Serial.print(ScrollTime + 50, BIN);
      Serial.print(' ');
      */
      Serial.print(ScrollTime, DEC);
      Serial.print(' ');
      Serial.print(ScrollTime, BIN);
      Serial.print(' ');
      Serial.print(Tempo, DEC);
      Serial.print(' ');
      Serial.print(Tempo, BIN);
      /*
      p = (unsigned long *)&Tempo;
      Serial.print(' ');
      Serial.print( (*p), BIN);
      tempo2 = Tempo;
      Serial.print(' ');
      Serial.print(tempo2, DEC);
      Serial.print(' ');
      Serial.print(tempo2, BIN);
      */
      p = &ScrollTime;
      Serial.print('p');
      Serial.print( (*p), BIN);

      p = &ScrollTime+1;
      Serial.print('+');
      Serial.print( (*p), BIN);

      p = &ScrollTime-1;
      Serial.print('-');
      Serial.print( (*p), BIN);
     
     
      unsigned long *a;
      p = &ScrollTime;
      a = (unsigned long *)p;
      Serial.print('a');
      Serial.print( (*a), BIN);
      p-=sizeof(unsigned long);
      p+=sizeof(unsigned int);     
      a = (unsigned long *)p;
      Serial.print('A');
      Serial.print( (*a), BIN);
      Serial.print('A');
      Serial.print( (*a), DEC);
     
      p = &ScrollTime;
      p+=sizeof(unsigned long);
      p-=sizeof(unsigned int);     
      a = (unsigned long *)p;
      Serial.print('B');
      Serial.print( (*a), BIN);
      Serial.print('B');
      Serial.print( (*a), DEC);
     
      if ((*a) < 135593984){
        (*a)=135593984;
      }
     
      Serial.println();
      /*
      if (Tempo > 70000L){
        while(1);//stop!!
      }
      */
      stato ^= true;
      digitalWrite(LED, stato);
      ScrollTime = millis();
    }
}
Logged

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

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

altro test più "barbaro":
Code:
unsigned long Tempo;
unsigned int  ScrollTime;
const byte LED=13;
boolean stato=true;
unsigned long secondi;

void setup () {
    delay(2000);
    pinMode(LED, OUTPUT);
    digitalWrite(LED, stato);
    Serial.begin(19200);
    Serial.println("Partito");
}

void loop () {
    Tempo+=1;

    if (Tempo > ScrollTime + 300) {
        Serial.println(ScrollTime, DEC);
        stato ^= true;
        digitalWrite(LED, stato);
        ScrollTime = Tempo;
    }
}


e la parte incriminata:
Code:
64715
65016
65317
65318
65319
65320
65321
65322
65323
65324
65325
65326
65327
65328
65329
65330
65331
65332
65333
65334
65335
65336
65337
65338
65339
da li in poi tutto procede al peggio.

con
Code:
unsigned long Tempo;
unsigned int  ScrollTime;
const byte LED=13;
boolean stato=true;
unsigned long secondi;

void setup () {
    delay(2000);
    pinMode(LED, OUTPUT);
    digitalWrite(LED, stato);
    Serial.begin(19200);
    Serial.println("Partito");
}

void loop () {
    Tempo+=1;

    if (Tempo >= ScrollTime + 300) {
      Serial.print('S');
        Serial.println(ScrollTime, DEC);
        Serial.println(Tempo, DEC);
        stato ^= true;
        digitalWrite(LED, stato);
      Serial.print('T');
        Serial.println((Tempo - (ScrollTime + 300)), DEC);
        if (Tempo - ScrollTime < 300){
          Serial.println("azz");
        }
        ScrollTime = Tempo;
    }
}

mi sono accorto che è proprio la matematica ad essere sbagliata!

quando entriamo nell'if, in teoria (Tempo - (ScrollTime + 300) dovrebbe essere sempre = 0 salvo overflow.
da 0 a 65400 tutto ok, a 65401 (valore alquanto bizzarro) l'operazione da SEMPRE 65237 come risultato.

notare che l'if Tempo - ScrollTime < 300 però è corretto, per via del cast "fatto giusto"


ogni idea che mi viene in mente si schianta su quel 65401.
Logged

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

Pages: 1 2 3 [4] 5 6 ... 8   Go Up
Jump to: