• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Zawieszanie wyświetlacza OLED
#41
Raport 1423, funkcja, której użyłeś stwierdza, ze wolnego ram 1422. Czy to nie daje do myślenia?

Ponadto, w raporcie nie ma info o zużyciu stosu,bo tego kompilator nie wie. Min zużycie RAM dla stosu (przerwania),to:
2 bajty adresu powrotu (dla uC ponad 128k FLASH 3 bajty)
1 bajt rejestru statusu (dla ponad 128k dodatkowo RAMPZ)
2 rejestry R0 i R1
To daje już 5 bajtów. W praktyce, w przerwaniu jest zapamiętywane kilka do kilkunastu rejestrów, można śmiało przyjąć ok 10.
Do tego dochodzi sterta - wiesz co to jest? Czym się różni od stosu?
No i przerwania mogą być (prawie) wielopoziomowe, wtedy zapotrzebowanie na stos się zwiększa.

Funkcję, którą użyłeś, możesz sobie wsadzić w .... gdzie chcesz, ale nie do programu, aby stwierdził jakie jest zużycie RAM. Owszem, program ten pokaże ile RAM w danym momencie masz do dyspozycji, ale zarezerwuj taki RAM, zapisuj tam cały czas cokolwiek a program się zawiesi, bo zniszczysz stos a być może i stertę.

Funkcja, która ja udostępniłem, sprawdza jak dużo ram jest zajmowane przez stos i stertę (a może tylko stos, nie pamiętam). O ile biblioteki (sprawdzałeś?) nie allokują dynamicznie ram, to te 1,4k jest ok. 200 bajtów by też wystarczyło a nawet i 20, wszystko zależy od programu.
Jeśli więc nie chcesz analizować kodu, uruchom moja funkcję, ona "prawdę ci powie".

[EDIT}
Sprawdziłem tą moją funkcję, sprawdza zużycie stosu. Jeśli stera będzie używana, to zwróci 0 ram. Jeśli chcesz sprawdzać zużycie sterty, trzeba by szukać nie bajtu $FF tylko bloku (np 16 bajtów) o wartości $FF albo lepiej w sekcji "init3" wypełnić jakim konkretnym wzorem, np tekstem, i szukac tego tekstu(od dołu) i jego braku (od góry) RAM.

Te wszystkie programy, nie sa potrzebna jak się używa debugera, niestety, zabawkowe Arduino, nie wie co to sprzętowy debuger, dlatego nie używam tej zabawki, bo na wiele ona się nie nadaje.
 
Odpowiedź
#42
es2 - uruchomiłem Twoją funkcję odnośnie " Sekcja ".initX"(szczerze powiedziawszy nie mam pojęcia co ma być rezultatem ) lecz funkcja odnośnie "sprawdzania zajętości stosu" pokazała błąd "'FreeRam' was not declared in this scope" . Dlatego skorzystałem z kodu kaczkata ponieważ nawet na internecie ciężko mi znaleźć rozwiązanie odnośnie błędu.
 
Odpowiedź
#43
Pokaż kod.
 
Odpowiedź
#44
Kod:
#include "DHT.h"                          // biblioteka DHT
#include "U8glib.h"                       // bibioteka OLED I2C

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  // I2C / TWI

#define DHTPIN 2                          // definicja PIN dla DHT
#define DHTTYPE DHT22                     // DHT 22
DHT dht(DHTPIN, DHTTYPE, 6);                  // deklaracja DHT
char str[10];                         // znak stopni celsujsza i procent
int WILG;                           // zmienna wilgotnosc
float TEMP;  // zmienna temperatura w stopniach C

unsigned long aktualnyCzas = 0; // do millis
unsigned long zapamietanyCzas = 0;  // do millis


int relay_pin = 8;                // przekaznik
int relay_pin2 = 12;              // przekaznik
int relay_pin3 = 7;                // przekaznik
int relay_pin4 = 9;
#define led_info_promiennik 4         // dioda od promiennika
#define led_info_generator 13      // dioda od generatora pary
#define led_info_nic 1



int potencjometr = A0;                // odczyt napiecia z potentcjometru pinem analogowym 0
int wartosc = 0;                       // zmienna przechowujaca wartosc napiecia odczytanego
int dane[5]; // do potencjometru do sredniej
int i=0;  // do potencjometru do sredniej
int srednia;  // do potencjometru do sredniej

//------------------------------------------------------------------//
//                Sekcja ".initX"    (ZERO zainicjalizowane)                //
//------------------------------------------------------------------//
#define NOINIT __attribute__ ((section(".noinit")))
unsigned char DnoStosu NOINIT;            // Kontrola stosu
void ClrIntRam(void) __attribute__ ((naked)) __attribute__ ((section (".init3")));
void ClrIntRam(void)
{
unsigned char *AdrRam;
   //--- Zapisujemy od ostatniej zajetej komórki ram do wierzchołka stosu -32 bajty rezerwy ---
   for (AdrRam=&DnoStosu; AdrRam < (unsigned char*)RAMEND-32; AdrRam++)            // Wpisanie do IntRam $FF
       {
       *AdrRam = 0xFF;
       }
}

