Go Down

Topic: [MAC] Aggiornamento IDE 1.0x all'ultima versione Atmel Toolchain (Read 39089 times) previous topic - next topic

nid69ita

#30
Sep 06, 2013, 05:16 pm Last Edit: Sep 06, 2013, 09:06 pm by nid69ita Reason: 1
Mettendo static in quella funzione il warning di ignorato progmem sparisce
Code: [Select]
size_t Print::print(const __FlashStringHelper *ifsh)
{ static const char PROGMEM *p = (const char PROGMEM *)ifsh; // qui static
  size_t n = 0;
  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    n += write(c);
  }
  return n;
}

ma appare:
Code: [Select]
H:\Arduino\ArduinoERW105\hardware\arduino\cores\arduino\Print.cpp:44: warning: only initialized variables can be placed into program memory area
my name is IGOR, not AIGOR

gpb01

Che indendoi per "mettendo static" ??? Dove ???

Cortesemente riportiamo sempre il codice completo ... altrimenti è impossibile fare delle prove congrue tutti assieme ;)

E comunque ... se vogliamo essere sicuri che la variabile venga messa VERAMENTE nella PROGMEM ... dobbiamo trovare il modo di far scomparire quel warning :)

Guglielmo

P.S. : Anche perché, risolto quello, ho idea che ne risolveremo altri simili, in altri punti, mano mano che compariranno ;)
Search is Your friend ... or I am Your enemy !

gpb01

Per inciso Leo, ho provato a modificare quella tua riga così :

Code: [Select]
//const char PROGMEM *p = (const char PROGMEM *)ifsh;
PROGMEM PGM_P p = (PROGMEM PGM_P)ifsh;


... la compilazione va a buon fine (come prevedibile) ma rimane questo warning :

Code: [Select]
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.cpp: In member function 'size_t Print::print(const __FlashStringHelper*)':
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.cpp:45:17: warning: '__progmem__' attribute ignored [-Wattributes]


... ora, puoi verificare (... magari disassemblando il codice) se comunque, nonostante il warning, la stringa viene prelevata dalla Flash e non dalla RAM in fase di esecutione ???  Perché, in caso affermativo, diventerebbe un "warning trascurabile" ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

leo72

Secondo me non cambia molto, PGM_P dovrebbe essere un alias per "const char *", quindi è senza PROGMEM. Compila senza warning perché appunto non usa l'attributo __progmem__.
Se aggiungi PROGMEM, torni alla condizione iniziale, ossia riottieni esattamente la linea di codice inizialmente commentata, per cui torna fuori il warning.

gpb01


Secondo me non cambia molto, PGM_P dovrebbe essere un alias per "const char *", quindi è senza PROGMEM. Compila senza warning perché appunto non usa l'attributo __progmem__.
Se aggiungi PROGMEM, torni alla condizione iniziale, ossia riottieni esattamente la linea di codice inizialmente commentata, per cui torna fuori il warning.


Si, Si, quello lo avevo visto ...
... quello che ti chiedevo se magari potevi dare un'occhiata al codice compilato e ... riuscire a capire se comunque usava la PROGMEM (... e quindi era un warning trascurabile) o meno (... e quindi era un vero problema) ;)

Grazie,

Guglielmo

P.S. : Ho già effettuato anche io il disassembleggio con avr-objdump ma ... sono piuttosto arruginito con l'assembler e, di sicuro, non conosco quello Atmel di questi micro ...  :smiley-mr-green:
Search is Your friend ... or I am Your enemy !

leo72

Non lo conosco neanche io così a fondo, cosa credi  ;)
Ci darò un'occhiata...  :D

gpb01


Non lo conosco neanche io così a fondo, cosa credi  ;)
...


SICURAMENTE più di me  :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:

Guglielmo

P.S. : Parlassimo di quello Intel x86 sarebbe un'altra cosa ... ;)
Search is Your friend ... or I am Your enemy !

leo72

Compilando con la mia modifica:
Code: [Select]
PGM_P p = (PGM_P)ifsh;

Nel disassemblato si trova la stringa salvata in Flash:
Code: [Select]

00000068 <_ZZ5setupE3__c>:
  68: 4d 41 52 49 4f 00                                   MARIO.


Usando il codice originale, si trova la stringa in Flash:
Code: [Select]

00000068 <_ZZ5setupE3__c>:
  68: 4d 41 52 49 4f 00                                   MARIO.


Compilando senza usare la funzione F(), la stringa in Flash non c'è.

Maurotec

Non facciamo che quella è una variabile locale della funzione setup(), ma mi sembra strano trovarla li, anche perchè se no secondo l'esempio dovrebbe trovarsi in loop().

allega il disassemblato, please.

Ciao.

gpb01

Allora, programma di prova :


Code: [Select]
void setup() { 
  delay(2000);
  Serial.begin(9600);
}

void loop() { 
  Serial.print(F("Stringa di prova"));
}



Modifica alla Print.cpp con cui è compilato :

Code: [Select]
size_t Print::print(const __FlashStringHelper *ifsh)
{
  //const char PROGMEM *p = (const char PROGMEM *)ifsh;
  PROGMEM PGM_P p = (PROGMEM PGM_P)ifsh;
  size_t n = 0;
  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    n += write(c);
  }
  return n;
}



warning che si ottiene relativo alla Print.cpp :

Code: [Select]
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.cpp: In member function 'size_t Print::print(const __FlashStringHelper*)':
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.cpp:45:17: warning: '__progmem__' attribute ignored [-Wattributes]



allegato il disassemblato.

Guglielmo
Search is Your friend ... or I am Your enemy !

