Scrivere su flash in runtime

Buongiorno a tutti

Sono quasi 4 giorni che leggo e giro come un dannato per trovare un metodo che mi permetta di scrivere sulla parte libera della flash non occupata dallo sketch. Sono in grado di leggere qualsiasi byte alla pos che voglio della flash, ma non a scriverci sopra. Mi servono 20k della flash + 4 della eeprom che come detto in altri post sono a tappo.

Mi sono studiato tutte le funzioni semplici e avanzate del progmem che provvede a scrivere e recuperare i dati in page, ma questa operazione di scrittura la fa solo in fase di upload dello sketch i byte memorizzati diventano costanti.

Ho letto che solo il bootloader è in grado di scrivere sulla flash in runtime e che la memoria Flash è divisa in due sezioni, la sezione del programma di avvio e la sezione di programma applicativo. Entrambe le sezioni hanno dedicato i bit di blocco per la scrittura e la lettura / scrittura di protezione. L'istruzione SPM che scrive nella sezione Memoria per l'applicazione Flash deve risiedere nella sezione Programma di avvio.

Si potrebbe in qualche modo cambiando i fuse allargare la zona dedicata al boot invece che 2k dirgli che è 22k? allora li potrei andare a scrivere in runtime tra il 3° e il 22° k. (non credo che userò mai 256k della mega in sketch è uno spreco di spazio)

In questi 20-30k (se si riesce a ottenerli) devo scrivere dei parametri una volta solo, ma dopo lo start di arduino, verrebbe usata esclusivamente come una sorta di eeprom.

Riporto informazioni lette (non solo su topolino :) ) quindi se ho detto qualche scemenza non uccidetemi.

ciao

Come ti ho già detto è possibile farlo, però non è una cosa semplice, ti consiglio di leggere attentamente sul data sheet la sezione relativa al bootloader, dove trovi tutti i dettagli su come scrivere la flash e di guardarti la sezione relativa al boot delle avrlibc dove trovi varie routine pronte all'uso. Ti rammento che non puoi scrivere la flash per singoli byte/word, puoi solo scriverla per singole pagine che devono essere preventivamente cancellate, se non mi ricordo male sul 2560 le pagine di memoria sono organizzate a 256 byte per volta.

Post contemporaneo!

cancellato.

Pablos, negli ultimi giorni ho studiato un pò la programmazione della Flash per via dello studio del bootloader del 1284.

Ci sono 2 punti fermi: 1) la dimensione dell'area destinata al bootloader non può essere definita dall'utente, quindi con una qualsiasi dimensione, ma è fissata dai fuse. A seconda del micro si va da un minimo ad un massimo. Nel caso del 2560 si va da 1024 a 8192 byte. Ricordati che la memoria dei chip è a 16 bit, o word, per cui guardando i fuse vedrai 512w/4096w invece che dei dati che ti ho scritto. 2) Solo un programma scritto nell'area del bootloader può scrivere a runtime nell'area di memoria dell'applicazione. Anzi, il bootloader può scrivere anche nell'area del bootloader e, addirittura, autocancellarsi. Questo perché l'istruzione SPM è disabilitata quando viene eseguito il codice dall'Application Section.

Quindi, un programma che non è un bootloader può solo leggere dalla Flash.

leo72:

  1. la dimensione dell’area destinata al bootloader non può essere definita dall’utente, quindi con una qualsiasi dimensione, ma è fissata dai fuse

Credo che hai travisato quanto spiegato nella sezione bootloader applicandolo in senso generale.
E’ vero che la SPM può funzionare solo dalla sezione bootloader, però nulla vieta di porre la funzione che scrive la flash in questa area e richiamarla a piacere dal proprio software, come ho detto non è una cosa semplice da fare però è possibile, pregasi leggere l’application note di Atmel che ho allegato.

doc2575.pdf (48.2 KB)

Quando parlavo della dimensione prefissata del bootloader mi riferivo all'affermazione fatto da pablos:

Si potrebbe in qualche modo cambiando i fuse allargare la zona dedicata al boot invece che 2k dirgli che è 22k?

Questo non si può fare: la dimensione della Bootloader Section può essere fissata max fino a 4096w (8192 byte), ossia con i valori dei fuse.

Questo non si può fare: la dimensione della Bootloader Section può essere fissata max fino a 4096w (8192 byte)

Che iella!!