void setup()
{
 dht.begin();                          // inicjalizacja DHT
pinMode(potencjometr, INPUT); //pin A0 (pot) jako wejście
pinMode(relay_pin, OUTPUT);
pinMode(relay_pin2, OUTPUT);
pinMode(relay_pin3, OUTPUT);
pinMode(relay_pin4, OUTPUT);
digitalWrite(relay_pin, HIGH);
digitalWrite(relay_pin2, HIGH);
digitalWrite(relay_pin3, HIGH);
digitalWrite(relay_pin4, HIGH);
pinMode(led_info_promiennik, OUTPUT);
pinMode(led_info_generator, OUTPUT);
pinMode(led_info_nic, OUTPUT);

}

void draw(void){
u8g.firstPage();              
do {
u8g.setFont(u8g_font_helvB08);               // czcionka
u8g.drawStr( 2, 27, "Zwiekszanie wilgotnosci!");            
                   

u8g.drawStr( 2, 42, "Wilgotnosc :");            
u8g.drawStr( 80, 42, dtostrf(WILG, 5, 2, str));
u8g.drawStr( 110, 42, "%");

u8g.drawStr( 2, 57, "Wilg. zad.:");            
u8g.drawStr( 80, 57, dtostrf(wartosc, 5, 2, str));
u8g.drawStr( 110, 57, "%");
} while( u8g.nextPage() );                       // koniec petli obrazu

}
void draw2(void){
u8g.firstPage();              
do {
u8g.setFont(u8g_font_helvB08);               // czcionka
u8g.drawStr( 2, 27, "Zmniejszanie wilgotnosci!");            
                   

u8g.drawStr( 2, 42, "Wilgotnosc :");            
u8g.drawStr( 80, 42, dtostrf(WILG, 5, 2, str));
u8g.drawStr( 110, 42, "%");

u8g.drawStr( 2, 57, "Wilg. zad.:");            
u8g.drawStr( 80, 57, dtostrf(wartosc, 5, 2, str));
u8g.drawStr( 110, 57, "%");
} while( u8g.nextPage() );                       // koniec petli obrazu

}
void draw3(void){
u8g.firstPage();              
do {
u8g.setFont(u8g_font_helvB08);               // czcionka
u8g.drawStr( 2, 27, "Strefa Nieczulosci");            
                   

u8g.drawStr( 2, 42, "Wilgotnosc :");            
u8g.drawStr( 80, 42, dtostrf(WILG, 5, 2, str));
u8g.drawStr( 110, 42, "%");

u8g.drawStr( 2, 57, "Wilg. zad.:");            
u8g.drawStr( 80, 57, dtostrf(wartosc, 5, 2, str));
u8g.drawStr( 110, 57, "%");
} while( u8g.nextPage() );                       // koniec petli obrazu

}
void loop() {

aktualnyCzas = millis();

if (aktualnyCzas - zapamietanyCzas >= 50UL) {
   //Zapamietaj aktualny czas
   zapamietanyCzas = aktualnyCzas;
}
                     
WILG = dht.readHumidity();                     // odczytaj wilgotnosc
TEMP = dht.readTemperature();                  // odczytaj temp
wartosc = analogRead(A0);
dane[i]=wartosc; // do sredniej potencjoemtru
i++;
if(i==5){
i=0;
}
for(int j=0;j<5;j++){
 srednia+=dane[j]; // do sredniej potencjoemtru
}
srednia/=5.0; // do sredniej potencjoemtru
wartosc  = map(wartosc, 0, 1023, 0, 100);           // skalowanie od 0 do 100            

// PETLA OD WARUNKOW
if(wartosc>(WILG+2)) {
 u8g.firstPage();
 do {
   draw();
 } while (u8g.nextPage() );
digitalWrite(relay_pin2, HIGH); //Wyłączenie Promiennika
digitalWrite(relay_pin3, LOW); // ON wentylatora
digitalWrite(relay_pin4, LOW);  //ON wentylatora
digitalWrite(relay_pin, LOW);  // Wlaczenie GENERATORA PARY  
digitalWrite(led_info_generator, HIGH); //Włączenie diody od GENERATORA
digitalWrite(led_info_promiennik, LOW); //WYLACZENIE diody od PROMIENNIKA
digitalWrite(led_info_nic, LOW); // Wyłączenie diody od Strefy Nieczułości
}
else if(wartosc<(WILG-2)){

u8g.firstPage();
 do {
   draw2();
 } while (u8g.nextPage() );
digitalWrite(relay_pin3, HIGH);  // OFF wentylatorow
digitalWrite(relay_pin4, HIGH);  // OFF wentylatorów
digitalWrite(relay_pin, HIGH);  // Wylaczenie GENERATORA
digitalWrite(relay_pin2, LOW); // Wlaczenie Promiennika
digitalWrite(led_info_promiennik, HIGH); //Włączenie diody od PROMIENNIKA
digitalWrite(led_info_generator, LOW); //Wyłączenie diody od GENERATORA
digitalWrite(led_info_nic, LOW); // Wyłączenie diody od Strefy Nieczułosci
}
else { // tolerancja 2 stopni odnosnie rownosci ze wzgledu na te wahania potencjometru
u8g.firstPage();
 do {
   draw3();
 } while (u8g.nextPage() );
digitalWrite(relay_pin, HIGH); // Wyłaczenie generatora
digitalWrite(relay_pin2, HIGH); // Wyłączenie promiennika
digitalWrite(relay_pin3, HIGH);  // OFF wentylatorow
digitalWrite(relay_pin4, HIGH);  // OFF wentylatorów
digitalWrite(led_info_promiennik, LOW); //WYLACZENIE diody od PROMIENNIKA
digitalWrite(led_info_generator, LOW); //WYLACZENIE diody od GENERATORA
digitalWrite(led_info_nic, HIGH); // Włączenie diody od Strefy Nieczułosci
}
}

