-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: Wieviel SRAM ist noch frei?

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801

    Wieviel SRAM ist noch frei?

    Anzeige

    Werkzeuge wie avr-size können keine Informationen über den Laufzeit-Verbrauch an SRAM liefern. Das liegt in der Natur der Sache, weil der Verbrauch nicht statisch bestimmt werden kann. Zumindest nicht von avr-size, und nicht für ein allgemeines Programm.

    Falls es interessiert, wie viel SRAM man noch zur Verfügung hat, geht das mit folgendem Code. Dabei wird vorausgesetzt, daß keine dynamische Speicherverwaltung mit malloc() und Konsorten verwendet wird und das SRAM maximal 64k groß ist. __builtin_alloca() stellt kein Problem dar.

    In der init-Sequenz wird ein Muster ins SRAM geschrieben. Zur Laufzeit kann mit der Funktion
    unsigned short get_mem_unused(void)
    getestet werden, wie viel von diesem Muster noch intakt ist und nicht von Stackframes der Funktionen/Interruptroutinen überpinselt wurde. Damit hat man einen Anhaltspunkt, wie weit der Stack bislang maximal nach unten gewachsen ist. Kann man dann ins EEPROM merken und auslesen oder aufs Display/PC weiterschicken. Das vom Benutzer verwendete SRAM, wo Variablen etc liegen (Sections .data, .bss und .noinit), ist schon berücksichtigt und muss nicht mehr abgezogen werden.

    Das Modul mit -O1, -O2 oder -Os übersetzen.

    mem-check.h:
    Code:
    #ifndef _MEM_CHECK_H_
    #define _MEM_CHECK_H_
    
    extern unsigned short get_mem_unused (void);
    
    #endif /* _MEM_CHECK_H_ */
    mem-check.c:
    Code:
    #include <avr/io.h> // RAMEND
    #include "mem-check.h"
    
    #if !defined (__OPTIMIZE__)
    #warning mem-check funzt nur mit Optimierung
    
    unsigned short 
    get_mem_unused (void)
    {
    	return 0;
    }
    
    #else /* __OPTIMIZE__ */
    
    // Mask to init SRAM and check against
    #define MASK 0xaa
    
    // From linker script
    extern void* __heap_start;
    
    unsigned short 
    get_mem_unused (void)
    {
    	unsigned short unused = 0;
    	const unsigned char *ramend = (unsigned char*) RAMEND;
    	unsigned char *p = (unsigned char*) &__heap_start;
    	
    	do
    	{
    		if (*p++ != MASK)
    			break;
    			
    		unused++;
    	} while (p < ramend);
    		
    	return unused;
    }
    
    // Init SRAM to MASK
    // !!! Do never call this function !!!
    void __attribute__ ((naked, section (".init2")))
    __init_mem (void)
    {
    	unsigned char *p = (unsigned char*) &__heap_start;
    	const unsigned char *ramend = (unsigned char*) RAMEND;
    	
    	do 
    	{
    		*p++ = MASK;
    	} while (p < ramend);
    }
    
    #endif /* __OPTIMIZE__ */
    Disclaimer: none. Sue me.

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Gute Idee.
    Ich frag' mich grad', ob ein Pattern notwendig ist ? Return addr. = 0 gibt's doch eigentlich genausowenig ?
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Ich denk schon, daß man ein Muster braucht.

    Auf dem Stapel wird ja auch der Frame angelegt, der dient ja nicht nur für Rücksprung mit rets/reti. Zudem werden auch Register dort gesichert im Funktions/ISR-Prolog. Und Registerinhalte können durchaus 0 sein.

    Der Hauptgrund ist aber, daß das SRAM der AVRs nach PORST (power on/down reset) keinen definierten Zustand hat. Was als Saat für Pseudo-Zufall praktisch ist, würd hier dazu führen, daß man schnell einen Wert findet, der != Pattern ist, und man wäre fehlinformiert.
    Disclaimer: none. Sue me.

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Ja sicher, hast eh' recht, außerdem was soll's, frißt ja kein Brot.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    28.06.2006
    Beiträge
    7
    Ich stell mich etwas blöd an, aber wie nutze ich die obigen Codeschnipsel bitte?

    Bisheriges erfolgloses Vorgehen:

    Ich hab eine "mem-check.h" in "/utils" abgelegt und binde sie wie die twi.h in mein Programm ein, also..

    #include <util/mem-check.h>

    mem-check.h:
    Code:
    #ifndef _MEM_CHECK_H_
    #define _MEM_CHECK_H_
    
    extern unsigned short get_mem_unused (void);
    
    #endif /* _MEM_CHECK_H_ */
    und dann hab ich den anderen 'mem-check.c'-CODE in mein Programm kopiert vor die ganzen ISR's und nach den globalen Variablendeklarationen.

    Das Programm wird schon immer mit -Os compiliert, also sollte ich die "Forderung" nach optimierter Übersetzung erfüllen, oder?

    Das Problem ist nun eine Fehlermeldung während des compilierens, bei dem es die Art, wie ich die get-mem-unused aufrufe moniert.
    Ich rufe die Funktion folgendermassen auf:

    volatile uint8_t test=0;

    ..

    test = get-mem-unused;


    Fehlermeldung:
    error: invalid arguments to binary

    Was mach ich falsch?

    Danke & Grüße
    0tes_Gesetz

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Die function ist vom typ "short", test ist aber nur n'byte ?
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    28.06.2006
    Beiträge
    7
    Thx für die Antwort, aber das Verstellen des Variablentyps der Variable 'test' von "uint8_t" auf "unsigned short" oder "uint16_t" brachte keinen Erfolg.

    Fehlermeldung nach wie vor:
    error: invalid arguments to binary

    Wenn ich die Funktion über ..

    test = get-mem-unused;

    ..aufrufe.

    Grüße
    0tes_Gesetz

    PS: was bedeutet "invalid arguments to binary" ... "ungültige Argumente in/für Binary"? - welche Binary?
    Die Funktion get-mem-unused braucht doch keine Übergabeparameter, oder? - ist doch (void)...

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    test = get-mem-unused;
    Du machst das aber schon mit Klammer ?
    test = get-mem-unused();
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    28.06.2006
    Beiträge
    7
    Jetzt ja!!



    Ganz großes Dankeschön.

    Grüße
    0tes_Gesetz

  10. #10
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Na, sehen sie, Herr Kollege, kaum macht man's richtig, geht's.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •