Inizio con un ringraziamento...

Ciao a tutti, sono un ingegnere informatico appassionato di elettronica. Nell'ultimo anno ho "smanettato" un po' con Arduino realizzando qualche simpatico circuitino con il micro in versione stand-alone; tutto andava bene, finché la versione 1.0 del nuovo IDE non mi ha bloccato, per l'ormai stranoto motivo che è stato oggetto di un lungo thread su questo forum. Dato che, a suo tempo, mi fu "illuminante" la celeberrima guida di Michele Menniti, pensai di rivolgermi a lui, per email, per cercare lumi su una possibile soluzione. Ed è stato grazie a lui, che ho conosciuto il forum, e di conseguenza la guida+sketch pubblicata daTestato; la combinazione è stata decisamente efficace, in quanto ho potuto riprendere la programmazione dei miei micro standalone :-) Inizio la mia partecipazione al forum, quindi, con un pubblico ringraziamento al "menny" per la disponibilità dimostrata e all'utente Testato per l'ottimo lavoro svolto per TinyISP. A frequentare i forum c'è sempre da imparare :)

Dario (dalubar)

Benvenuto!! Tu sai che i nuovi devono procurasi la loro sfera di cristallo con diametro non inferiore a 11,34 cm per metterli a disposizione a chi risponde secondo un calendario publicato su Arduino.cc/calendario_sfere_di_cristallo.php ;) ;) No scherzo.

Benvenuto e buon divertimento con arduino. Un bel gesto ringraziare chi Ti ha aiutato.

Ciao Uwe

Ciao Dario, benvenuto tra noi! Ti ringrazio per i complimenti, ma devo però renderti la pariglia, come suol dirsi! Il tuo intervento fa sembrare che tu sia un newbie che è appena riuscito a mettere il suo primo blink usando la programmazione ISP, invece io sono testimone diretto del fatto che hai realizzato un'applicazione hardware/software spettacolare, tant'è che ti sei rivolto a me perché hai raggiunto il limite di flash ed hai qualche "problemino" di byte. Non dico altro, per rispetto della privacy, voglio solo che gli altri amici sappiano che non sei un principiante qualsiasi. Benvenuto ancora!!

Ti spiego l'intervento di UWE, il nostro amato :* e nel contempo temuto ]:D moderatore: ogni tanto, ultimamente spesso, qualcuno apre un Topic chiedendo aiuto senza spiegare nulla di ciò che vuole; allora Uwe si è dotato di due sfere di cristallo (io penso siano frutto di una trasformazione genetica di altre due ben più note sfere :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes:) per leggere nel pensiero di chi vuol essere aiutato :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes:

Ciao Uwe, e grazie per il tuo benvenuto. Ehh, davvero troppo buono Michele! :)

Si, è vero, ultimamente ho un piccolo problemino con uno sketch su ATMega328 che si trova ormai vicino al numero magico "32768". Il fatto è che già a una dimensione di 32400 circa, lo sketch (pur correttamente trasferito) manda in blocco totale il micro. Ormai ho fatto tante di quelle prove che posso anche essere più dettagliato: intorno ai 32460-32560 byte, il micro parte mediamente una volta su tre, ovvero alimentando la scheda, c'è il 33% di probabilità che non si avvii (staccando e riattaccando, il micro invece partirà tranquillamente). Superati i 32560 byte l'ATMega328 non "parte" neppure se gli fornisco le valigie gratis!! Come mai? Qualcuno ha riscontrato questo problema?

Terapie provate allo stato attuale: a) ricerca selvaggia sui forum. Su uno in particolare, americano, ho letto di un tizio al quale capitava la stessa cosa e che ha ricevuto come risposta il fatto che poteva trattarsi di sovrapposizione dei puntatori della zona RAM/FLASH dovuto a un uso intenso al "limite" dell'area RAM (com'è nel mio caso). Cosa ci sarà di vero? Mah! b) il buon menny di mi ha suggerito qualche impostazione dei fuses da inserire nel file board.txt, ma neppure così ho avuto risultati. c) algoritmo dello struzzo: "ignorare il problema nella speranza che il problema ti ignori".

L'opzione "c" al momento è quella più gettonata...alla fine non saranno 200 byte che mi cambieranno la vita (anzi lo sketch), ma devo dire che per puro interesse tecnico mi piacerebbe sapere il "perchè" di questa anomalia, soprattutto dopo aver visto un'immagine nella guida di menny che, con orgoglio, mostrava una compilazione di ben 32768 byte andata a buon fine!! Un po' di invidia mi sarà pur concessa, no? :)

Grazie a quanti daranno qualche buon consiglio.

Domanda n°1: ovviamente stiamo parlando di un 328 al quale hai eliminato lo spazio di flash riservato al bootloader, così da utilizzare in toto la flash disponibile, giusto?

Domanda n°2: a consumo di SRAM come sei messo?

Risposta 1. Ovviamente si :)

Risposta 2. Qui rispondere è decisamente più complicato...lo sketch è grande e lo sforzo intellettuale è stato quello di concentrare la maggior parte dei servizi possibile all'interno di quello spazio ristretto. Posso solo dirti che ogni singola riga di codice è stata scritta guardando attentamente al dimensionamento delle variabili (non uso un "int" se posso usare "byte", per intenderci), all'uso intenso del bitwise per concentrare più informazioni su una singola variabile (8 switch di dispositivi stanno su un unico byte), uso della clausola PROGMEM per memorizzare le costanti su flash, e altre amenità varie...tutto per cercare di pesare il meno possibile sulla RAM. Certo, le variabili ci sono (anche diversi vettori), ma credo che sarà difficile stringere ancora...

Io avevo dei problemi che non partiva l' arduino (non ricordo se un 2009 o un UNO R1) perché avevo aggiunto dei condensatori elettrolitici sui 5V. Probabilmente facevano alzare troppo lentamente la tensione di alimentazione e il Reset al Power On non funzionava corettamente. A secondo del valore del condensatore partiva ognitanto o con un condensatore piú grande non partiva neanche. Il problema col spazio si puó risolvere con un ATmega1280,1281,2560 o 2561.

Ma progmem non copia le variabili quando vengono usati dalla flash nella RAM? http://arduino.cc/forum/index.php/topic,89931.msg676005.html#msg676005 potrebbe aiutare?

Ciao Uwe

OK. Però bisogna avere almeno un dato per poter ragionare.
Hai provato ad usare avr-size per avere l’occupazione statica della SRAM del micro?

  1. avvii la compilazione premendo l’icona di compilazione insieme al tasto shift. Nel terminale dell’IDE vedrai i messaggi scorrere del compilatore. Tra di essi, in cima, c’è la cartella temporanea in cui il compilatore ha creato i file oggetti ed i file .hex pronti per l’upload. Apri un terminale in quella cartella e digita un “avr-size nomeSketch.cpp.hex --target=m328p -c”. Avrai in risposta un resoconto dettagliato dell’impiego di SRAM del tuo sketch. Ovviamente si tratta di consumo statico, come ti ho detto: quindi niente array dinamici costruiti a runtime ecc… però è già un dato di massima su cui ragionare (spero che la sintassi sia giusta, vado a memoria).

uwefed: Ma progmem non copia le variabili quando vengono usati dalla flash nella RAM?

No. Normalmente ogni stringa o dato numerico inserito nello sketch viene comunque copiato in SRAM prima di venir gestito dalla CPU. Con PROGMEM si passa al programma l'indirizzo della Flash da cui prelevare quel dato, evitando proprio che venga copiato in SRAM e vada a consumarla.

uwefed:
Io avevo dei problemi che non partiva l’ arduino (non ricordo se un 2009 o un UNO R1) perché avevo aggiunto dei condensatori elettrolitici sui 5V. Probabilmente facevano alzare troppo lentamente la tensione di alimentazione e il Reset al Power On non funzionava corettamente. A secondo del valore del condensatore partiva ognitanto o con un condensatore piú grande non partiva neanche.
Il problema col spazio si puó risolvere con un ATmega1280,1281,2560 o 2561.

Uwe, ma che razza di valori hai usato per rallentare così tanto la stabilizzazione dell’alimentazione da bloccare il reset iniziale? :fearful: non penso che un 100µF, tipico di un’uscita stabilizzata esterna, per un assorbimento di circa 300-500mA, possa causare un ritardo qualsiasi, quindi devi aver messo delle cisterne :grin:
Scherzi a parte mi pare che Dario abbia verificato che con sketch <30000 bytes il problema NON lo abbia mai, quindi non dovrebbe essere legato ad una problematica hardware, ma potrei ricordar male io.

Non avevo messo un condensatore cosí grande; qualche centinaio di µF. Comunque mi ricordo adesso quando mi é capitato: era un arduino nano alimentato dalla USB con un TLC5940 e 5 LED RGB (ovvero 5x6LED RGB multiplexati) con una corrente su ogni LED bassina, sotto 10mA e un DS1307. Concordo che questa causa si puó escludere quando il problema non si presenta con un sketch da 30000Byte ma con uno poco piú grande sí.

Domanda cretina: Se compili un sketch, il valore di flash occupata conta anche le variabili messi nella flash con progmem?

Ciao Uwe

Allora…premesso che non ho mai fatto esperienza con i file della directory “bin” di avr, come suggerito da Leo, ho provato a lanciare il seguente comando, dopo aver rintracciato la dir d’interesse (cut&past per non sbagliare):

avr-size C:\Users\xxx\AppData\Local\Temp\build3137404511334209821.tmp\ROCCA_V1_3_3.cpp.hex --format=m328p -c

e questo è il risultato:

avr-size: invalid argument to --format: m328p
Usage: avr-size [option(s)] [file(s)]
Displays the sizes of sections inside binary files
If no input file(s) are specified, a.out is assumed
The options are:
-A|-B|-C --format={sysv|berkeley|avr} Select output style (default is berkeley)
–mcu= MCU name for AVR format only
-o|-d|-x --radix={8|10|16} Display numbers in octal, decimal or hex
-t --totals Display the total sizes (Berkeley only)
–common Display total size for COM syms
–target= Set the binary file format
@ Read options from
-h --help Display this information
-v --version Display the program’s version

avr-size: supported targets: elf32-avr coff-avr coff-ext-avr elf32-little elf32-big srec symbolsrec tekhex binary ihex

A quanto pare non riconosce il parametro “m328p”…e neppure viene menzionato tra le opzioni.
Ho provato le altre opzioni disponibili ma o mi dà errore oppure dà:

AVR Memory Usage

Device: Unknown

Program: 0 bytes
(.text + .data + .bootloader)

Data: 0 bytes
(.data + .bss + .noinit)

Dove sbaglio?
(Ricordo che in questo momento sto usando IDE 1.0)

Non so aiutarti, posso però dirti che Leo (a quest’ora è in fase REM causa alzataccia) lavora con la 0023 (simile alla 0022), e che con la 1.0 finora si è fatto pochissimo; quindi forse dovresti rifare la prova con la 0022 che già hai; una copia dello schetch “compatibile” 0022 l’avrai ancora vero?
Ti faccio inoltre notare che Leo ti aveva suggerito “target” e non “format”, come tentativo usa anche mcu=m328p.

Si, mi ero accorto anch'io di aver ricopiato male nel forum, ma in effetti la prova l'ho fatta corretamente col parametro "target" e non format. Provata anche l'opzione mcu=m328p...ma è uguale.

Cmq sono convinto che si tratti semplicemente di un problema di versione IDE. Domani con calma proverò con la 0022 (certo salvo tutte le versioni, con il software non si scherza :) )

Adesso chiudo...un saluto a tutti. A domani.

1 errore mio, dovevi farlo sul file .cpp.elf

Poi, i parametri: avr-size mi fa sempre un po' dannare, alcuni parametri variano da versione a versione. Dai semplicemente avr-size nomeSketch.cpp.elf

Ti apparirà un output tipo

avr-size /path/to/temporary_compile_dir/compiled.cpp.elf

text    data     bss     dec     hex                                                                                                     
11926    1594     474   13994    36aa

Per avere il consumo di RAM basta sommare i valori di data e bss, in questo esempio 1594 e 474.

uwefed: Domanda cretina: Se compili un sketch, il valore di flash occupata conta anche le variabili messi nella flash con progmem?

Sì. PROGMEM serve a non far occupare la SRAM. Anzi, siccome per usarlo devi importare una lib specifica, il consumo di Flash aumenta.

EDIT: http://hackaday.com/2010/09/01/how-to-fix-avr-size-on-ubuntu-10-04/ Qui ti spiegano i parametri, io non me li ricordo mai :sweat_smile:

Alleluja! Ecco l'output:

text data bss dec hex filename 31976 270 747 32993 80e1 ROCCA_V1_3_3.cpp.elf

A quanto pare data + bss = 1K circa, quindi come SRAM dovremmo essere ad appena la metà di quella disponibile.

Usandolo con l'opzione -C viene fuori:

Program: 32246 bytes (.text + .data + .bootloader)

Data: 1017 bytes (.data + .bss + .noinit)

Il valore 32246 è lo stesso riportato alla fine della compilazione...

La parola agli esperti :)

Bene, come consumo di RAM siamo sicuri di non essere fuori. Resta da avere conferma del fatto che il tuo microcontrollore non riserva spazio per il bootloader. Potresti provare a leggere il fuse alto?

Carica lo sketch ArduinoISP sul tuo Arduino, collega il micro esterno come per la programmazione (vedi guida di Menny) Poi apri un terminale in /hardware/arduino/tools e dai questi comandi (uso Linux, la sintassi Windows non è corretta):

avrdude.exe -C avrdude.conf -p m328p -P laPortaCom -U hfuse:r:fuse.txt:m -b 19200 -c stk500v1

Dovresti ritrovarti in fuse.txt un valore esadecimale corrispondente al valore del fuse alto.

Comunque ho visto i fuse della sua board virtuale e sono OK, quindi il dubbio che mi viene e se li abbia programmati correttamente mettendo prima il bootloader. Spiego a Dario, per scrupolo: La tecnica ISP programma correttamente i fuse solo se carichi il bootloader usando quella board virtuale. Successivamente carichi via ISP il tuo sketch. Quest'ultima operazione sovrascrive il bootloader, ma non ci interessa, lo abbiamo caricato SOLO per cambiare i valori dei fuse. Ma tu fai già così vero?

menniti:
La tecnica ISP programma correttamente i fuse solo se carichi il bootloader usando quella board virtuale.
Successivamente carichi via ISP il tuo sketch.
Quest’ultima operazione sovrascrive il bootloader, ma non ci interessa, lo abbiamo caricato SOLO per cambiare i valori dei fuse.

Aspetta. Caricare uno sketch via ISP non cancella il bootloader né riprogramma i fuse. Con l’IDE di Arduino l’unico modo per programmare i fuse è quello di fare l’upload del bootloader. Per “ingannare” l’IDE andrebbe creato un finto bootloader vuoto, solo per poter resettare il fuse alto e togliere la prenotazione dello spazio per il bootloader.

Quindi se lui ha caricato il bootloader la prima volta, ha i fuse programmati per riservare lo spazio per il bootloader.