Maurotec

Tutti gli attributi (o direttive del compilatore) devono essere specificati dopo il codice a cui vogliamo che il compilatore dedichi un comportamento specificato dal nome dell'attributo.

quindi:

const char *PROGMEM, non ha molto senso.
scusate:
PROGMEM PGM_P p, non ha molto senso.


Nella doc creata durante la compilazione c'è documentazione circa la funzione (o macro) __c che è valida solo in C++ e non è presente in C, non so se ho quella doc ancora adesso però ricordo di aver letto qualcosa quindi appena posso controllo la doc e vediamo di che si tratta, magari c'è un bug e il compilatore dice di ignorare ma poi non lo fa.

Ora vedo il disassemblato.

Ciao.

PaoloP

--> https://github.com/arduino/Arduino/issues/1274
Dicono di averlo risolto --> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734  :|

Maurotec

Io non trovo più la doc dove ho letto circa __c function (o macro) ecc, probabilmente tempo fa ho tentato di compilare la toolchain con le patch di atmel e ho creato la doc in pdf, ora non trovo più nulla forse ho cancellato il tentativo fallito di compilare la toolchain.

Mi ricordo anche che la doc ufficiale viene modificata da atmel per aggiungerci cose, ma non ci giurerei.

Riepilogando:
Come la classe Print a chiamare una funzione dedicata se il puntatore in RAM punta in flash, si fa una porcata che però funziona
si usa reiterpret_cast come questo:

Code: [Select]

class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))


Quando si scrive F("mia stringa"), ad opera di ppc (preprocessore C) viene trasformata nel modo seguente:
Code: [Select]

(reinterpret_cast<const __FlashStringHelper *>(PSTR(mia stringa)))

Anche PSTR viene espanso in:
Code: [Select]

(__extension__({static char __c[] PROGMEM = (mia stringa); &__c[0];}))


Ecco che spunta __c che non è una funzione ne macro ma un array di caratteri statico che punta in FLASH, cioè __c contiene l'indirizzo in flash di m (ia stringa\0)

Ora  questo cast (reinterpret_cast<const __FlashStringHelper *>(PSTR(mia stringa))) è da tipo static char [] a puntatore const
__FlashStringHelper, che non è una classe, ma una forward declare di una classe che non è stata definita in nessun posto (almeno io non l'ho trovata) quindi si tratta di un tipo usato per comodità così da permettere al C++ di richiamare il metodo di Print corretto.

Ora static ha senso solo dentro un modulo o compile unit, o dentro un blocco di codice {} e in effetti come si vede il blocco c'è: (__extension__(start block-->{static char __c[] PROGMEM = (mia stringa); &__c[0];}<--end block))
guardate che &__c[0]; preleva l'indirizzo da __C[0]


Probabilmente da static char a const __FlashStringHelper * qualcosa non torna, ma invece si perchè il cast è da &__c a const __FlashStringHelper *, booo mi sono perso, vedete voi di usare qualcosa di C standard senza coninvolgere l'arduino core.

Quasi sicuramente il problema è dentro il metodo print, quando si fa il cast da  const __FlashStringHelper * a puntatore a in flash.

Ciao.


gpb01


... booo mi sono perso, vedete voi di usare qualcosa di C standard senza coninvolgere l'arduino core.
...


Ahahahahah ... se ti sei perso tu fugurati noi ...

Comunque, mi sembra che sia appurato che, in un modo o nell'altro, i dati FINISCONO nella FLASH e quindi, anche se il compilatore si incavola e da un warning, alla fine il tutto va ...

Lo accettiamo cone un "warning trascurabile" e passiamo al successivo ERRORE ?

Attendo la vostra opinione prima di proseguire ... ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

gpb01

OK, accettiamo che anche questo "warning" sia in realtà trascurabile e passiamo invece ad un errore più serio che deve essere risolto, pensa l'inusabilità della libreria WiFi ...


Riprendiamo il nostro codice e aggiungiamo solo una "include" :

Code: [Select]
#include <WiFi.h>

void setup() { 
  delay(2000);
  Serial.begin(9600);
}

void loop() { 
  Serial.print(F("Stringa di prova"));
}



gli errori che ne conseguono sono :


Code: [Select]
In file included from /Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/libraries/WiFi/utility/wifi_drv.h:6:0,
                 from /Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/libraries/WiFi/WiFi.cpp:1:
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/IPAddress.h: In member function 'IPAddress::operator uint32_t()':
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/IPAddress.h:51:55: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/IPAddress.h: In member function 'bool IPAddress::operator==(const IPAddress&)':
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/IPAddress.h:52:75: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/hardware/arduino/cores/arduino/IPAddress.h:52:108: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/libraries/WiFi/WiFi.cpp: In member function 'uint8_t* WiFiClass::macAddress(uint8_t*)':
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/libraries/WiFi/WiFi.cpp:144:1: error: unable to find a register to spill in class 'POINTER_REGS'
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/libraries/WiFi/WiFi.cpp:144:1: error: this is the insn:
(insn 36 26 27 2 (set (reg:QI 23 r23)
        (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                (const_int 2 [0x2])) [9 S1 A8])) /Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/libraries/WiFi/WiFi.cpp:142 28 {movqi_insn}
     (nil))
/Users/gpb01/Desktop/Prove Toolchain/Arduino 1.0.5 TL.app/Contents/Resources/Java/libraries/WiFi/WiFi.cpp:144: confused by earlier errors, bailing out



... ???? AIUTOOOOOOOO

Guglielmo
Search is Your friend ... or I am Your enemy !

Go Up