//----------------------------------------------------------------------//
//                Sprawdz zajetość stosu                                    //
//----------------------------------------------------------------------//
void TestStosu()
{
unsigned char *AdrRam;
unsigned int cnt=0;


   //--- Sprawdzamy od ostatniej zajetej komórki ram do wierzchołka stosu -32 bajty rezerwy ---
   for (AdrRam=(&DnoStosu)+1; AdrRam < (unsigned char*)RAMEND-32; AdrRam++)            // Wpisanie do IntRam $FF
       {
       cnt++;
       if (*AdrRam != 0xFF)
           {
           FreeRam = cnt;                    // Wolny obszar RAM'u
           if (FreeRam < 32 )
               {                            // Jesli za mały obszar to generuj błąd
               PrintError( ERR_STOS );
               StanLedErr=LED_ERR_STOS;
               sprintf_P(str, PSTR(" Free $%04x RAM"CRLF), FreeRam); PrintString(str); _delay_ms(TIMUARTFREE);
               }
           return;
           }
       }
}
 
Odpowiedź
#45
Pokaż gdzie deklarujesz FreeRam.
 
Odpowiedź
#46
Racja , tylko niewiem jak zadeklarować, zapewne tak jak w przypadku NOINIT lecz zapewne inna, nieznana mi składnia.
 
Odpowiedź
#47
Funkcje check_mem(); sprawdza właśnie odległość miedzy wskaźnikiem stosu i sterty. Funkcja FreeRam to tylko ilość między stertą a końcem ram, czyli to samo co podaje Arduino po zakończeniu kompilacji. Przykładowo na MEGA FreeRam podaje wolnego 7953b, a check_mem 7945b.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#48
"unsigned int cnt=1423" - mimo to nadal występuje błąd "'FreeRam' was not declared in this scope" . Co robię źle? Te kody z pamięcią są niezwykle zawiłe.
 
Odpowiedź
#49
(29-10-2018, 02:20)kaczakat napisał(a): Funkcje check_mem(); sprawdza właśnie odległość miedzy wskaźnikiem stosu i sterty.

Funkcję check_mem() można sobie w buty wsadzić
Kod:
void check_mem() {
 stackptr = (uint8_t *)malloc(4);          // use stackptr temporarily
 heapptr = stackptr;                     // save value of heap pointer
 free(stackptr);      // free up the memory again (sets stackptr to 0)
 stackptr =  (uint8_t *)(SP);           // save value of stack pointer
}

Pokazana jest odległość w danej chwili, od sterty do stosu. Za czy przed check_mem zaallokuj np 1kb pamięci i ją zwolnij. Co pokaze chcek_mem? wolnej pamięci tyle samo co i przed rezerwacja 1kb. W przerwaniu utwórz tablicę 1kb. Co pokazuje check_mem? To co wcześniej. Rezerwuj i zwalniaj w przerwaniu i w programie głównym po 1kb. Co pokazuje check_mem? Że mamy dużo wolnej pamięci ram a takie rezerwacje doprowadzą do zawieszenia programu.

Dlatego darujcie sobie te free_mem itp, bo one pokazują wielkość ram w danej chwili a nie maksymalne zapotrzebowanie na pamięc. Jedyny znany mi sposób (jak nie ma MMU, kto wie co to jest i jak tego uzywać?) to zapełnienie całej dostępnej RAM jakąś wartością lub lepiej wzorem, tak jak robię to w sekcji init3 (kto wie co to jest i do czego służy? Dlaczego nie robię tego w init0, 1 albo 2) później sprawdzanie w jakim obszarze wzór nie został naruszony.
 
Odpowiedź
#50
es2 - widzę , że ma Pan dużą wiedzę na ten temat. Jednak tak jak napisałem wyżej , po zdefiniowaniu w Pana kodzie FreeRam nadal pojawia się błąd przy kompilacji - "FreeRam' was not declared in this scope".
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości