sram troppo piccola

salve a tutti
premetto che non sono molto addentro al discorso relativo alla struttura dei processori, ma ho notato che sostanzialmente la sram di tutte le unità è purtroppo molto limitate in dimensione.
Mi risulta spesso difficile costruire sketchs "grandi" perchè alla fine non c'è spazio per gestire le variabili e il risultato finale risulta spesso instabile, mentre è (inutilmente) immenso lo spazio che col tempo è stato dedicato alla flash.
Da quello che ho capito, in questo tipo di processori, non è possibile gestire più di 64k. E mi sembra di aver anche capito che mentre si possono aumentare - anche esternamente - gli altri tipi di memoria, quella del contenitore delle variabili è in pratica un collo di bottiglia.
Premesso inoltre che adotto tutte le possibili giuste attenzioni alla creazione del codice (PROGMEM, utilizzo di byte anzichè di int, char al posto di string, unsigned per risparmiare un byte, utilizzo di variabili ove possibile solo dichiarate all'interno delle routines etc etc), volevo capire se esiste qualche altro metodo, anche hardware, che possa risolvere questo mio isterico appetito di spazio dedicato.

Benvenuto nel magico mondo dei microcontrollori :D.

fotosettore:
Da quello che ho capito, in questo tipo di processori, non è possibile gestire più di 64k.

Ma tu lo sai che l'AGC (Apollo Guidance Computer) che era installato nell'Apollo 11 e che ha portato gli uomini a raggiungere la Luna aveva solo 2k words (4k byte)? :wink:

Purtroppo se si ragiona come se fossimo su un PC allora si, 64k sono pure pochissimi, ma per una piccola MCU pensare di realizzare programmi complessi è utilizzarlo per cose per le quali non sono state progettate, elaborazioni complesse si fanno su sistemi centrali, periferiche intelligenti come Arduino si limitano a mettere in pratica ciò che il sistema centrale comanda. Non per niente in sistemi distribuiti ci sono vari Arduino come attuatori intelligenti ed una unità centrale che li controlla, generalmente o un Raspberry PI o un PC.

docdoc:
Ma tu lo sai che l'AGC (Apollo Guidance Computer) che era installato nell'Apollo 11 e che ha portato gli uomini a raggiungere la Luna aveva solo 2k words (4k byte)? :wink:

OT: Stai seguendo anche tu i video di CuriousMarc su YouTube? :wink:

Non metto in dubbio che tutto si può fare con meno di quanto sia disponibile, perchè fondamentalmente noi programmatori siamo un pò come le donne: più spazio abbiamo, più ne usiamo.

Però vedo una spropositata quantità di flash, come se io dovessi fare sketch di 5 mila righe e poi 0,01 di sram, che non riesce a contenere neanche le variabili definite nelle librerie esistenti e di obbligatorio uso.
Proprio perchè nel '69 si usavano 4k di ram, non è detto che oggi, dopo 50 anni, si debba rimanere fermi a quanto c'era quando la polizia usava la giulia 1300 ti verde :slight_smile: Anche loro hanno cambiato automobile !

Intendo dire : ogni giorno escono device anche con 4Mega di flash e oltre ma "cui prodest" se poi debbo fare i salti mortali per le variabili ?
ripeto : sono un nuotatore della riva, nel mare processori, non un sub.
dove sbaglio ?
E soprattutto, per rimanere in argomento, che soluzioni ci sono oggi, se ci sono ?

Se mi parlate di esp32 forse siamo fuori forum, ma dico già da ora che ho provato ad usarlo :le librerie sono ancora troppo embrionali, piene di problemi e quindi è un prodotto ancora da svezzare.

Allora dai un'occhiata ad un Arduino Due, uno dei "nuovi" MKR1000 & Co. (o Arduino Zero, non ne so molto di queste schede più recenti), un ESP8266, una Teensy, un STM32... Tutte schede con MCU a 32 bit.

Però ripeto: se hai bisogno di (molta) più RAM, è perché stai programmando come se fossi su un PC, devi cambiare stile e modo di gestire le cose. Quella di usare tutte le risorse a disposizione è una piaga dei tempi moderni, che fa sì che un sacco di software sia molto più leeeeeeeento e pesaaaaante di quello che dovrebbe. Per un buon programmatore è buona pratica cercare sempre di usare il minimo indispensabile. In ambiente embedded questa è l'UNICA pratica possibile.

Poi beh, anch'io penso che 4k invece di 2 ci starebbero bene su un 328, ma stiamo parlando di un "computer intero" che costa 2€... Tieni conto che per ragioni tecniche (= semplicità circuitale), questi microcontrollori usano SRAM, e la SRAM è costosetta ancora oggi.

Stiamo parlando di Arduino, quindi Uno, Mega, Nano, Leonardo ... che sono a 8 bits

Se guardi la Due (ma poco supportata) di Ram ne ha 96Kb ma è una 32 bits, come la esp32 o esp8266.
Non possiamo fare paragoni tra MCU a 8 bits e quelle a 32 bits.

E aggiungerci un cippettino di SRAM seriale?

Il "problema" è paragonare architetture Harvard con quelle von Neumann.

maubarzi:
E aggiungerci un cippettino di SRAM seriale?

Ma se ben ricordo non è utilizzabile come sram "aggiuntiva". Qui siamo proprio nei limiti dell'architettura Harvard.

Si.
La usi come periferica di memorizzazione esterna, però veloce.
Non è una estensione della sram interna.
La usi un po' come la eeprom ma senza i limiti nel numero di scritture.

Se su una MCU e hai bisogno di tanta memoria per i dati, mi sa che stai trattando strutture corpose che molto probabilmente si prestano ad essere anche serializzate da qualche parte e accedute solo quando servono, per cui non dovrebbe essere un grosso problema avere una SRAM esterna dove appoggiare questi dati.

In buona sostanza mi confermate quello che pensavo e temevo : unica via è gestire bene le risorse a disposizione, perché oltre un certo limite non si può andare - stop !
Pensavo e speravo che questo limite fosse un po' più avanti, sinceramente.

Poco tempo fa, per esempio, è uscito il d1-mini pro ... con ben 4m di ram rispetto a 1 mega del suo predecessore. Bravi ! Ma a che mi servono 4mega ... solo per incamerare, ad esempio, un mini dbase o delle immagini utilizzando sotterfugi software ?

Quindi: ottimizzare la programmazione (come già sto facendo - vedi primo post) ed accontentarmi (per ora) quello che offre il mercato.

Non sono un "risorsivoro" ... capisco bene che occorre essere parsimoniosi, soprattutto con questi device.

Forse ho sopravvalutato le mie necessità nel caso specifico che sono - credo - normali : una libreria che gestisce un pannello led (pxmatrix), la adafruit per i font, le solite librerie per il wifi, una routine per l'update OTA e lo sketch di gestione. Esce fuori che uso il 70% di sram, con avviso che quella che rimane potrebbe non bastare. Librerie troppo pesanti ... debbo tagliare.

Che dire ? che a questo punto un esp8266 si carica troppo ed un esp32 è ancora troppo giovane per non andare in random-reset :slight_smile:

Attenderò tempi migliori.

E aggiungerci un cippettino di SRAM seriale?

dove posso trovare info a riguardo ?

Ma tu sei al limite con quale scheda esattamente?
Con ESP8266 tipo questa?
Dovrebbe avere 64K per le istruzioni e 96K per i dati, tutto SRAM, non flash.

Per i cippettini di SRAM aggiuntivi prova a vedere link tipo questo

Per acquistare prova quì
Ho cercato per 1Mb, puoi vedere le sigle e cercare se le trovi anche su altri canali.

Però è memoria che usi come appoggio, devi gestirti lettura e scrittura per spostarti i dati nella SRAM della MCU quando ti serve.

Mah, scusate se sono lapidario ma non ci sono più i programmatori di una volta...
Altrimenti avremmo ancora Apple Mac 128
Altrimenti avremmo ancora Apple Mac 512
Oggi abbiamo i Tera...ma non è che ci fai 1 Milione di cose in più (a parità di risorse dovrebbe essere così...)

Alcuni anni fa Mitsubishi mi chiese come avevo fatto ad usare il 99% della memoria di un loro PLC: non era mai successo! Troppo prolisso io? No, è che altri programmatori usavano plc di più alta gamma per fare le stesse cose che io sono riuscito a fare con un PLC compact.
Ma questo non perché sono un genio, ma perché avevo solo quel PLC.

Devo dire che quando ho programmato il primo Arduino continuavo a controllare se mi bastava la memoria...
Poi la fissa mi è passata: non ho mai superato il limite.

Ma non sono ai livelli di Guglielmo o di Standardoil o altri qui dentro che di dieci righe ne fanno una...

steve-cr:
Ma non sono ai livelli di Gilberto o di Standardoil o altri qui dentro che di dieci righe ne fanno una...

forse non sono troppo addentro al discorso e mi scuso se chiedo ancora lumi, ma mi sembra di aver definitivamente capito, grazie ai vostri post che lo confermano, che lo spazio disponibile per lo sketch è praticamente immenso mentre quello delle variabili no e che quindi debbo adeguarmi.

Se quanto inteso è quindi giusto, poco senso ha parlare di fare 1 riga di 10. Scrivere poche righe significa ergonomizzare la lettura e forse la velocità di esecuzione. Ma che c'entra con il problema che ho posto all'inizio ?

Se ho necessità di variabili che vengano viste da tutto lo sketch, segue che debbo definirle fuori da setup e loop.
Alcune posso portarmele appresso come risposta alle funzioni ma poi se mi servono in altre sub debbo per forza definirle globali.
Qui casca il somaro: se le variabili sono tante e "altrettantissime" sono all'interno delle librerie in #include, poco posso fare.
Se faccio 1000 righe o 10 poco cambia. In quella zona c'è un campo di calcio di spazio. Nella zona variabili, in confronto, c'è lo spazio una scatola di scarpe.

Dove sbaglio ?

@ maubarzi
domattina darò una occhiata al tuo secondo link

sto utilizzando un d1-mini wemos, praticamente identico a quello del tuo primo link. ho scritto uno sketch di circa 1500 righe e ho consumato il 30% di spazio di flash. rimane spazio per andare su marte a piedi !
ho inserito il minimo di variabili, tra le altre cose con i dovuti accorgimenti detti nel primo post, e siamo al 55% di sram.
aggiungo le varie librerie che occorrono, falciate di tutte le cose che non utilizzo nel caso specifico, ed arrivo al 70%, con indicazione di alert.
le librerie servono, non posso farne a meno.

deduzio logica et conclusio : sto cercando di fare entrare 2 litri di acqua in una bottiglia da 1 litro. Non è possibile, debbo farmene una ragione e trovare una soluzione.
Dato che non esistono bottiglie da 5 litri, non mi rimane che ... "tagliare" !

Deve comunque essere un qualcosa a basso costo e compatto. Tra l'altro sono obbligato a quel tipo di famiglia di device perché le librerie che uso sono specifiche.

Cambierò in corsa quello che mi ero prefissato di fare.
Sono certo che tutto ciò mi servirà come esperienza.

maubarzi:
E aggiungerci un cippettino di SRAM seriale?

La RAM connessa esternamente sul Atmega328 e ATmega32U4 non possono aumentare la RAM del controller. Percui non possono essere messi delle variabili usate dallo sketch. possono essere memorizzate delle informazioni come su un EEprom esterna.
Il ATmega2560 ha la possibilitá di estendere la RAM interna con un integrato SRAM esterno.
Vedi Upgrading RAM In An Arduino Mega | Hackaday
e Arduino MEGA 2560 32Kb RAM shield | Hackaday.io
e QuadRAM — Rugged CircuitsRugged Arduino

unsigned per risparmiare un byte

Una variabile unsigned non risparmia memoria rispetto la stessa signed. Viene spostato solo il range di valori memorizzabili.
un unsigned byte va da 0 a 255.
un signed byte va da -128 a +127 esatamente come l' altro 256 valori diversi.

@fotosettore il tuo discorso non mi piace, é polemico. 2 kByte di RAM di un controller con 32kByte di memoria codice nella maggiore delle volte bastano.
Ci sono dei casi dove un ATmega328 é troppo piccolo. In quel caso si deve usare una scheda con prestazioni maggiori. Molto semplice.

Un controller che sta sul Arduino UNO non é indicato per qualsiasi progetto. Certe applicazioni come audio, video e tanti dati come per esempio per display grandi.

Ci sono dei controller molto piú piccoli (a livello RAM/ROM e periferiche integrate) che hanno la loro giustificazione di esistenza.

Ciao Uwe

>fotosettore: ... sai quale è la risposta a tutte le tue critiche/osservazioni ? Una sola, hai sbagliato piattaforma !

Sul mercato ci sono un'infinità di MCU e schede di sviluppo con capacità di Flash e di SRAM adatte a tutte le applicazioni; se uno sceglie la piattaforma sbagliata per quello che deve fare, poi NON può lamentarsi che non bastano le risorse ... le risorse vanno valutate PRIMA di scegliere la piattaforma su cui realizzare quello che si vuole realizzare e NON a posteriori accorgendosi che non bastano per l'applicazione che si sta scrivendo.

Guglielmo

grazie a tutti per i preziosissimi consigli

fotosettore:
... ho consumato il 30% di spazio di flash .... e siamo al 55% di sram.

Cioè hai usato il 30% dei 64K per le istruzioni e il 55% dei 96K per le variabili?

Sarei curioso di capire in dettaglio cosa stai cercando di fare.
Comunque, la tua conclusione è sostanzialmente corretta, i limiti ci sono, come su tutto.
Io sono ancora intrigato a saturare Arduino UNO che ha utili 30K di flash e 2K di SRAM.
Ovviamente, questi aggeggi sono pensati per certi scopi, se ad es. vuoi mettere su un web server un minimo articolato allora non è la piattaforma giusta.
Ho letto che prevedevi anche un dbase, anche questa non sarebbe proprio nelle sue corde.
Puoi farlo, ma devi fare a pungi con i bit.

Tornando al discorso delle variabili da passare in giro che devono essere globali: dipende.
Bisognerebbe scendere nel merito, ma restando ad un discorso generico, ho visto cose che voi umani...
Nella maggior parte dei casi (nel tuo impossibile dirlo perchè non abbiamo visto il codice) il problema è di come viene scritto il codice. Ci sono soluzioni che non hanno nulla di logico e vengono utilizzate solo perchè è l'unico modo noto di affrontare un certo problema.
Ho visto gente usare db relazionali solo perchè sanno che è un modo comodo per memorizzare i dati, ma avrebbero ottenuto un risultato vari ordini di grandezza più efficiente usando semplici file di testo.
Un esempio su tutti? Il motore di wiki di Wikipedia. Ho buttato il naso su come è fatta e mi sono venuti i capelli dritti!
Ho trovato un altro motore di wiki che ha risolto il problema dei db in modo estremamente elegante, non lo ha usato :wink:
Parlo della parte per memorizzare le pagine, ha usato file di testo con delta delle revisioni in stile git.
Pagine statiche di testo con block chain delle revisioni per risalire a tutte le modifiche. Tutto per via testuale.
1000 volte più efficiente.

Ho letto che hai vincoli per rimanere su questa piattaforma per cui devi cercare di ricavarne il massimo.
Prova a seguire il consiglio dato riguardo l'ATmega2560 che puoi espandere con schede da 1/2Mb, come indicato in uno dei link di uwefed.
A differenza di quello che avevo suggerito io con la SRAM seriale che sarebbe una RAM da usare come appoggio ad accesso seriale, l'espansione, in questo caso è vera e l'accesso sarebbe parallelo.

Poi, se hai usato solo il 55% della SRAM, ne hai ancora parecchia, per le variabili locali, quindi non sei ancora a collo, come si suol dire.

Ultima cosa, se proprio arrivi al limite e ti serve ancora birra, ti puoi buttare sull'implementazione di un cluster, cioè più dispositivi specializzati su compiti differenti che comunicano tra di loro. Sarebbe sicuramente interessante come applicazione.