ma nel pdf leggo "Definition of Boot segment in *.xcl file for an ATmega128 with 8kB Boot size: 4096w " vale la stessa dimensione per la 2560?

@astrobeed Quel pdf che hai linkato me lo ero già sparato tutto :) infatti avevo cercato la Self_programming.h che avevo trovato, ma non c'è stato verso di trovare Self_programming.c, ho pensato che si trovasse nel cdrom dell'atimel completo di doc e lib, 6giga di download ma nulla. Comunque vabbè è un argomento di scarso interesse, quindi mi sa che morirà qui.

ciao

Tu dici questo zip :http://www.atmel.com/Images/AVR106.zip

Trovato qui : http://www.atmel.com/products/microcontrollers/avr/megaavr.aspx?tab=documents

E morta li? :P

Ciao

grazie, librerie con data 2006 ne ho trovate a fiumi, pensi che ci sia compatibilità con un chip che è uscito 4 anni dopo? :D

E morta li?

perchè, sei interessato? :P

ciao

pablos:

Questo non si può fare: la dimensione della Bootloader Section può essere fissata max fino a 4096w (8192 byte)

Che iella!!

ma nel pdf leggo "Definition of Boot segment in *.xcl file for an ATmega128 with 8kB Boot size: 4096w " vale la stessa dimensione per la 2560?

I file .xcl immagino siano file descrittivi per qualche applicativo Windows. Quindi serviranno ad istruire qualche programma sulle caratteristiche del micro. Forse AvrStudio? A parte questo, non ho mai usato un Atmega128 ma conosco l'Atmega2560: esso ha 5 dimensioni per la sezione Bootloader: 0/512/1024/2048/4096w. Che sono 0 byte, 1024, 2048, 4096 e 8192.

Pablos, che necessità hai per dover scrivere sulla Flash? Non potresti fare in altro modo? Magari se spieghi, possiamo vedere di trovare un'alternativa.

pablos: grazie, librerie con data 2006 ne ho trovate a fiumi, pensi che ci sia compatibilità con un chip che è uscito 4 anni dopo? :D

E morta li?

perchè, sei interessato? :P

ciao

Tra le caratteristiche degli ATmega questa è quella che non ho approfondito, pertanto anche se non mi serve al momento, leggere e sapere mi interessa e purtroppo il tempo in questo periodo per me è molto poco e quel poco poco produttivo.

PS: occhio al gioco di parole.

Si quel documento è datata e si riferisce ad un'altra MCU, ma è già una base su cui lavorare, alla fine penso che basta modificare qualche registro e poco altro.

Ciao.

Ricordatevi però che una porzione di codice che possa scrivere sulla Flash può girare solo nella Bootloader Section. Un programma che sta nell'Application Section non può farlo in maniera diretta. Astro ha mostrato un documento che illustra come farlo richiamando una funzione alloggiata nella Bootloader Section ma sempre lì deve stare, altrimenti la SPM viene disattivata.

leo72: illustra come farlo richiamando una funzione alloggiata nella Bootloader Section ma sempre lì deve stare, altrimenti la SPM viene disattivata.

Esatto, la funzione che scrive sulla flash, e rammento che col 2560 sono pagine da 256 byte per volta, deve risiedere nella Bootloader Section, il che è impossibile da fare con l'IDE di Arduino, però è possibile realizzare un booloader modificato che contiene questa funzione/i, delle quali è indispensabile conoscere l'esatto address, che poi vengono richiamate dal programma principale, però è da verificare se è possibile farlo da IDE Arduino, lavorando un C/C++ sotto Avr Studio è fattibilissimo. Gli esempi della application note sono relativi al compilatore per avr di IAR, però sono facilmente adattabili ad altri compilatori e il codice non ha una data di scadenza :grin:

leo72: Pablos, che necessità hai per dover scrivere sulla Flash? Non potresti fare in altro modo? Magari se spieghi, possiamo vedere di trovare un'alternativa.

E' un po' lungo da spiegare nei dettagli, cerco di essere breve .... mmm mi sa che ti annoierai:

Il mio progetto è quello di creare una piattaforma antiscemo :) , tutto ciò che riguarda la logica di azione e reazione tra i pin. La mega è totalmente configurata da un file su sd dove ci sono tutti i byte che servono per dire al chip imposta i registri in questo modo ed esegui determinate cose se ci sono determinati eventi, questo mi permette di usare arduino per molteplici applicazioni senza nemmeno guardare lo sketch, le impostazioni sono modificabili da remoto.

Parametri su SD da passare alla eeprom 4 byte IP 6 byte MAC 4 Byte Gateway 4 byte subnet 4 byte per server NTC_1 4 byte per server NTC_2 4 byte per server NTC_3

5 byte di aggiustamento hh,mm,gg,mese,anno (+/-)

54 byte setup Input/output e pullup + 0/1 allo start - setup di tutti i pin (54 byte di configurazioni) qui scgli se il pin deve essere Input con o senza pullup opp Output, inoltre stabilisci se allo start di arduino il pin deve partire da 1 o 0.

16 byte setup Input/output/analog - setup di tutti i pin analogici. qui si può scegliere come sopra come vuoi che sia il pin

99 gruppi di appartenenza - 9 byte per ogni gruppo, questi 9 byte raccolgono tutti i registri PIN-ABCDEFGHJ... ed è la parte più complicata ma anche la più snella potendo gestire tutti i pin senza "cicli for" con la manipolazione dei registri in un colpo solo.Potrebbe essere impiegato per creare in domotica gli scenari, sollevare gruppi di serrande e chiuderne altre accendere luci nello stesso istante, se li mettiamo tutti e 8 a 0 spegnamo tutto e buonanotte, insomma comandare comunque un insieme di pin a scelta inseriti nel gruppo.

25 codici IR con sistema di autoapprendimento, ipotizzando uno voglia usare un 32bit, sono 25x4byte al massimo che metto a disposizione, ogni codice può essere assegnato a 1 o anche a tutti i pin in base al gruppo di appartenenza che viene scelto nelle condizioni. Il sistema comprende in modo opzionale uno o più ricevitori IR, basta che nel setup su SD venga scritto su quali pin sono stati messi.

54 condizioni/ON - 54 condizioni/OFF - la condizione stabisce con 2 byte ciascuno cosa deve fare il pin quando un evento lo commuta a 1 o 0, quindi che il pin sia settato in Input o Output non ha importanza il programma agisce in base a questi 2 byte.

300 timer + enable/disable + ON/OFF - 300 orologi (che sembrano tanti, ma distribuiti opzionalmente su tutti i pin non lo sono), ho dovuto comunque fare dei tagli per questioni di mem .... Si può decidere perciò di dare 300 timer a un pin solo oppure 7-8 timer a tutti i pin ovviamente se sono impostati output... a scelta dell'utente, utile per utenze che hanno molte accensioni e spegnimento durante il giorno o la notte (prendi un acquario per esempio)

54 impulsi - 1 byte, questo parametro decide se il pin una volta chiamato deve dare un impulso 0 o 1 di n secondi o deve restare sempre 0 o 1, avendo un byte posso solo moltiplicando per 1000 decidere minimo un secondo massimo 4 minuti può essere utile per fare dei timer luci scala con ogni piano separato, comandare dei relè passo-passo, una luce lampeggiante, azionare delle serrande elettriche a tempo...ecc

30 AND 0/1 di massimo 12 pin 30 OR 0/1 di massimo 12 pin

25 byte password MD5 - default > scritta su popup web diretta su eeprom 25 byte password MD5 - utente > scritta su popup web diretta su eeprom

poi c'è tutta la parte dei pin analogici (Manca memoria per i parametri) che possono essere usati con tutti i sensori che uno vuole purchè si rispettino i 0-5v, il setup su sd avrà come dati da confrontare degli INT quindi 2 byte, in questo modo a me non interessa se ci colleghi una fotoresistenza un lm35 o un sensore hall, il dato reale e la formula è fatta dalla pagina web che visualizza in real time i valori convertiti in lux, gradi, ampere ecc ecc (del resto arduino che se ne fa dei dati convertiti in celsius o ampere?)

Ci sarebbe la parte della ripetizione IR in base ai codici memorizzati su eeprom, per accendere con i timer programmati o da remoto condizionatori e apparati vari con infrar. (non l'ho fatta)

Inserimento opzionale di uno o 2 tipi standard di display lcd, aggiungo le librerie che saranno usate

Come detto prima c'è poi la ethernet le paginette web che visualizza in sinnottico 70 pin con l'invio di soli 40 byte senza refresh della pagina ma in modalità persistente.

Le svariate combinazioni dei parametri qui sopra possono dare molte applicazioni senza sbattimenti di programmazione sketch e anche un inesperto di programmazione può usare la scheda, certo non ci fa un pallone sonda o un rover da mandare su Venere.

Fino ad ora ho risolto una montagna di problemi. Riassumendo il tutto ti ho risposto in modo lungo :) alla tua domanda, non vorrei passare per pazzo facendo richieste assurde, ecco perchè mi serve più memoria per i parametri da poter leggere rapidamente, potrei spaziare molto di più nelle opzioni.

Ringrazio tutti voi per l'aiuto datomi nelle parti più difficili.

Cosa ne faccio di quei parametri: Tutti i parametri presenti nel file setup.ini su sd al reset vengono nel setup() confrontati con quelli scritti nella eeprom , se il byte è diverso viene sovrascritto col nuovo dato nella singola cella, altrimenti non scrive nulla, evitando di logorare inutilmente la memoria. Posso resettare 1000 volte senza scrivere nulla, quindi se voglio cambiare un dato, vado sulla pagina web cambio il dato nel file ini e resetto, con questo ti spiego perchè il PROGMEM non fa al caso mio e ti spiego anche perchè volevo un reset remoto senza impegnare un altro pin. Desideravo che arduino fosse il più autonomo possibile senza l'ausilio di computer di appoggio, server con database ecc, una cosa piccola dove con i connettori vai alle interfacce e stop.

ciao

1) ho perso 5 minuti per leggere il tuo post. :sweat_smile: 2) il problema del reset si risolve usando il WDT ed il nuovo bootloader per Mega2560 (sei stato tu a segnalarlo?) che c'è sul sito di Arduino. Ho usato una versione simile per il 1284P e posso dirti senza paura di smentite che il WDT viene resettato e può essere gestito senza problemi.

Dico una cosa. Ma perché non usi una memoria esterna per memorizzare tutto? (non ti dico di estendere la SRAM: l'Atmega2560 può gestire anche della memoria SRAM esterna come estensione della RAM interna. Solo che perdi un sacco di pin...) Una FRAM, una EEPROM... immagazzini i parametri e poi li leggi con delle tabelle.

ho perso 5 minuti per leggere il tuo post

te l'ho anticipato che facevo la sintesi ahahahahhaha

http://www.hobbytronics.co.uk/arduino-external-eeprom dici una cosa così? mi prenderebbe solo 2 pin SCL e SDA? , non conosco i tempi di lettura, ma non saranno poi così esagerati.

pablos:

ho perso 5 minuti per leggere il tuo post

te l'ho anticipato che facevo la sintesi ahahahahhaha

http://www.hobbytronics.co.uk/arduino-external-eeprom dici una cosa così? mi prenderebbe solo 2 pin SCL e SDA? , non conosco i tempi di lettura, ma non saranno poi così esagerati.

Esattamente. Un bel 24LC512, che ha 512 Kbit di capacità, 64 kB. Sai la roba che ci metti dentro? La scrittura prende 5 ms, ma la lettura è sull'ordine dei decimi di ms.

Bhe si potrebbe essere una soluzione, però pensavo questi dati mi fanno gola.

Microcontroller AT91SAM3X8E Arduino Due
Flash Memory 512 KB all available for the user applications
SRAM 96 KB (two banks: 64KB and 32KB)
Clock Speed 84 MHz
la due non ha eeprom, ma è in grado di gestire 256kb della flash con una pseudo lib eeprom

quasi quasi pensavo di prendere una due e la shield ethernet R3 che è compatibile e incominciare da capo con quella

Leo sei interessato a smanettare su una due? Fammi sapere :slight_smile:

ciao

pablos: Bhe si potrebbe essere una soluzione, però pensavo questi dati mi fanno gola.

Microcontroller AT91SAM3X8E Arduino Due Flash Memory 512 KB all available for the user applications SRAM 96 KB (two banks: 64KB and 32KB) Clock Speed 84 MHz la due non ha eeprom, ma è in grado di gestire 256kb della flash con una pseudo lib eeprom

quasi quasi pensavo di prendere una due e la shield ethernet R3 che è compatibile e incominciare da capo con quella

Leo sei interessato a smanettare su una due? Fammi sapere :)

ciao

Che cosa vorresti da me? :sweat_smile: