logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega16][C] - Niespodziewane nadpisanie łańcucha znaków w pamięci

Myrek1 20 Maj 2013 08:23 1191 4
  • #1 12325707
    Myrek1
    Poziom 23  
    Witam,
    Mam problem z avr-gcc. Chodzi o to, że program w pewnym momencie (nie zawsze w tym samym) zmienia mi wartość zmiennej w SRAMie, najczęściej gdzieś przy wywołaniu przerwania np od ADC czy timera. Ale to nie reguła. Zmienia się to też w czasie wykonywania zmian na innych elementach, o czym za raz.Może nie na sucho, dam kod.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Chodzi o to, że mam zmienne z opisami (menu_1_1[] i zmienne z wartościami (menu_1_2[]). Ich adresy przechowywane są w tabeli dwuwymiarowej (menu_tab), w pierwszej komórce wskaźnik do opisu, w drugiej do zmiennej. W pewnym momencie wywoływana jest funkcja ToString, która zmienia mi wartość zmiennej na ciąg znaków. No i w mamy wskaźniki do ciągu znaków opisów i zmiennych.
    Wiem, że to marnowanie miejsca w SRAMie, ale na razie tak jest, więc proszę nie pisać o PROGMEM.

    Problem jest taki, że czy to przy przerwaniach, jak pisałem wcześniej, czy nawet podczas zamiany jakiejś zmiennej przez ToString zmienia mi się zawartość zmiennej Wartosc2 i tylko tej. Te tablice są dłuższe i wszystkie jednakowe (tu jest tylko wycinek), a problem dotyczy tylko jednej wartości (Wartosc2). Dodatnie Volatile nic nie zmienia, żadna z tych zmiennych nie jest wykorzystywana w przerwaniu.
    Dlaczego występuje ten problem niespodziewanego zastąpienia ciągu znaków w SRAMie przypadkowymi wartościami? Przecież zarezerwowany jest ten obszar pamięci dla konkretnej zmiennej.
    SRAM ma zajętość ponad 97%, czy w takich sytuacjach mogą wystąpić takie problemy, a kompilator o tym nie informuje? Czytałem, że są takie możliwości.
    Ale trochę nie chce mi się wierzyć, że program może robić różne rzeczy a programista nie ma na to wpływu.

    Macie jakieś pomysły?
    Dzieki.[/code]
  • #2 12325719
    mmacura
    Poziom 18  
    Jeśli masz zajęte ponad 97% RAM to zostaje Ci mniej niż 30 bajtów RAM.
    Przy każdym wywołaniu przerwania procesor odkłada swój stan na stos (czyli do RAM) i może nadpisywać zmienne, jeśli masz zbyt dużo w RAM - kompilator nie jest wstanie tego sygnalizować.
    Spróbuj ten sam program włożyć do ATMega32 - powinno pomóc.

    Marek
  • #3 12325748
    Myrek1
    Poziom 23  
    Zgadza się, w Atmega32 jest ok. Tak też myślałem, tylko że kompilator powinien informować o tym, że może nastąpić takie "coś". I faktycznie, udało mi się uchwycić ten problem, występuje przy zapisie na stos.
    Czyli na przyszłość bezpieczniej jest jeśli zostawimy ok 30 bajtów RAMu, tak?
    Dzięki.
  • #5 12326033
    BlueDraco
    Specjalista - Mikrokontrolery
    Stałe zapisuje się w pamięci stałej. Ty pakujesz mnóstwo stałych do małej pamięci RAM i masz pretensje do kompilatora, że nie ostrzega Cię o błędach wynikających z dynamiki wykonania Twojego programu (a więc praktycznie nie do uchwycenia przez kompilator) i z nadmiernej zajętości pamięci, o której kompilator Cię informuje.
REKLAMA