- Labornetzteil AliExpress         
Ergebnis 1 bis 10 von 18

Thema: Feste Größe ändert sich beim Programmablauf (="Suchspiel" Memoryüberschneidung)

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    37
    Beiträge
    1.225
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Dank nochmal und ich höre mit dem Problem und dem leichten Verdacht auf irgendeinen Stacküberlauf auf.
    Leichter Verdacht? 1960 von 2048 Bytes belegt erklärt alles! Da küsst der Stack ziemlich sicher deine Daten. Die verbleibenden 88 Byte verknusperst du zum Frühstück mit irgendwelchen Funktionsargumenten, Stringarrays etc. (alleine im Kontext von sprung zähle ich grob überschlagen 29 Byte und ein ISR-Aufruf sichert alle genutzten Register, was auch mal 32 Bytes + Rücksprungadresse kosten kann).

    Tipp: Ich meine im Hinterkopf zu haben, dass statische Strings vom Compiler als Konstanten im RAM abgelegt werden. Du könntest also schon einiges an Speicher freimachen wenn du deine ganzen Strings im Flash ablegst (PROGMEM) und nur bei Bedarf in den RAM holst.

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.695
    Zitat Zitat von markusj Beitrag anzeigen
    ... alleine im Kontext von sprung zähle ich grob überschlagen 29 Byte und ein ISR-Aufruf sichert alle genutzten Register, was auch mal 32 Bytes + Rücksprungadresse kosten kann ...
    Danke - das ist mal wieder ein Abschnitt zur Programmierung, den ich ohne solche Bemerkungen (sprich ohne einen Leitfaden) garnicht angehen kann. Deshalb freue ich mich darüber - weil ich damit wenigstens ne Chance habe mich sinnvoll durchzudenken.

    Zitat Zitat von markusj Beitrag anzeigen
    ... im Hinterkopf ... dass statische Strings ... im RAM abgelegt werden ...
    Genau. Anfangs hatte ich einige im EEPROM. In meinem Servotester hatte ich festgestellt, dass merkbar lange Zugriffzeiten möglich sind, die mich dort das eine oder andere Mal wirklich gestört hatten. Deshalb sind hier die Strings (noch) im RAM - und ich war haarscharf dran, den 328er durch einen 1284er zu ersetzen - obwohl das ne neue Platine bedeutet hätte. Wenn ich über die Testphase drüber bin, dann gehen etliche Strings raus oder werden zurückgestutzt; der wesentliche Anteil davon sind Bemerkungen die für den laufenden (autonomen) Betrieb weniger bis gar keine Bedeutung haben. Da ich ausserdem das Thema PROGMEM immer noch als böhmisches Dorf vor mir herschiebe und meinem Zeitplan hinterherhinke bin ich über diese ramfressende Methode nicht hinausgekommen.

    Danke für Deine Unterstützung.
    Ciao sagt der JoeamBerg

  3. #3
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    54
    Beiträge
    502
    Hallo Joe,

    das mit dem Progmem ist kinderleicht und bewahrt einen wirklich vor bösen Überraschungen. Ich hab hier mal ein kleines Beispiel, wie ich das implementiert habe um Statusmeldungen auszugeben.
    Code:
    int main(void)
    {
    unsigned char actual_page = 0;
    char main_text[20];
    ...
    get_str_from_flash(6, main_text);//"Menue 4"
    tp_write_statusbar(&tp, main_text);
    ...
    Die flash_mem.c:
    Code:
    #include <stdint.h>
    #include <avr/pgmspace.h>
    #include <string.h>
    
    #include "main.h"
    #include "flash_mem.h"
    
    const char str1[] PROGMEM = "INFO allgemein";
    const char str2[] PROGMEM = "              ";//14 Leerzeichen
    const char str3[] PROGMEM = "Menue 1";
    const char str4[] PROGMEM = "Menue 2";
    const char str5[] PROGMEM = "Menue 3";
    const char str6[] PROGMEM = "Menue 4";
    const char str7[] PROGMEM = "Menue 5";
    ...
    
    const char *strarray1[] PROGMEM = {
        str1,
        str2,
        str3,
        str4,
        str5,
        str6,
        str7,
        str8,
        str9,
        str10,
        str11,
        str12,
    ...
    };
    
    void get_str_from_flash(uint16_t strnum, char* str)
    {
    if(strnum>0)strcpy_P(str, (const char*)(pgm_read_word(&(strarray1[strnum-1]))));
    else strcpy(str, "Invalid number!");
    }
    und in der flash_mem.h steht nur:
    Code:
    #ifndef _MEM_FLASH_H_
    #define _MEM_FLASH_H_
    
    extern void get_str_from_flash(uint16_t strnum, char* str);
    
    #endif  /* _MEM_FLASH_H_ */
    Geändert von sast (21.01.2014 um 14:38 Uhr)

    雅思特史特芬
    开发及研究

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    37
    Beiträge
    1.225
    Zitat Zitat von sast Beitrag anzeigen
    das mit dem Progmem ist kinderleicht und bewahrt einen wirklich vor bösen Überraschungen. Ich hab hier mal ein kleines Beispiel, wie ich das implementiert habe um Statusmeldungen auszugeben.
    Leider nicht ganz, da das Timing in dem Fall sich verändert. Der EEPROM ist noch langsamer im Zugriff als der Flash, aber bei timingkritischen Anwendungen ist das eben ein relevanter Faktor. Außerdem: Warum so umständlich mit der zusätzlichen Zeigertabelle? Um von den zwei Byte des Pointers ein Byte einzusparen im Tausch gegen schlecht zu debuggende "Magic Numbers"? In dem Fall wäre es ratsam, anstatt der Zahlenwerte einen enum zu nutzen.

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    54
    Beiträge
    502
    Markus könntest du das mal bitte an einem konkreten Beispiel zeigen, was du meinst?

    Danke
    sast

    雅思特史特芬
    开发及研究

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Hallo Joe
    In deiner *com*.h da hast du so was definiert

    volatile s16 M12ocr;
    hier wirst du wohl ein int brauchen, aber bei allen anderen Variablen auch?
    Mit so was habe ich mich schon einige male in ein Schlamassel gebracht und bin daher sehr vorsichtig.
    Wenn nach dem compile Data mehr als 60% braucht werde ich schon hellhörig.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  7. #7
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.695
    Zitat Zitat von sast Beitrag anzeigen
    Markus könntest du das mal bitte an einem konkreten Beispiel zeigen, was du meinst ...
    Ja, bitte, das würde mir auch helfen. Ich saß grad ne Weile an dem Vorschlag von sast - und bin natürlich und notwendigerweise schnell in die entsprechenden Tutorials vom RN und m-controller-net reingeschliddert. Zum Glück kam Markus - und ich hatte erstmal "Pause" gemacht - - - die Beispiele in RN und m-controller-net haben mich noch nicht zu ner funktionierenden Lösung gebracht.

    Zitat Zitat von Hubert.G Beitrag anzeigen
    ... volatile s16 M12ocr ... int brauchen, aber bei allen anderen Variablen auch? ...
    Hubert - mal mein "warum so" dazu.
    Die MotorPWM wird aktuell mit 8 Bit gefahren - am Timer 1 (*gg* - klingt nach weiterer Vergeudung von Ressourcen).
    Code:
      TCCR1B |=  (1<<WGM12);                // Fast PWM, 8 Bit TOP=0xFF=dez255     133
      TCCR1B |=  (1<<CS11);         // Prescaler ist clk/8 =>  9,8 kHz             135
            // theoretisch: 20 MHz / 8 / 255  =>  9,803922 kHz, DMM-Messung 9,78 kHz
    Code:
      volatile s16  M12ocr; // temporärer Stellwert für OCR1A        -255...255
    Beabsichtigt, vermutet, ist die spätere Verwendung von mehr als 8 Bit, weil die Regelung durchgehend von -fahrt (rechtsdrehend) bis +fahrt (linksdrehend) geplant ist - und da wären mir die verbleibenden 127 Ticks zu wenig. Die Lösung mit Fallunterscheidung "vor" oder "zurück" bzw. "re" oder "li" habe ich im MiniD0 und Dottie mit den vollen 255 Ticks praktiziert - sie gefällt mir eben nicht, weil ich wegen der Hin- und Herschalterei z.B. bei Langsamfahrt so etwas - - eben unschön finde. Um mir spätere Störmöglichkeiten durch vergessene Anpassungen zu ersparen, ist die Vorgabe der Fahr-PWM auf signed 16 ausgelegt (mehrere Größen). Ich hoffe, dass mir dieses Vorhaben gelingen wird. Ich versuche schon meist das Zahlenformat klein zu halten - - genau wegen des eher begrenzten SRAM-Platzangebots.

    Zitat Zitat von Hubert.G Beitrag anzeigen
    ... Wenn nach dem compile Data mehr als 60% braucht werde ich schon hellhörig ...
    Genau so gehts mir auch, ich wollte ja schon ne eigene Platine statt der RN-MotorControl bauen mit nem mega1284. Aber das gäbe schon wieder ne zusätzlichen Zeitaufwand ohne wirklichen Fortschritt . . . Sogar an einen 1284er-Huckepack-ersatz für den 328er hatte ich gedacht - aber nicht lange *gg*.

    Hubert - ich hoffe dass damit Deine Bedenken behoben sind?
    Ciao sagt der JoeamBerg

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    37
    Beiträge
    1.225
    Zitat Zitat von sast Beitrag anzeigen
    Markus könntest du das mal bitte an einem konkreten Beispiel zeigen, was du meinst?
    Naja, die enum-Variante ist einfach. Im wesentlichen dein Code, nur statt uint16_t strnum ein strnum_t str. Und dann eben
    PHP-Code:
    typedef enum {
       
    str_info 0,
       
    str_space,
       
    str_menu1,
       ...
    strnum_t

    // Verwendung dann so:
    get_str_from_flash(str_infostr); 
    Damit gewinnst du etwas mehr Übersichtlichkeit, hast aber immer noch die unnötige Indirektion strarray1->*str->Flash. Der direkte Weg wäre einfach, die Strings direkt mit sprechenden Namen zu versehen und dann zu referenzieren. Damit scheidet dann auch die Möglichkeit weg, versehentlich einen nicht existierenden String zu referenzieren.
    PHP-Code:
    const char str_info[] PROGMEM "INFO allgemein";
    const 
    char str_space[] PROGMEM "              ";//14 Leerzeichen
    const char str_menu1[] PROGMEM "Menue 1";

    ...

    // Verwendung, get_str_from_flash wird überflüssig
    strcpy_P(str, &str_menu1); 
    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    54
    Beiträge
    502
    Hallo Markus,

    die erste Variante unterscheidet sich ja nicht wirklich von meiner, bis auf die Namen. Ursprünglich war bei mir auch angedacht, z.B. über eine Zählschleife einen Block aufzurufen. Da das jetzt nicht mehr so ist, gefällt mir deine Variante 2 sogar noch besser.

    Danke für die Ausführung
    sast

    雅思特史特芬
    开发及研究

Ähnliche Themen

  1. per TV-remote ein "move" programmablauf auslösen..
    Von carlitoco im Forum Robby RP6
    Antworten: 4
    Letzter Beitrag: 01.04.2008, 20:59
  2. Stecker in "Computer-Größe"
    Von danst im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 13.01.2007, 15:19
  3. "Leser stellen sich vor" - Was haltet ihr davon?
    Von Florian im Forum Umfragen
    Antworten: 31
    Letzter Beitrag: 17.03.2006, 16:52
  4. IO-Pins lassen sich nicht richtig mit "bsf"/"
    Von keiang im Forum PIC Controller
    Antworten: 3
    Letzter Beitrag: 21.07.2005, 19:12
  5. AT90S2313 - RX-Interupt - Der "hängt sich auf"
    Von Gottfreak im Forum AVR Hardwarethemen
    Antworten: 10
    Letzter Beitrag: 13.05.2004, 23:32

Berechtigungen

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

LiFePO4 Speicher Test