Come scoprire errori di overflow della memoria nel codice Arduino C?


10

Diverse volte ho avuto alcuni output sospetti sul monitor seriale dopo aver caricato il codice su Arduino: come l'eterno output di spazi bianchi o improvvisamente taglio di stringhe o stringhe rimescolate.

Poiché non vi era alcun errore di compilazione o avviso nell'IDE di Arduino, pensavo che Arduino fosse rotto ma dopo alcuni test ho scoperto che non tutti i tipi di errori vengono rilevati dal compilatore IDE di Arduino, specialmente quando si assegnano variabili in un ciclo per le strutture di array. Questo sembra mandare in crash Arduino in breve tempo.

Come posso scoprire errori non visualizzati dall'IDE di Arduino?

Risposte:


10

La libreria MemoryFree può aiutarti a trovare rischi con l'utilizzo della memoria.

Esempio:

#include <MemoryFree.h>

// On Arduino Duemilanove with ATmega328:
//
// Reported free memory with str commented out:
// 1824 bytes
//
// Reported free memory with str and Serial.println(str) uncommented:
// 1810
//
// Difference: 14 bytes (13 ascii chars + null terminator)

// 14-bytes string
//char str[] = "Hello, world!";


void setup() {
    Serial.begin(115200);
}


void loop() {
    //Serial.println(str);

    Serial.print("freeMemory()=");
    Serial.println(freeMemory());

    delay(1000);
}

Non sono sicuro che MemoryFree conti per il puntatore dello stack. Se il puntatore dello stack si scontra con il puntatore dell'heap, potresti riscontrare errori di segmentazione.


7

La causa più comune dell'esaurimento della RAM è l'utilizzo dell'oggetto String o l'utilizzo di molti array di caratteri costanti (stringa di tipo c).

IDE 1.0.4 include una correzione a malloc che ha afflitto l'oggetto String per molto tempo.

Per ridurre la RAM sprecata da stringhe di caratteri costanti come:

Serial.print("Hello World");  // This consumes RAM!

È possibile utilizzare la macro F (). Questa macro forzerà l'array di caratteri a rimanere in PROGMEM. Quando si utilizza l'array, viene consumato solo un byte di memoria.

Serial.print(F("Hello World"));  // Keeps the character-array in PROGMEM

Tenere presente che le stringhe memorizzate in PROGMEM non possono essere modificate durante il runtime.

Per quanto riguarda la scoperta, senza un debugger o un controller di memoria, è necessario utilizzare tecniche investigative vecchio stile per trovare dove si verificano i problemi.


1
Grazie per la risposta utile! Non esiste davvero alcun debugger di memoria con supporto IDE?
Powtac,

1
Questa è una vecchia domanda, ma sì, ci sono debugger adeguati per le MCU ATmega ATmel. Non ci sono debugger per gli arduinos , perché arduino toolchain e "IDE" sono fondamentalmente un giocattolo.
Connor Wolf,

1
In realtà il tuo suggerimento con F () ci ha salvato alcune centinaia di byte in RAM!
Powtac,

1
Ottengo un errore di compilazione quando utilizzo F () con stringhe che contengono //. :-(
powtac,

Ottengo questo errore di compilazione su Arduino 1.5.7 ...
powtac

3

Sembra che tu stia parlando di errori di runtime (del tipo di perdita di memoria / segfault) qui.

Non c'è modo di scoprire tali errori (a meno che non si pettini molto attentamente il codice) nel codice già scritto. Tuttavia, è abbastanza facile evitare che ciò accada durante la scrittura del codice. Fai solo molta attenzione quando scrivi loop o chiamate ricorsive; chiediti "questo potrebbe sfuggire di mano?". Se sembra che questo abbia lo scopo di "sfuggire di mano", quindi scrivere codice per proteggerlo.

Informazioni sui segfault: basta controllare i valori limite degli indici di array e si dovrebbe essere OK. Se si utilizzano i puntatori, fare attenzione all'aritmetica dei puntatori.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.