Como descobrir erros de estouro de memória no código do Arduino C?


10

Várias vezes tive algumas saídas suspeitas no Serial Monitor após o upload do código para o Arduino: como saída eterna de espaços em branco ou corte repentino de strings ou strambled strings.

Como não houve erro ou aviso de compilação no Arduino IDE, pensei que o Arduino estava quebrado, mas depois de alguns testes descobri que nem todos os tipos de erros são detectados pelo compilador Arduino IDE - especialmente ao atribuir variáveis ​​em um loop para estruturas de matriz. Isso parece travar o Arduino em um curto período de tempo.

Como posso descobrir erros não exibidos pelo IDE do Arduino?

Respostas:


10

A biblioteca MemoryFree pode ajudá-lo a encontrar riscos com o uso da memória.

Exemplo:

#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);
}

Não tenho certeza se o MemoryFree é responsável pelo ponteiro da pilha. Se o ponteiro da pilha colidir com o ponteiro da pilha, você poderá encontrar falhas de segmentação.


7

A causa mais comum de exaustão da RAM é o uso do objeto String ou o uso de muitas matrizes de caracteres constantes (string no estilo c).

Forutantly IDE 1.0.4 inclui uma correção para malloc que atormentou o objeto String por um longo tempo.

Para reduzir a RAM desperdiçada por seqüências de caracteres constantes, como:

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

Você pode usar a macro F (). Essa macro forçará a matriz de caracteres a permanecer no PROGMEM. Quando a matriz é usada, apenas um byte de memória é consumido.

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

Lembre-se de que as seqüências armazenadas no PROGMEM não podem ser alteradas durante o tempo de execução.

No que diz respeito à descoberta, sem um depurador ou controlador de memória, você precisa usar técnicas de detetive antiquadas para descobrir onde estão os problemas.


11
Obrigado pela resposta útil! Realmente não há depurador de memória de suporte a IDE?
Powtac

11
Essa é uma pergunta antiga, mas sim, existem depuradores adequados para os atmel ATmega MCUs. Não há depuradores para arduinos , porque a cadeia de ferramentas do arduino e o "IDE" são basicamente um brinquedo.
Connor Wolf

11
Na verdade, sua dica com F () nos salvou algumas centenas de bytes em RAM!
Powtac

11
Eu recebo um erro de compilação ao usar F () com seqüências de caracteres que contêm //. :-(
powtac 14/09/14

Eu recebo esse erro de compilação no Arduino 1.5.7 ...
powtac

3

Parece que você está falando de erros de tempo de execução (do tipo vazamento de memória / segfault) aqui.

Não há como descobrir esses erros (a menos que você examine cuidadosamente o código) no código que já está escrito. No entanto, é bastante fácil impedir que isso aconteça enquanto escreve o código. Apenas tenha muito cuidado ao escrever loops ou chamadas recursivas; pergunte a si mesmo "isso pode ficar fora de controle?". Se parecer que esse é o escopo para "sair do controle", escreva um código para se proteger.

Sobre segfaults - basta verificar os valores limites dos índices da matriz e você deve estar bem. Se você estiver usando ponteiros, tenha cuidado com a aritmética dos ponteiros.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.