Ciao a tutti,
Qualcuno mi sa dire se esiste un comando per cancellare la RAM a fine ciclo?
Grazie
Ciao a tutti,
Qualcuno mi sa dire se esiste un comando per cancellare la RAM a fine ciclo?
Grazie
provato con la cancellina?
no dai scusa ma non ho resistito ;D
Mostra il codice così magari ci capiamo meglio.
E magari spiega cosa intendi per "cancellare la ram"
...con la cancellina è un casino... dovrei spotacciare tutto lo schermo...
Ho uno sketch che si blocca dopo una decina di giorni di funzionamento, mi basta staccare l'alimentazione che riparte.
Mi sembra di capire che ad un certo punto a RAM satura, arduinio si blocchi.
************
* Title :
* Version : v16
* Last updated : 14.09.15
* Target : Arduino UNO
* IDE : 1.0.6
* Installato il : 14 SETTEMBRE 2015
* NOTE : ACCENSIONE RITARDATA DI 300 SEC AL VOID SETUP
**************/
// INIZIO
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>
#include "EmonLib.h" // Include Emon Library
// MAC address for your Ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Your Xively key to let you upload data
char xivelyKey[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
/*
D1= ING Controlo Stato caldaia da D6
D2= OUT sempre hight per visualizzazione stato resistenza su xively
D3= ING DHT11
D6= OUT uscita in parallelo a D8 per visualizzazione stato caldaia su xively
D7= OUT relay ventola
D8= OUT relay caldaia
D9= ING Controllo Stato resistenza 2Kw interna al bollitore
*/
// Analog pin which we're monitoring (0 and 1 are used by the Ethernet shield)
// A0 Libero per Ethernet shield
// A1 Libero per Ethernet shield
int sensorPin_A2 = 2; //H2O_IN
float mediaA2; // media valori di A2
//A3 Amperometro Produzione Fotovoltaico FV
//A4 Amperometro Consumi in Casa
int sensorPin_A5 = 5; //H20_OUT
float mediaA5; // media valori di A5
int sensorPin_D1 = digitalRead(1); //STATO CALDAIA
int sensorPin_D3 = digitalRead(3); //DHT11
int sensorPin_D9 = digitalRead(9); //STATO RESISTENZA
const float AnaRef = 5.0; // valore tensione pin di riferimento tensione AREF(5V)
const unsigned int Risoluzione = 1024; // risoluzione (10 bit)
const float RangeMin = 2.0; // temperatura minima °C sensore LM35DZ (alim. 5V, out con res. 2k in serie)
const float RangeMax = 100.0; // temperatura massima °C sensore LM35DZ (alim. 5V, out con res. 2k in serie)
const float Incremento = 0.01; // incremento (10 mV/°C)
float Volt = 0; // valore sensori analogici in volt
const float Isteresi = 1.0; // isteresi (1 °C)
float TA = 0.0; // TA = temperatura aria
float TAM = 2.0; // soglia inferiore temperatura aria (min 2 °C = RangeMin) TAM=TempAriaMin
float TAMAX = 30.0; // soglia superiore temperatura aria (max 100 °C = RangeMax) TAMAX=TempAriaMax
float ToutW = 0.0; // temperatura acqua "TempAcquaOUTtermosolare" = ToutW
float TWMIN = 2.0; // soglia inferiore temperatura acqua (min 2 °C) TWMIN=TempAcquaMin
float TWMAX = 43.0; // soglia superiore temperatura acqua (max 100 °C) TWMAX=TempAcquaMax
float TinW = 0.0; // temperatura acqua in ingresso al termosolare "TempAcquaINGtermosolare" = TinW
EnergyMonitor emon1; // Create an instance CORRENTE GENERATA DAL FOTOVOLTAICO
float media_emon1;
EnergyMonitor emon2; // Create an instance CORRENTE CONSUMATA IN CASA
float media_emon2;
extern unsigned long timer0_millis;
float ConteggioMillis;
// Define the strings for our datastream IDs
char sensorId[] = "2-Temperatura_esterna";
char sensorId1[] = "3-Umidita_esterna";
char sensorId2[] = "6-H2O_Out";
char sensorId3[] = "5-H2O_In";
char sensorId4[] = "4-Ambiente";
char sensorId5[] = "0-Energia_Produzione";
char sensorId6[] = "1-Energia_Consumo";
char sensorId7[] = "7-Caldaia";
char sensorId8[] = "8-R2KW";
XivelyDatastream datastreams[] = {
XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
XivelyDatastream(sensorId1, strlen(sensorId1), DATASTREAM_FLOAT),
XivelyDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
XivelyDatastream(sensorId3, strlen(sensorId3), DATASTREAM_FLOAT),
XivelyDatastream(sensorId4, strlen(sensorId4), DATASTREAM_FLOAT),
XivelyDatastream(sensorId5, strlen(sensorId5), DATASTREAM_FLOAT),
XivelyDatastream(sensorId6, strlen(sensorId6), DATASTREAM_FLOAT),
XivelyDatastream(sensorId7, strlen(sensorId7), DATASTREAM_FLOAT),
XivelyDatastream(sensorId8, strlen(sensorId8), DATASTREAM_FLOAT),
//XivelyDatastream(sensorId10, strlen(sensorId10), DATASTREAM_FLOAT),
};
// Finally, wrap the datastreams into a feed
XivelyFeed feed(xxxxxxxxxx, datastreams, 9 /* number of datastreams */);
EthernetClient client;
XivelyClient xivelyclient(client);
/////////////////////////////////FINE INIZIALIZZAZIONE XIVELY
//
// FILE: dht11_test1.pde
// PURPOSE: DHT11 library test sketch for Arduino
// DHT11 connesso a pin DIGITALE 3
//
//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
return 1.8 * celsius + 32;
}
//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
return celsius + 273.15;
}
// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm
double dewPoint(double celsius, double humidity)
{
double C= 373.15/(273.15 + celsius);
double SUM = -7.90298 * (C-1);
SUM += 5.02808 * log10(C);
SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/C)))-1) ;
SUM += 8.1328e-3 * (pow(10,(-3.49149*(C-1)))-1) ;
SUM += log10(1013.246);
double VP = pow(10, SUM-3) * humidity;
double T = log(VP/0.61078); // temp var
return (241.88 * T) / (17.558-T);
}
// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
double a = 17.271;
double b = 237.7;
double temp = (a * celsius) / (b + celsius) + log(humidity/100);
double Td = (b * temp) / (a - temp);
return Td;
}
#include <dht11.h>
dht11 DHT11;
#define DHT11PIN 3 // PIN DIGITALE 3
void setup() //////// SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP
{
delay (300000); //RITARDO ACCENSIONE ARDUINO PER PERMETTERE AL MODEM TIM DI ALLINEARSI
Serial.begin(9600);
Serial.println(F("DHT11 TEST PROGRAM "));
Serial.print(F("LIBRARY VERSION: "));
Serial.println(F(DHT11LIB_VERSION));
Serial.println();
Serial.println(F("Starting single datastream upload to Xively..."));
Serial.println();
while (Ethernet.begin(mac) != 1)
{
Serial.println(F("Error getting IP address via DHCP, trying again..."));
delay(15000);
}
/////////////////////////////////////////////////////////
ConteggioMillis=1;
analogReference(DEFAULT); // DEFAULT (5V), INTERNAL (1,1V), EXTERNAL (0÷5V)
//////////////////////////////////////////////////////////
pinMode(A2, INPUT); // sensore A2 di temp. acqua ING termosolare (TinW)
pinMode(A3, INPUT); // TA Fotovoltaico (Produzione_Energia)
pinMode(A4, INPUT); // TA Casa (Consumo_Energia)
pinMode(A5, INPUT); // sensore A1 di temp. acqua OUT termosolare (ToutW)
pinMode(1, INPUT); //*D1 ingresso controllo stato caldaia da D6
pinMode(2, OUTPUT); // D2 uscita per relè in parallelo alla resistenza 2Kw installata sul bollitore
pinMode(3, INPUT); //*D3 ingresso controllo stato ventola da D5?????????????
pinMode(4, OUTPUT); // TENTATIVO DI NON FAR BLOCCARE LA SCHEDA ETHERNET http://forum.arduino.cc//index.php?topic=186039.15
pinMode(6, OUTPUT); //*USCITA IN PARALLELO AL RELE ACQUA PER VISUALIZZAZIONE WEB STATO CALDAIA
pinMode(7, OUTPUT); // relay ventola ON/OFF
pinMode(8, OUTPUT); // relay caldaia ON/OFF
pinMode(9, INPUT); // D9 ingresso per relè in parallelo alla resistenza da 2Kw installata sul bollitore
pinMode(10, OUTPUT); // TENTATIVO DI NON FAR BLOCCARE LA SCHEDA ETHERNET http://forum.arduino.cc//index.php?topic=186039.15
//////////////// AMPEROMETRI
emon1.current(3, 500); // Current: A3 -CORRENTE GENERATA DAL FOTOVOLTAICO- input pin, calibration (118 valore di calibrazione da gtrovare manualmente)
emon2.current(4, 500); // Current: A4 -CORRENTE CONSUMATA IN CASA- input pin, calibration (118 valore di calibrazione da gtrovare manualmente)
///////////////////////////
}
void loop() //////// LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP
{
digitalWrite(2, HIGH); // attivazione uscita D2 sempre high per controllo stato resistenza
mediaA2=0; // media valori di A2
mediaA5=0; // media valori di A5
media_emon1=0; // media valori di emon1 A3
media_emon2=0; // media valori di emon2 A4
Serial.println(F("\n"));
int chk = DHT11.read(DHT11PIN);
Serial.print(F("Read sensor: "));
switch (chk)
{
case 0: Serial.println("OK");
// DHT11 TEMPERATURA
Serial.print(F("Temperature Esterna Casa(oC): "));
Serial.println((float)DHT11.temperature, 2);
datastreams[0].setFloat(DHT11.temperature);
//Serial.print(F("Read sensor value "));
//Serial.println(datastreams[0].getFloat());
/* //DHT11 UMIDITA' *******NON PRECISO********
Serial.print(F("Humidity (%): "));
Serial.println((float)DHT11.humidity, 2);
datastreams[1].setFloat(DHT11.humidity);
Serial.print(F("Read sensor value "));
Serial.println(datastreams[1].getFloat());
*/
//Serial.println(F("Uploading it to Xively"));
/*int ret = xivelyclient.put(feed, xivelyKey);
Serial.print(F("xivelyclient.put returned "));
Serial.println(ret);
Serial.println();
delay(2000);
*/
break;
case -1: Serial.println(F("Checksum error")); break;
case -2: Serial.println(F("Time out error")); break;
default: Serial.println(F("Unknown error")); break;
}
Serial.println(F("xivelyclient.put returned "));
delay(10);
/* ********DISCONNESSO*******
// MONITORAGGIO A0 sensore di temperatura aria (TA)
// sensorId4[] = "4-Ambiente";
int sensorValue_A0 = ((5.0 * analogRead(sensorPin_A0) * 100.0) / 1024)+0; // sensore di temperatura aria (TA)
for (int i=0; i<100; i++){
mediaA0+=(5.0 * analogRead(sensorPin_A0) * 100.0) / 1024;
}
mediaA0=mediaA0/100;
datastreams[4].setFloat(mediaA0);
delay(10);
Serial.print("A0= ");
Serial.print(datastreams[4].getFloat());
if (mediaA0 >= (TAMAX + Isteresi)) {
digitalWrite(7, HIGH); // relay ventola ON
Serial.println(F(" Aria >30°C - Ventola ON"));
}
else if (mediaA0 < (TAMAX - Isteresi)) {
digitalWrite(7, LOW); // relay ventola OFF
Serial.println(F(" Aria <30°C - Ventola OFF"));
}
*/
// MONITORAGGIO sensore A5 di temp. acqua OUT termosolare(ToutW)
// sensorId2[] = "6-H2O_Out";
int sensorValue_A5 = ((5.0 * analogRead(sensorPin_A5) * 100.0) / 1024)+4; // sensore di temp. acqua OUT termosolare(ToutW)
for (int i=0; i<100; i++){
mediaA5+=(5.0 * analogRead(sensorPin_A5) * 100.0) / 1024;
}
mediaA5=((mediaA5/100)+1);
datastreams[2].setFloat(mediaA5);
delay(10);
Serial.print(F("H2O_Out= "));
Serial.println(datastreams[2].getFloat());
if ((sensorPin_A5 > (TWMAX + Isteresi)) && ConteggioMillis==1) (timer0_millis = 0, ConteggioMillis = 0 );
if ( sensorPin_A5 > (TWMAX + Isteresi) && (millis()>30000)) {
delayMicroseconds(120); // 120 µs (min time reading = 100 µs x channel)
digitalWrite(8, LOW); // relay caldaia OFF
digitalWrite(6, LOW); //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
Serial.println(F(" Temp. Acqua Bollitore >43°C - Caldaia OFF"));
}
else if (mediaA5 < (TWMAX - Isteresi)) {
digitalWrite(8, HIGH); // relay caldaia ON
digitalWrite(6, HIGH); //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
ConteggioMillis=1;
Serial.println(F(" Temp. Acqua Bollitore <43°C - Caldaia ON"));
}
// MONITORAGGIO sensore A2 di temperatura acqua ingresso termosolare (TinW)
// sensorId3[] = "5-H2O_In";
int sensorValue_A2 = ((5.0 * analogRead(sensorPin_A2) * 100.0) / 1024)+0; // sensore di temperatura acqua ingresso termosolare (TinW)
for (int i=0; i<100; i++){
mediaA2+=(5.0 * analogRead(sensorPin_A2) * 100.0) / 1024;
}
mediaA2=((mediaA2/100)+1);
datastreams[3].setFloat(mediaA2);
delay(10);
Serial.print(F("H20_IN= "));
Serial.println(datastreams[3].getFloat());
// **************INIZIO MONITORAGGIO FOTOVOLTAICO***************
// sensorId5[] = "0-Energia_Produzione";
double Produzione_Energia = (emon1.calcIrms(1480)-0); // Calculate Irms only
for (int i=0; i<100; i++){
media_emon1+=Produzione_Energia; // Amperer misurati da TA connesso ad A3
}
media_emon1=media_emon1/100;
media_emon1=(media_emon1*220);
if (media_emon1<140)
{
media_emon1=0; // da valore 0 in cui la misura sia monima, ciò per evitare false misure soprattutto in assenza di sole
}
datastreams[5].setFloat(media_emon1);
delay(10);
Serial.print(F("FV= "));
Serial.println(datastreams[5].getFloat());
// sensorId6[] = "1-Energia_Consumo";
double Consumo_Energia = emon2.calcIrms(1480); // Calculate Irms only
for (int i=0; i<100; i++){
media_emon2+=Consumo_Energia; // Amperer misurati da TA connesso ad A4
}
media_emon2=media_emon2/100;
media_emon2=(media_emon2*220);
datastreams[6].setFloat(media_emon2);
delay(10);
Serial.print(F("Casa= "));
Serial.println(datastreams[6].getFloat());
// ************FINE MONITORAGGIO FOTOVOLTAICO***************
// sensorId7[] = "7-Caldaia";
int sensorValue_D1 = digitalRead(1);
datastreams[7].setFloat(sensorValue_D1);
Serial.print(F("Caldaia= "));
Serial.println(datastreams[7].getFloat());
// sensorId8[] = "8-R2KW";
int sensorValue_D9 = digitalRead(9);
datastreams[8].setFloat(sensorValue_D9);
Serial.print(F("Resistenza= "));
Serial.println(datastreams[8].getFloat());
Serial.println(F("Uploading it to Xively"));
int ret = xivelyclient.put(feed, xivelyKey);
Serial.print(F("xivelyclient.put returned: "));
Serial.println(ret);
Serial.println();
delay(1000);
/////////////////////////////////////////////
}
E perchè la ram si dovrebbe riempire proprio dopo 10 gg?
Cè una parte di codice allora che parte dopo 10 gg ed è sbagliata, la ram usata la stabilisci tu con le variabili globali e quelle locali, le globali sono intoccabili occuperanno sempre lo stesso spazio anche quando entri nelle funzioni dove non sono usate, quelle locali vengono distrutte quando esci dalla funzione o ciclo come lo definisci tu.
ad esempio è importante dichiarare questi pin come INT invece che BYTE?
int sensorPin_A2 = 2; //H2O_IN
int sensorPin_A5 = 5; //H20_OUT
int sensorPin_D1 = digitalRead(1); //STATO CALDAIA
int sensorPin_D3 = digitalRead(3); //DHT11
int sensorPin_D9 = digitalRead(9); //STATO RESISTENZA
ma soprattutto è necessario avere tutte quelle var globali che impegnano ram?
ad esempio invece di usare "int sensorPin_D9 = digitalRead(9); //STATO RESISTENZA" non puoi mettere digitalRead(9) nel punto del programma in cui ti serve?
tutti quei char sensorId[] 1-2-3-4-5 .... non puoi metterli locali? o in flash?
se puoi non utilizzare il pin 4 e nel setup mettilo in HIGH anche il pin 10 va messo nel setup in HIGH
E sono questi i momenti dove capisce il terribile lato di Arduino.
Devi sapere che le macchine generalmente usano due tipi di allocazioni delle risorse, una statica (i dati vengono allocati nello stack) e dinamica (i dati vengono allocati nell'heap).
Ora stare qui a spiegare le differenze e come funziona l'allocazione della memoria risulta impossibile, ti rimanderei a qualche ricerca su Google o meglio uno studio dell'architettura della memoria.
Ti basti sapere che quando dichiari una variabile di tipo base (intero, byte, float, ecc) e anche agglomerati di essi cioè strutture, queste vengono allocate nello stack, il compilatore sa bene quanta memoria serve al programma per funzionare. Nasce ora un problema, lo stack è tutto bello ordinato, ma tutti gli oggetti come le liste dove vanno a finire visto che queste possono essere inizializzate in runtime, beh esiste una seconda parte di memoria chiamata heap (memoria dinamica). questo heap è situato nello stesso luogo fisico dello stack, ma mentre il primo cresce come una pila dall'ultimo spazio di memoria disponibile verso il primo, l'heap fa il contrario e nulla vieta che questi due spazi cozzino e si vadano a sovrascrivere a vicenda, su PC questo non succede primo perché il kernel impone dei sistemi di verifica per impedirlo e secondo la memoria nella maggior parte dei casi è in esubero.
Quindi sta a te il controllo che questi due spazi non entrino in conflitto, come fare? beh il compilatore si occupa di gestire lo stack tu devi occuparti dell'heap, quando finisci di usare un oggetto devi eliminarlo dalla memoria con una chiamata a free. è anche questo uno dei motivi che spinge i programmatori di un certo livello a fare a meno di oggetti dinamici o ridurre il loro utilizzo al minimo indispensabile.
@gelholder bhè se il problema è solo quello visualizzato a video potresti metterci dei post-it sopra
nel codice postato da @pablos ci sarebbe anche da dire che non andrebbe mai fatto! ma mettiamoci un post-it sopra e facciamo finta di niente.
Il reale problema potrebbe essere questo:
if ( sensorPin_A5 > (TWMAX + Isteresi) && (millis()>30000))
millis() è un contatore che parte da 0 quando accendi la scheda e somma 1 ad ogni millisecondo, in quel frammento di codice dopo 30 secondi dall'accensione eseguirai sempre quell'if se il sensorPin_A5 è maggiore dell'isterisi piu TWMAX.
Millis però è una variabile di tipo unsigned long e una volta che raggiunge il suo valore massimo ritorna a 0 e questo accade dopo circa 50 giorni.
Io ti consiglio di ripulire il codice con un pò di olio di gomito e di sistemare un pò la sua logica.
Per scoprire se finisci la ram:
quale ide usi? 1.0 o 1.6?
@RobertoBochet non usa l'heap!
RobertoBochet:
E sono questi i momenti dove capisce il terribile lato di Arduino.
Devi sapere che le macchine generalmente usano due tipi di allocazioni delle risorse, una statica (i dati vengono allocati nello stack) e dinamica (i dati vengono allocati nell'heap).
Sugli AVR programmati con avr-gcc le variabili globali vengono poste in una apposita area riservata all'inizio della ram, nello stack ci vanno solo i dati per i salti alle subroutine quali indirizzo di ritorno e stato macchina, le variabili locali vengono poste ultizzando i 32 SFR generici degli AVR e, ovviamente, vengono automaticamente azzerati e riciclati quando si cambia routine.
L'heap è riservato alla memoria dinamica e alle variabili locali dichiarate static, ovvero mantengono il loro ultimo valore e non vengono distrutte.
Dato che in avr-gcc non esiste nessun sistema di pulizia e ordinamento automatico del heap, normalmente presente su processori di classe maggiore e veri compilatori C++, è facile che abusando della memoria dinamica, p.e. con l'oggetto String, questa a va scontrarsi con quella dello stack, che parte dalla fine della ram a scendere, con effetti catastrofici sull'esecuzione del codice.
Quanto sopra è uno dei motivi principali per cui il C++, anzi il quasi C++ offerto da avr gcc, è il male assoluto sulle piccole mcu, oltre allo spreco di preziosa ram.
Caspita ragazzi!
Devo ammettere che ci sono molti concetti che dovrò studiare per comprendere le vostre risposte.
Comunque, ciò che ho notato nello sketch è dopo aver aggiunto F() nei vari Serial.print di costanti testo, arduino funziona bene per una decina di giorni contro i 2gg di prima.
Ma... giusto per capire, non esiste quindi un comando che ponendolo a fine ciclo cancella la RAM tipo ciò che succede nel momento in cui si toglie l'alimentazione alla scheda?
L'IDE che sto usando è: 1.0.6
...ed io che ero così orgoglioso del mio Arduino connesso a xively...
Grazie
vbextreme:
@RobertoBochet non usa l'heap!
Insomma adopera oggetti come EthernetClient, XivelyClient o dht11.
Esistono scketch che se caricati sull'Arduino tengono traccia della memoria adoperata.
Esempio www.leonardomiliani.com/2012/come-sapere-loccupazione-di-ram-del-proprio-sketch/
Astro come al solito ha chiarito ulteriormente il funzionamento degli AVR, la storia delle variabili locali allocate esternamente allo stack non la conoscevo, grazie per la precisazione.
L'uso della macro F() non puo essere che raccomandato, e dalla tua affermazione si capisce che è quasi sicuramente un problema di allocazione della memoria, ma come dice Astro su AVR non esiste una specie di GC per tanto la memoria dinamica va liberata manualmente.
Io farei qualche test con lo scketch di leonardo giusto per garanzia in più che il problema stia li.
Grazie del link, vediamo cosa riesco a combinare...
Insomma adopera oggetti come EthernetClient, XivelyClient o dht11.
Da quel che ricordo io nessuna delle due usa l'heap, la x non la conosco.
Naturalmente bisognerebbe spulciare per benino il codice.
Sono oggetti, per definizione del C++ sono allocati nell'heap, il fatto che non sia esplicito il new non vuol dire che non vengano create delle istanze delle suddette classi.
Sono oggetti, per definizione del C++ sono allocati nell'heap
Assolutamente errato! gli oggetti vengono creati nello stack e non nell'heap, almeno che non vengano esplicitamente allocati dinamicamente con la new.
vbextreme:
Assolutamente errato! gli oggetti vengono creati nello stack e non nell'heap,
Ma assolutamente no, e vale per tutti i micro e i compilatori di questo mondo visto che è una caratteristica hardware e non prettamente software, lo stack è una memoria di tipo LiFo gestita tramite il registro SP, Stack Pointer che esiste in tutti i micro/mcu anche se in alcuni casi è gestito esclusivamente ad hardware.
Lo stack viene usato esclusivamente per i dati da salvare quando si richiama una subroutine o una ISR, al massimo viene usato come memoria temporanea per i risultati intermedi dei calcoli o per passare gli indici degli eventuali vettori alla funzione chiamata.
In quasi tutti i micro/mcu, diciamo pure il 99.99%, sono presenti le istruzioni assembly "push" e "pop", e non solo loro, che permettono di incrementare/decrementare di una posizione lo Stack Pointer e porre/estrarre una word (8-16-32-64 byte a seconda dell'architettura del micro) nello stack che è un'area di ram riservata, a seconda del micro può essere fissa perché determinata in hardware dal produttore oppure assegnata a software.
Mai e poi mai lo stack viene usato per le variabili locali, queste vengono allocate negli SFR, o nel heap se sono finiti, nel caso degli AVR usando avr-gcc, in area di memoria dedicata e riservata per altri modelli di micro e compilatori, come viene gestita la cosa dipende dal compilatore e non dal micro.
... c'è un bell'articoletto di Leo sull'utilizzo della memoria, semplice, schematico e chiaro ... QUI
Guglielmo
si comunque non finisce nell'heap!
Li ci finiscono solo le cose dinamiche!
Ovvio che nello stack ci possono finire solo le variabili di una funzione che non siano dichiarate statiche e quelle globali nei propri segmenti.
La cosa mi sembra sempre più complessa...
gpb01:
... c'è un bell'articoletto di Leo sull'utilizzo della memoria, semplice, schematico e chiaro ... QUIGuglielmo
Fortiguard mi blocca l'accesso. Maledizione!
Ma solo a quella pagina, sembra.
Ho appena verificato la pagina QUI indicata e non ha alcun problema ... è molto probabilmente un falso positivo di Fortiguard.
Guglielmo