Pages: 1 [2] 3 4   Go Down
Author Topic: Verificare SRAM utilizzata  (Read 2290 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Astro mi ricorda che c'e' la possibilità di usare la flash, probabilmente con "progmem" che ho sempre lasciato come ultima spiaggia poichè in diversi post lessi che non è proprio il massimo dell'affidabilità ed efficienza, senza mai leggere il perchè.
L'affidabilità è massima, dalla Flash i dati sono letti così come lo è il codice.
Se sono stringhe e devi stamparle, puoi usare la funzione F(), introdotta con l'IDE 1.0, che maneggia in automatico tali dati dalla Flash. Se i tuoi dati sono invece array di byte/char, con un paio di mal di testa riuscirai a gestire i dati dalla Flash  smiley-sweat
Ricordati però che puoi gestire solo costanti, non dati cioè che devono cambiare in fase di elaborazione.
Logged


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

Qui
http://arduino.cc/forum/index.php/topic,120603.msg908145.html#msg908145
c'è un esempio di array di byte letto direttamente dalla Flash. Alla fine, sono poche righe di codice, come vedi
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2754
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie ... ti meriti una confezione di karma. Ma con karma però una alla volta ehehehhe

si sono degli array di byte
il file è così composto i numeri sono di esempio, in realtà saranno byte di giorni mesi ore e minuti + 2 byte di enable

[digital PORT ON timer]
(portimer_hi150) = 53,54,55,56,57,58
(portimer_hi151) = 59,60,61,62,63,64
(portimer_hi152) = 65,66,67,68,69,80
(portimer_hi153) = 81,82,83,84,85,86
(portimer_hi154) = 87,88,89,90,91,92
(portimer_hi155) = 93,94,95,96,97,98
(portimer_hi156) = 03,04,05,06,07,08
(portimer_hi157) = 08,10,12,14,16,18

(portimer_hi160) = 53,54,55,56,57,58
(portimer_hi161) = 59,60,61,62,63,64
(portimer_hi162) = 65,66,67,68,69,80
(portimer_hi163) = 81,82,83,84,85,86
(portimer_hi164) = 87,88,89,90,91,92
(portimer_hi165) = 93,94,95,96,97,98
(portimer_hi166) = 03,04,05,06,07,08
(portimer_hi167) = 08,10,12,14,16,18
....... ecc ecc per 30 porte dalla 15 alla 45
« Last Edit: November 21, 2012, 04:34:42 pm by pablos » Logged

Meglio imparare dalle cose inutili piuttosto che non imparare niente.   [Arduino Mega R3 + Ethernet shield W5100 + SD card 8Gb FAT32]

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

Grazie ... ti meriti una confezione di karma. Ma con karma però una alla volta ehehehhe
Con molta caRma  smiley-wink

Quote
si sono degli array di byte
il file è così composto i numeri sono di esempio

Uhm.. leggi i dati da un file?
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2754
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

si leggo da un txt creato da un prog eseguibile

nello sketch vengono organizzati cosi'

Code:
...
...
              
void get_port_timer()
{
  char *p = charBuf;  
  byte i = 0;
   while (*p != '\0')  
  {
    if (*p == ',') { ++i;  ++p;  continue;}
        if (isdigit(*p))
        {
            if(tipo_str == 7)
            {
             port_on[x][y][i] *= 10;
             port_on[x][y][i] += (*p - '0');
            }

             if(tipo_str == 8)
            {
             port_off[x][y][i] *= 10;
             port_off[x][y][i] += (*p - '0');          
            }
        }  
    ++p;
  }    
}

che funziona bene, ma sappiamo già qual'è il limite
« Last Edit: November 22, 2012, 04:11:02 am by pablos » Logged

Meglio imparare dalle cose inutili piuttosto che non imparare niente.   [Arduino Mega R3 + Ethernet shield W5100 + SD card 8Gb FAT32]

Offline Offline
Sr. Member
****
Karma: 7
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Visto però che l'allocazione dinamica è usata raramente, nella maggior parte delle volte la memoria SRAM è occupata da .data, .bss e stack.

un'ultima cosa poi posso dormire più tranquillo: il tipo in avrfreaks scriveva che il compilatore gli dava fuori questa cosa...
Code:
AVR Memory Usage
----------------
Device: atmega16

Program:   14362 bytes (87.7% Full)
(.text + .data + .bootloader)

Data:        635 bytes (62.0% Full)
(.data + .bss + .noinit)

leggevi qua no?
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=818461

be comunque quello che ho notato è che il compilatore dava 62% full nel data segment...con 635 byte... significa che in pratica c'è un segmento dati che viene allocato con al massimo 1k di ram?
Adesso mi pare che quando trafficavo con i 2/386 c'era un segmento dati ed un segmento codice e c'erano delle limitazioni sulla lunghezza dei segmenti...anche qua?
Logged

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

@pablos:
se leggi i dati da un file, non puoi usare PROGMEM. I dati dovresti trascriverli in un array all'interno del tuo programma, così che puoi trasformarli in PROGMEM e recuperarli da Flash. Potresti anche inserirli in un file .h che alleghi allo sketch in fase di compilazione.
Però i dati devono comunque essere presenti nel firmware, non puoi scriverli in Flash leggendoli da un file.

1) Però, visto che "peschi" da un file, necessiti di una elaborazione molto veloce? Non potresti leggerli sempre dalla SD?
2) Visto che l'Atmega2560 ha 4 kB di Flash, io non starei a farmi tante seg*e mentali: farei uno sketch che mi carica i dati e da lì poi li leggo. Anzi, avendo 4 kB di spazio, puoi anche infilarci la tabella completa (avevi detto che l'avevi troncata per motivi di spazio, giusto?).

@qsecofr:
sì, leggevo da lì.
Nei sistemi x86 si lavora con architetture Von Neumann, nei chip Atmel con architetture Harvard. In quest'ultime la memoria dati e la memoria del codice sono separate per cui la dimensione massima per le variabili, lo stack e l'heap è fissa.
Nel caso in oggetto, l'Atmeg16 ha 1024 byte per cui l'occupazione di .data (le variabili dichiarate), .bss e .noinit (le variabili non inizializzate) occupano 635 byte di SRAM. Il resto è a disposizione dello stack, dell'heap e degli eventuali dati creati dinamicamente.

(ho capito la tua domanda?)
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2754
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
1) Però, visto che "peschi" da un file, necessiti di una elaborazione molto veloce? Non potresti leggerli sempre dalla SD?
L'accesso alla SD non è sta gran cosa  smiley-roll

Quote
2) Visto che l'Atmega2560 ha 4 kB di Flash, io non starei a farmi tante seg*e mentali: farei uno sketch che mi carica i dati e da lì poi li leggo. Anzi, avendo 4 kB di spazio, puoi anche infilarci la tabella completa
Flash Memory 256 KB of which 8 KB used by bootloader
SRAM   8 KB
EEPROM 4 KB


Quote
(avevi detto che l'avevi troncata per motivi di spazio, giusto?).
Si, per motivi di spazio.
Ma non ho capito il discorso di infilarci la tabella completa... dove me la infilo sta tabella ahahahahhaha
Logged

Meglio imparare dalle cose inutili piuttosto che non imparare niente.   [Arduino Mega R3 + Ethernet shield W5100 + SD card 8Gb FAT32]

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

Quote
2) Visto che l'Atmega2560 ha 4 kB di Flash, io non starei a farmi tante seg*e mentali: farei uno sketch che mi carica i dati e da lì poi li leggo. Anzi, avendo 4 kB di spazio, puoi anche infilarci la tabella completa
Flash Memory 256 KB of which 8 KB used by bootloader
SRAM   8 KB
EEPROM 4 KB
Scusami. Volevo dire EEPROM!
Carichi i dati su EEPROM con un altro sketch, poi carichi lo sketch che userà tali dati. Invece di accedere all'array accederai direttamente alla cella in memoria.
Così i dati potranno essere 4096, tanto la EEPROM mica la usi per altre cose, o no?
Logged


Offline Offline
Sr. Member
****
Karma: 7
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nel caso in oggetto, l'Atmeg16 ha 1024 byte per cui l'occupazione di .data (le variabili dichiarate), .bss e .noinit (le variabili non inizializzate) occupano 635 byte di SRAM. Il resto è a disposizione dello stack, dell'heap e degli eventuali dati creati dinamicamente.
(ho capito la tua domanda?)

perfettamente... allora se è così io metterei come possibilità di vedere se comandando il compilatore si può aumentare di qualche k lo spazio .data oppure procederei ad allocare 'ste tabelle grossine in heap... la funzione malloc c'è e funziona vero? ... dopo mi attacco la scheda e provo.
o se no vedere di dichiarare localmente il più possibile.... le variabili locali dove le butta? heap o stack?
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2754
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Infatti la priorità era ottimizzare lo sketch togliendo tutte le variabili pubbliche, usarle localmente ed eventualmente passarle alle funzioni solo quando vengono richiamate (questo non è il mio forte).

Sono i classici errori che si fanno quando si inizia un programmino, si mette tutto all'inizio, si dichiarano variabili INT quando assumeranno valori < di 255, non si usano localmente, non si bada al risparmio tanto lo sketch è piccolo. Poi quando si vanno a prendere i pezzetti e si uniscono  per fare un progetto un po' più pesante bisogna rivedere tutto.

Logged

Meglio imparare dalle cose inutili piuttosto che non imparare niente.   [Arduino Mega R3 + Ethernet shield W5100 + SD card 8Gb FAT32]

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

perfettamente... allora se è così io metterei come possibilità di vedere se comandando il compilatore si può aumentare di qualche k lo spazio .data
No, aspetta. Non puoi aumentare di "qualche k" lo spazio delle variabili  smiley-wink
La memoria SRAM sugli Atmega328 non è espandibile. Esistono solo pochi chip Atmel che hanno la possibilità di accedere a della RAM esterna allargando lo spazio degli indirizzi. Io conosco l'Atmega128 e l'Atmega2560, probabilmente ce ne sono altri, ma non mi ricordo. Ma tornando all'Arduino, hai una SRAM di 2 kB (sull'Atmega328) e quella resta.
L'unico modo per non saturare la RAM è: ottimizzare.
Ad esempio, abbiamo visto che la seriale occupa 128 byte di SRAM per i suoi buffer. Durante il debug può essere utile ma, una volta sviluppato lo sketch, se non serve espressamente leviamola.

Dichiariamo tutte la variabili usando il giusto tipo. Vedo spesso dichiarazioni del tipo "int LED = 13;". Si usa un dato che occupa 2 byte ed il cui valore max è molto superiore al numero che si sta memorizzando quando si potrebbe usare un tipo "byte" che occupa 1 solo byte e che contiene lo stesso il numero in questione senza problemi.

Non tutti sanno che il tipo boolean è in realtà un tipo char/byte ed occupa 1 byte anch'esso. Spesso si potrebbe risparmiare memoria adottando dei flag piccolissimi, semplicemente manipolando i singoli bit di un byte: in questo modo in un unico byte ci stanno 8 flag.

Ecc...

Quote
oppure procederei ad allocare 'ste tabelle grossine in heap... la funzione malloc c'è e funziona vero? ... dopo mi attacco la scheda e provo.
Qui sono curioso, non ho molta pratica di gestione dinamica della memoria.

Quote
o se no vedere di dichiarare localmente il più possibile.... le variabili locali dove le butta? heap o stack?
Le butta in .data e .bss. Nello stack ci stanno altri dati:
Nello stack ci vengono memorizzati il PC (Program Counter) quando viene chiamata una funzione in modo da sapere da dove riprendere l'esecuzione del programma, i registri di sistema quando vengono chiamati gli interrupt che sospendono il codice principale  della funzione chiamante.
Insomma, tutta quella roba che varia continuamente durante l'esecuzione di un programma.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"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

usarle localmente ed eventualmente passarle alle funzioni solo quando vengono richiamate (questo non è il mio forte).

Attenzione che le variabili locali sono disponibili solo all'interno della funzione che le dichiara, le puoi passare ad altre funzioni solo se richiamate all'interno di questa, non puoi passarle dalla loop() a meno che non hai una return con il relativo valore da utilizzarsi come valore da passare ad un'altra funzione.

Quote
si dichiarano variabili INT quando assumeranno valori < di 255, non si usano localmente,

quella della dichiarazione come int di tutte le variabili è una bruttissima abitudine che deriva da vari esempi, sia ufficiali che di utenti, per Arduino, chi non conosce a fondo la questione, leggi principiante, pensa che sia normale utilizzare int per le variabili e continua a farlo.
Il discorso variabili globali e locali è da pesare attentamente ogni volta, a favore delle variabili globali è che sono disponibili sempre per tutte le funzioni e che richiedono un tempo d'accesso minore rispetto alle locali, il motivo è dovuto al diverso tipo di indirezzamento, diretto per le globali, indiretto e tramite un array per le locali.
Per contro le variabili globali consuma sempre memoria in modo fisso e incrementale, più ne usi più memoria serve, non esiste una vera e propria regola su come distribuire le variabili tra locali e globali, però in linea di massima possiamo dire che se una variabile deve essere utilizzata da più funzioni è meglio dichiararla come globale.
Se la variabile viene utilizzata solo da una/due funzione/i e dal main loop, o serve esclusivamente ad uso interno della stessa, è sicuramente meglio dichiararla come locale a meno che non sia importante recuperare qualche ciclo macchina ai fini della velocità di esecuzione, è valido nel caso di una funzione che viene richiamata ciclicamente molto spesso e/o viene utilizzata all'interno di un ciclo con molte iterazioni.
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2754
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void setup()
{
  Serial.begin(9600);
  byte A = 200;
  String B = "mia stringa";
  test(A,B);
}

void test (byte var_1, String var_2)
{
  Serial.print((String)var_1 + "  " + var_2);
}

void loop() {}

questo crea temporaneamente e distrugge le varibili al termine delle funzioni ... è corretto?
Logged

Meglio imparare dalle cose inutili piuttosto che non imparare niente.   [Arduino Mega R3 + Ethernet shield W5100 + SD card 8Gb FAT32]

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

Il tuo sketch restituisce questo:
Code:
AVR Memory Usage
----------------
Device: atmega328p

Program:    3994 bytes (12.2% Full)
(.text + .data + .bootloader)

Data:        235 bytes (11.5% Full)
(.data + .bss + .noinit)

Usando variabili globali per A e B, si ha invece:
Code:
AVR Memory Usage
----------------
Device: atmega328p

Program:    4062 bytes (12.4% Full)
(.text + .data + .bootloader)

Data:        244 bytes (11.9% Full)
(.data + .bss + .noinit)
Logged


Pages: 1 [2] 3 4   Go Up
Jump to: