Arduino C kodundaki bellek taşması hataları nasıl bulunur?


10

Birkaç kez Arduino'ya kod yükledikten sonra Seri Monitörde bazı şüpheli çıktılar vardı: beyaz boşlukların ebedi çıkışı veya aniden dizelerin veya şifreli dizelerin kesilmesi gibi.

Arduino IDE'de derleme hatası veya uyarısı olmadığı için Arduino'nun kırıldığını düşündüm, ancak bazı testlerden sonra Arduino IDE derleyicisi tarafından her türlü hatanın yakalanmadığını öğrendim - özellikle dizi yapıları için bir döngüde değişkenler atarken. Bu, kısa sürede Arduino'yu çökertiyor gibi görünüyor.

Arduino IDE tarafından görüntülenmeyen hataları nasıl bulabilirim?

Yanıtlar:


10

MemoryFree kütüphane bellek kullanımı ile riskleri bulmanıza yardımcı olabilir.

Misal:

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

MemoryFree'nin yığın işaretçisini hesaplayıp sorgulamadığından emin değilim. Yığın işaretçiniz yığın işaretçinizle çarpışırsa, segmentasyon hataları yaşayabilirsiniz.


7

RAM tükenmesinin en yaygın nedeni String nesnesini kullanmak veya çok sayıda sabit karakter dizisi kullanmaktır (c stili dize).

Forutantly IDE 1.0.4, String nesnesini çok uzun süre rahatsız eden bir malloc düzeltmesi içerir.

RAM gibi sabit karakter dizeleri tarafından boşa azaltmak için:

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

F () makrosunu kullanabilirsiniz. Bu makro, karakter dizisini PROGMEM içinde kalmaya zorlar. Dizi kullanıldığında, yalnızca bir bayt bellek kullanılır.

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

PROGMEM içinde saklanan dizelerin çalışma zamanı sırasında değiştirilemeyeceğini unutmayın.

Keşif gittikçe, bir hata ayıklayıcı veya bellek denetleyicisi olmadan, sorunların nerede ortaya çıktığını bulmak için eski moda dedektif tekniklerini kullanmanız gerekir.


1
Yararlı cevap için teşekkürler! Gerçekten hiçbir IDE destek bellek hata ayıklayıcı yok?
powtac

1
Bu eski bir soru, ancak evet, atmel ATmega MCU'lar için uygun hata ayıklayıcılar var . Arduino için hata ayıklayıcı yoktur , çünkü arduino araç zinciri ve "IDE" temelde bir oyuncaktır.
Connor Wolf

1
Aslında F () ile ipucu bize RAM yüzlerce bayt kurtardı!
powtac

1
İçinde dizeleri olan F () kullanırken derleme hatası alıyorum //. :-(
powtac

Bu derleme hatasını Arduino
1.5.7'de alıyorum

3

Burada çalışma zamanı hataları (bellek sızıntısı / segfault türü) hakkında konuştuğunuz anlaşılıyor.

Zaten yazılmış olan kodda bu tür hataları (kodla çok dikkatli bir şekilde taramadıkça) keşfetmenin bir yolu yoktur. Ancak, kodu yazarken bunların olmasını önlemek oldukça kolaydır . Sadece döngüler veya yinelemeli aramalar yazarken çok dikkatli olun; kendinize "bu kontrolden çıkabilir mi?" Bunlar "elden kurtulmak" için bir kapsam gibi görünüyorsa, buna karşı korumak için kod yazın.

Segfaultlar hakkında - dizi indekslerinin sınır değerlerini kontrol etmeniz yeterlidir ve iyi olmalısınız. İşaretçiler kullanıyorsanız, lütfen işaretçi aritmetiğine dikkat edin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.