-         

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

Thema: Feste Gre ndert sich beim Programmablauf (="Suchspiel" Memoryberschneidung)

  1. #1
    Erfahrener Benutzer Robotik Visionr Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgu
    Beitrge
    7.554

    Feste Gre ndert sich beim Programmablauf (="Suchspiel" Memoryberschneidung)

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Bitte um Hilfe

    Die Gre int16_t tdek4 zur Dimensionierung einer Geschwindigkeitsrampe wird zu Beginn eines Programmslauf im main in einer Routine zur Dimensionierung verschiedener Gren mit einem Wert belegt und aktuell nicht weiter verwendet (wurde frher verwendet, aktuell inaktiv, wird spter wieder benutzt) bis auf die hier erwhnte Ausgabe. Diese Gre belegt das Ende der dokumentierten Memorymap.

    Die Ausgabe der Gre in einer Liste zusammen mit anderen Werten zeigt unerklrliche nderungen bei verschiedenen Ausgabeaufrufen >>obwohl<< sie, wie erwhnt, nur ein Mal mit einem festen Wert belegt wird. Sie nimmt dabei offensichtlich zufllige, soweit feststellbar stets andere Werte an. Auch ohne Aufruf der erwhnten Dimensionierungsroutine sind diese Schwankungen festzustellen.

    Die sinngleiche Gre tdek1 fr eine andere Geschwindigkeit liegt in der memorymap weit entfernt; sie ist stabil. Auch die der tdek4 in der memorymap benachbarte Gre - die vor ihr liegt, zeigt nicht solche Vernderungen.

    Hier ein Auszug aus dem zugehrigen *.map-File, die "E E E.."-Einschbe markieren entfernte Passagen.

    Code:
    Archive member included because of file (symbol)
    E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E
    -------------------------------------------------------------
    Allocating common symbols
    Common symbol       size              file
    iyp12               0x2               R5MoCo.o
    kend1t1             0x2               R5MoCo.o
    E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E
    -------------------------------------------------------------
    m34vorlauf          0x2               R5MoCo.o
    nenc1               0x1               R5MoCo.o
    tdek4               0x2               R5MoCo.o                      <<==
    Memory Configuration
    Name             Origin             Length             Attributes
    text             0x00000000         0x00020000         xr
    data             0x00800060         0x0000ffa0         rw !x
    eeprom           0x00810000         0x00010000         rw !x
    fuse             0x00820000         0x00000400         rw !x
    lock             0x00830000         0x00000400         rw !x
    signature        0x00840000         0x00000400         rw !x
    *default*        0x00000000         0xffffffff
    Linker script and memory map
    Address of section .data set to 0x800100
    LOAD 
    E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E
    -------------------------------------------------------------
    c:/programme/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5/crtm328p.o
                    0x000000a2                __vector_22
                    0x000000a2                __vector_12
                    0x000000a2                __bad_interrupt
                    0x000000a2                __vector_6
                    0x000000a2                __vector_3
                    0x000000a2                __vector_23
                    0x000000a2                __vector_25
                    0x000000a2                __vector_11
                    0x000000a2                __vector_13
                    0x000000a2                __vector_17
                    0x000000a2                __vector_5
                    0x000000a2                __vector_4
                    0x000000a2                __vector_9
                    0x000000a2                __vector_15
                    0x000000a2                __vector_10
                    0x000000a2                __vector_16
                    0x000000a2                __vector_20
     .text          0x000000a6     0x25d6 R5MoCo.o
                    0x00000430                TC2TMR_init
    E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E
    -------------------------------------------------------------
                    0x00000120                __vector_18
                    0x0000024a                itxt_rn
                    0x000002ee                init_twi_slave
     .text          0x0000267c        0x0 c:/programme/winavr-20100110/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a(_udivmodhi4.o)
     .text          0x0000267c        0x0 
    E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E
    -------------------------------------------------------------
     *(.fini0)
     .fini0         0x0000281e        0x4 c:/programme/winavr-20100110/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a(_exit.o)
     *(.fini0)
                    0x00002822                _etext = .
    .data           0x00800100      0x3b6 load address 0x00002822
                    0x00800100                PROVIDE (__data_start, .)
     *(.data)
     .data          0x00800100        0x0 c:/programme/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5/crtm328p.o
     .data          0x00800100      0x3b6 R5MoCo.o
                    0x008004b3                Idelta1
                    0x008004a8                m12v
                    0x008004a9                m12z
    E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E
    -------------------------------------------------------------
                    0x008008a3                m34vorlauf
                    0x008008a5                nenc1
                    0x008008a6                tdek4                     <<==
                    0x008008a8                PROVIDE (__bss_end, .)
                    0x00002822                __data_load_start = LOADADDR (.data)
                    0x00002bd8                __data_load_end = (__data_load_start + SIZEOF (.data))
    .noinit         0x008008a8        0x0
                    0x008008a8                PROVIDE (__noinit_start, .)
     *(.noinit*)
                    0x008008a8                PROVIDE (__noinit_end, .)
                    0x008008a8                _end = .
                    0x008008a8                PROVIDE (__heap_start, .)
    .eeprom         0x00810000        0x0
     *(.eeprom*)
                    0x00810000                __eeprom_end = .
    .fuse
     *(.fuse)
     *(.lfuse)
     *(.hfuse)
     *(.efuse)
    Ich bitte um Hinweise woran es liegen knnte und wie ich das abstellen kann.

    Ist das RAM so voll, dass der Stackpointer berlauft?
    Wie knnte ich besser bzw. eindeutig feststellen, was die Ursache ist?

    Ich danke im Voraus fr eure Tips und Hilfen.
    Ciao sagt der JoeamBerg

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beitrge
    1.220
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Wie knnte ich besser bzw. eindeutig feststellen, was die Ursache ist?
    Kannst du uns den Quelltext zeigen? Der Fehler liegt vermutlich an anderer Stelle, es wre ein groer Zufall wenn der Stack dir tdek4 "frisst" aber nenc1 verschont.

    Gre,
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  3. #3
    Erfahrener Benutzer Robotik Visionr Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgu
    Beitrge
    7.554
    Kannst du uns den Quelltext zeigen? Der Fehler liegt vermutlich an anderer Stelle ...
    Klar - im Prinzip. Aber sechstausend Zeilen Quelltext ist halt etwas viel . . . Vielleicht reichen diese Auszge:

    Auszug main
    Code:
    // - - - - - - - - - - - - - - -
    // Ports+Pins als Ein- (0) oder Ausgnge (1) konfigurieren, Pull Ups (1) aktiv.
    //      A = Ausgang, E = Eingang ohne , EU = Eingang MIT PullUp
      DDRB  = 0b11111111;   // siehe aktuell oben oder Fortschrittsbericht
      PORTB = 0b00000000;   //    und Port/Pull Ups (1)  aktivieren
                            //
      DDRC  = 0b11000010;   // PC0 .. 6 , kein PC6+7-Pin bei m168/328 in THT
      PORTC = 0b00000000;   // PC0, ~2 und ~3 sind ADC-Eingnge ##>> OHNE Pullup !!
                            // 
      DDRD  = 0b11000000;   // RX+TX Eingang mit Pullup
      PORTD = 0b00111111;   //   Pull Ups aktivieren, mit pololuMot AUCH bei INT0/~1
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                            //
      for(i=0; i<10; i++)   // gLED2(PB5) blinken lassen bevor Interrupts erlaubt sind
      {                     //   um ungewollte Resets u.. besser erkennen zu knnen
        SetBit(PgLED, L1g); // gnLED1 schalten EIN, HELL, aktuelle PC1
        SetBit(PORTB,  3 ); // ###>>> TEST
        wms   (3);          // ###>>> Die onBoard-LEDs schalten A<->Portpin <<<###
        ClrBit(PgLED, L1g); // gnLED1 schalten AUS, Dunkel
        ClrBit(PORTB,  3 ); // ###>>> TEST
        wms   (97);         //
      }                     // Ende von for(i=0; i<10; i++)
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Izthrznt      = 20000;        // Der ZeitHorizont fr ISR(TIMER2_COMPA_vect)
    //ncx0          =   128;        // Messwert-Pointer auf "keine Messwerterfassung"
      ncxP          =   200;        // Prescaler fr 1/100 sec bei Messwerterfassung
      ncxF          =     1;        // Messertflag; 1 <=> Wert darf gespeichert werden
      Izeit_1       = Izthrznt;     //
      Isecundn      = 1;    // Sekundenzhler, max 9 Stunden - NUR hier nullen
      TC2TMR_init(); // Init Timer/Cntr2-Interrupt 20 kHz/50 sec           tmr
                            //   ISR gibt auf PB2 ein Servosignal aus
    // - - - - - - - - - - - - - - -//      Hier die notwendigen Werte fr Motorbetrieb=Encoder, Regelfaktoren etc
    //        .. erforderlich VOR Initialisierung der externen Interrupts und Regelung
      nenc0         =    0; // Encoder-Prescaler, nur jeden nenc0-ten bergang zhlen
      nenc1         =    0;
      Kp12          =    1; // Regelfaktor P-Anteil !!! Divisor, lt fahrtest = 4 (1/4)
      Kp34          =    1; // Regelfaktor P-Anteil !!! Divisor ### war 5
      Ki12=Ki34     =   22; // Regelfaktor I-Anteil !!! Divisor
      Kd12=Kd34     =    4; // Regelfaktor D-Anteil !!! Divisor
    //ATSfak        = 1856; // AnTriebsStrang-faktor => Umrechnung von mm/s auf stupsi
      ATSfak        =  619; // AnTriebsStrang-faktor => Umrechnung von mm/s auf stupsi
      regel12=regel34 = 0;  // Ein-Ausschalter Regelung, regel = 1 => Regelung ist EIN
      rglsv12  = regel12; rglsv34  =  regel34;      // Regelflag, Sicherung
      XTI_0_1_init( );      // Init extINT 0 und 1                                 mot
      TC0CMPit();           // Init TmrCnt0 CmprMtchA, Regelungsaufruf 100Hz/Kanal tmr
      TC1PWM_init();        // Init Tmr/Cntr1 fr PWMs/Mot12 + Mot34               mot
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      sei();  //Globalen Interrupt freigeben
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      inKOlst();            // Initialisierung, KOnstanten-Liste = div. Vorgaben   kal
                            // Aufruf NACH sei(), weil evtl irDMEs abgefragt werden.
      init_uart0 ( F_CPU / BAUD / 16 - 1 );  // Init UART0 (NICHT nach PDannegger)
      I2C_init ();          // I2C-Buffer initialisieren, I2C-Slave-Init           I2C
    // - - - - - - - - - - - - - - -
      wms ( 1000);          // Zeit frs Startinfo - NUR FR TESTphase ! ! !
      info01();             // Startinfo ber USART ausgeben                       main
    Auszug *com*.h
    Code:
      volatile s16  M12ocr; // temporrer Stellwert fr OCR1A        -255...255
      volatile s16  M12inc; // vorzeichenbehaft. Incr, default:        -1, +1
      volatile s16  tdek1;  // Timer-Dekrement = Vorgabe fr tmot1
      volatile s16  P4soll; // PWMsollwert bei Aufruf wird aus speed bernommen,
                            //   speed wird nicht weiter verwendet
      volatile s16  M34ocr; // temporrer Stellwert fr OCR1A        -255...255
      volatile s16  M34inc; // vorzeichenbehaft. Incr, default:        -1, +1
      volatile s16  tdek4;  // Timer-Dekrement = Vorgabe fr tmot4
    inKOlst
    Code:
    // ============================================================================== =
      void inKOlst (void)           // Initialisierungen
     {                              //
     //             war 50 bis 30. Dez. 2013
      tdek1         =    6;         // default Startwert PWM-Timer - wird dekrementiert
      tdek4         =    6;         // default Startwert PWM-Timer - wird dekrementiert
      return;                       //
     }                              //
    // ============================================================================== =
    Auszug Timer
    Code:
    // ============================================================================= =
    // ===  Nicht unterbrechbare ISR fr timer2 =================================== */
    // Takt 20 Ips bei 20Mhz - Routine fr regelmssige Ablufe mit 
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     ISR(TIMER2_COMPB_vect)         // Vekt 0x008, Timerroutine fr "allgemeine Zwecke"
     {                              //   .. die nicht so eng zeitgebunden sind
    // - - - - - - - - - - - - - - - -
      Izeit_2 --;           //  ###>>> Izeit_2 ist aktuell int16_t ==>>
      if ( !Izeit_2 )       // WENN Izeit_2 != Null => wahr => Anweisung ausgefhren
      {                     // Eine Sekunde ist voll => Izeit_2 auf Hrznt_2 setzen
        Izeit_2 = Hrznt_2;  // ansonsten: Rckstellen auf Zeithorizont2
      }             // Ende if ( !Izeit_2 )
    // - - - - - - - - - - - - - - - -
    //      PWM-Rampe fr Motor1/Mot12 - wird ber tmoti/tdeki gesteuert
      if ( tmot1 )                          // Ist der Rampencounter != 0 ?
      {                                     //
        tmot1 --;                           // ... dann dekrementiere ihn bis
        if ( !tmot1 )                       // ... der Rampenwert abgelaufen ist
        {                                   //
          M12ocr    =  M12ocr + M12inc;     //##>>begang zu NEGATIVEn M12ocr mglich
    //      Es folgt Drehrichtungsumkehr NACH Nulldurchgang
    // war if (( M12ocr < 0) && (-1 == M12ocr)) Mrechtszur (); und sinngem //
          if (-1 == M12ocr) Mrechtszur ();  //
          if ( 1 == M12ocr) Mrechtsvor ();  //
    //      Setze OCR1A aus vorzeichenbehaftetem M12ocr
          if (M12ocr >= 0) OCR1A = M12ocr;  //
          else OCR1A = -1*M12ocr;           //
          if (M12ocr == P1soll) tmot1 = 0;  // Rampe12: Ende mit Sollwert erreicht
          else tmot1 = tdek1;               //   ansonsten ReInit Timer auf Rampenwert
        }                   // Ende if ( !tmot1 )
      }             // Ende von if ( tmot1 )
    // - - - - - - - - - - - - - - - -
    //      PWM-Rampe fr Motor4/Mot34
      if ( tmot4 )                          // Rampencounter > 0
      {                                     //
        tmot4 --;                           //
        if ( !tmot4 )                       // Wenn Rampenwert abgelaufen ist
        {                                   //
          M34ocr    =  M34ocr + M34inc;     //##>>bergang zu NEGATIVEn M34ocr mglich
    //      Es folgt Drehrichtungsumkehr NACH Nulldurchgang (siehe auch oben)
          if (-1 == M34ocr) Mlinksvor ();   //
          if ( 1 == M34ocr) Mlinkszur ();   //
    //      Setze OCR1A aus vorzeichenbehaftetem M34ocr
          if (M34ocr >= 0) OCR1B = M34ocr;  //
          else OCR1B = -1*M34ocr;           //
          if (M34ocr == P4soll) tmot4 = 0;  // Rampe34: Ende mit Sollwert erreicht
          else tmot4 = tdek4;               //   ansonsten ReInit Timer auf Rampenwert
        }                   // Ende if ( !tmot4 )
      }             // Ende von if ( tmot4 )
    // - - - - - - - - - - - - - - - -
      return;
     }       // Ende ISR(TIMER2_COMPA_vect)
    // ============================================================================= =

    Quelltext sprung (kplt) - hier wurde der falsche Wert entdeckt:
    Code:
    // ============================================================================= =
    // ==   Fahre Sprungfunktion, messe Sprungantwort       Aufruf aus r1n/do_MOSTL2
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      void sprung ( u8 m_buff[14] ) // Fahre Sprungfunktion, messe Sprungantwort
     {                              //
    // - - - - - - - - - - - - - - - -
    //char abc[12];                 // bersetzungsfeld fr Werteausgabe UART
      char s[10];                   // lok. String zum Dekodieren der SOLLFAHRT mm/sec
      s16   s16mot  = 0;            // SOLLfahrt Motor, 2 Bytes : unsigned int16_t
      u8    i       = 0;            // Variable
      u8    motNR;                  // MotorNummer 1 (mot12) oder 4 (mot34)
      u8    vz      = 0;            // Drehrichtungscode: 45 = li, 43 = re, 112 = aus
    // - - - - - - - - - - - - - - - -
    //      ncx0 wird mit Wert 255 im main initialisiert und damit "abgeschaltet"
    //      WENN ncx0 < 128 ist (erstes Bit ist 0) dann wird im Timer0 incrementiert
    //ncx0  =  255;                 // Initialisiere Pointer auf 1 vor berlauf
    // - - - - - - - - - - - - - - - -
    //      Die aufrufenden Parameter als Kontrolle/Besttigung auf UART ausgeben
      for ( i=0; i<9; i++) { s[i] = m_buff [i]; }  // Aufrufparameter kopieren
      s[9]         = 0;             // Markiere Stringende "0"=letzten Bitfeldelement
      uputs0 ("\r\t>>\t");uputs0 ( s );
    // - - - - - - - - - - - - - - - -
    //      Regelungen und sonstige Parameter abschalten:
      regel12  =  regel34  =  0;    // BEIDE REGELUNGen ausschalten
      
    // - - - - - - - - - - - - - - - -
    //      Dekodiere PWM-Vorzeichen und PWM-Stellwert
      vz    = m_buff[3];            // Drehrichtungscode: 45 = '-' => math neg
      for ( i=0; i<=2; i++) { s[i] = m_buff [i+3]; }  // im Byte 2 bis 5 {0-5}
      s[3]    = 0;                  // Markiere Stringende "0"  
      s16mot  = atoi ( s );         // vorzeichenbehafteter Motor-/PWM-Stellwert
    // - - - - - - - - - - - - - - - -
    //      Motor NR dekodieren und Daten melden
      motNR = m_buff[1] -  48;      // nmot ist die Motornummer 1 (12) oder 4 (34)
      if ( !(motNR == 1) && !(motNR == 4) ) return; // NUR mot12 oder mot34
      uputs0 ("\r\tmotNR "); uputs0i ( motNR );     // Nenne Motorkennung
      uputs0 ("\tSprung=> ");
      uputs0 ("\tPWM/tdek ");
      if ( s16mot < 0 ) s16mot = 0 - s16mot;        // s16mot MUSS positiv werden
    
    // - - - - - - - - - - - - - - - -
    //      Motor auswhlen, einschalten und Test fahren; 
    //      Anmerkung: die Auswahl "5"<=> beide Motoren ist fr die Messung der
    //      Sprungantwort nicht sinnvoll wegen der Datenerfassung
      switch ( motNR )              // Fallunterscheidung nach Motornummer
      {                             //
      case 1:                       // Anmerkung: ASCIIcode: 45 = '-' => math neg
        Mrechtsaus ();              // Zur Sprungaufnahme erstmal stoppen und
        wms ( 1000);                //      Auslauf abwarten
        uputs0i(s16mot);uputs0 ("/");uputs0i(tdek1);
        break;                      //
      case 4:                       //
        Mlinksaus ();               // Zur Sprungaufnahme erstmal stoppen und
        wms ( 1000);                //      Auslauf abwarten
        while ( Izeit_1 <= 15000 ) { }  // Nix tun, wenn Zeit zu kurz
        uputs0i(s16mot);uputs0 ("/");uputs0u(tdek4); // #####
        break;                      //
      default:
        break;
      }             // Ende switch ( motNR )
    //uputs0 ("\t\tMot=on");          // Gefahr von Zeitverzug beim Starten, daher
    //      diese Meldung lieber erstmal nicht ausgeben
    
    // - - - - - - - - - - - - - - - -
    //      Warten um nicht mit der Messung in einen Zeitberlauf zu kommen
      while ( Izeit_1 <= 15000 ) { }        // Nix tun, wenn Zeit zu kurz, damit
                    //  die Messung nicht in einen Time-berlauf luft
    
    //      Fnf Messungen IM STILLSTAND VOR DEM MOTORSTART
      switch ( motNR )              // Fallunterscheidung nach Motornummer
      {                             //
      case 1:                       // Anmerkung: ASCIIcode: 45 = '-' => math neg
        for ( i = 0; i <  6; i++ )  //
        {                           //
          messdat1  [ i] = Izeit_1; // Zeit = volatile s16  messdat1..3[100]
          messdat2  [ i] = IencB0;  // s16 - Encoderstand
    //    messdat3  [ i] = OCR1A;   // PWM-Wert
          wms (   2);               // Ungefhrer Messwert-Abstand
        }                   // Ende for ( i = 1; i < 100; i++ )
        if (vz==45) Mrechtszur ();  // Motortreiber 1 auf '+' math pos stellen
        else  Mrechtsvor ();        // Motortreiber 1 auf '-' math neg stellen
        OCR1A       = s16mot;       //
        break;              //
      case 4:                       //
        for ( i = 0; i <  6; i++ )  //
        {                           //
          messdat1  [ i] = Izeit_1; // Zeit = volatile s16  messdat1..3[100]
          messdat2  [ i] = IencB1;  // s16 - Encoderstand
    //    messdat3  [ i] = OCR1B;   // PWM-Wert
          wms (   2);               // Ungefhrer Messwert-Abstand
        }                   // Ende for ( i = 1; i < 100; i++ )
        if (vz==45) Mlinksvor ();   // Motortreiber 4 auf '+' math pos stellen
        else  Mlinkszur ();         // Motortreiber 4 auf '-' math neg stellen
        OCR1B       = s16mot;       //
        break;                      //
      default:
        break;
      }             // Ende switch ( motNR )
    // - - - - - - - - - - - - - - - -
    // ####>>>>     Der Motor luft jetzt, Daten also SOFORT beim Hochlaufen erfassen
      //              danach ne WEile warten !!! UND den Motor wieder ausschalten !!!
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Es werden jetzt die aktuellen Daten festgehalten fr Messfahrt 
    //      Beispiel von ..C2\D01-3_40\D01-3_40_mot_x23.c vom 15. Oktober 2009, 11:12:46
    //      ##>> Der folgende, aktuelle Code ist neu gestaltet
      switch ( motNR )              // Fallunterscheidung nach Motornummer
      {                             //
      case 1:                       // Anmerkung: ASCIIcode: 45 = '-' => math neg
        for ( i = 6; i < 30; i++ )  //
        {                           //
          messdat1  [ i] = Izeit_1; // Zeit = volatile s16  messdat1..3[100]
          messdat2  [ i] = IencB0;  // s16 - Encoderstand
    //    messdat3  [ i] = OCR1A;   // PWM-Wert
          wms (   2);               // Ungefhrer Messwert-Abstand
        }                   // Ende for ( i = 1; i < 100; i++ )
        break;              //
      case 4:                       //
        for ( i = 6; i <  30; i++ ) //
        {                           //
          messdat1  [ i] = Izeit_1; // Zeit = volatile s16  messdat1..3[100]
          messdat2  [ i] = IencB1;  // s16 - Encoderstand
    //    messdat3  [ i] = OCR1B;   // PWM-Wert
          wms (   2);               // Ungefhrer Messwert-Abstand
        }                   // Ende for ( i = 1; i < 100; i++ )
        break;                      //
      default:
        break;
      }             // Ende switch ( motNR )
    
      switch ( motNR )              // Fallunterscheidung nach Motornummer
      {                             //
      case 1:                       // Anmerkung: ASCIIcode: 45 = '-' => math neg
        for ( i = 30; i < 100; i++ )  //
        {                           //
          messdat1  [ i] = Izeit_1; // Zeit = volatile s16  messdat1..3[100]
          messdat2  [ i] = IencB0;  // s16 - Encoderstand
    //    messdat3  [ i] = OCR1A;   // PWM-Wert
          wms (   4);               // Ungefhrer Messwert-Abstand
        }                   // Ende for ( i = 1; i < 100; i++ )
        uputs0 ("\r\tiMessg\tIzeit_0\tIencB0\tOCR1A");
        break;              //
      case 4:                       //
        for ( i = 30; i < 100; i++ ) //
        {                           //
          messdat1  [ i] = Izeit_1; // Zeit = volatile s16  messdat1..3[100]
          messdat2  [ i] = IencB1;  // s16 - Encoderstand
    //    messdat3  [ i] = OCR1B;   // PWM-Wert
          wms (   4);               // Ungefhrer Messwert-Abstand
        }                   // Ende for ( i = 1; i < 100; i++ )
        uputs0 ("\r\tiMessg\tIzeit_0\tIencB1\tOCR1B");
        break;                      //
      default:
        break;
      }             // Ende switch ( motNR )
    // - - - - - - - - - - - - - - - -
    //uputs0 ("\r\tiMessg\tIzeit_0\tIencB0");
      for ( i = 0; i < 100; i++ )
      {                             //
        uputs0 ("\r\t"); uputs0i ( i );
        uputs0 ("\t");   uputs0u (messdat1[i]);
        uputs0 ("\t");   uputs0u (messdat2[i]);
    //  uputs0 ("\t");   uputs0u (messdat3[i]);
      }                     // Ende for ( i = 0; i < 100; i++ )
      wms ( 2000);          // Warte Sprungantwort ab
      switch ( motNR )      // Motor aus mit Fallunterscheidung nach Motornummer
      {                     //
      case 1:               //
        Mrechtsaus ();      //                                                     mot
        break;
      case 4:               //
        Mlinksaus ();       //                                                     mot
        break;
      default:              //
        break;
      }             // Ende switch ( motNR )
      uputs0 ("\r\tSprungantwort steht\r");
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     }      // Ende void sprung ( void )
    // ============================================================================= =
    Ciao sagt der JoeamBerg

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beitrge
    1.220
    Hmm, interessant. Arbeitest du in der Ecke irgendwo mit Zeigern, von denen einer vielleicht das Ziel knapp verfehlt? Testweise knntest du noch eine weitere Variable nach tdek4 anlegen und Mal beobachten ob die auch betroffen ist.
    Wie sieht die Speichersituation auf dem AVR aus? Es gibt ein kleines Tool im RN-Wissen mit dem man auf eine Heap-Stack-Kollision prfen kann: http://www.rn-wissen.de/index.php/Sp...en_mit_avr-gcc

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

  5. #5
    Erfahrener Benutzer Robotik Visionr Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgu
    Beitrge
    7.554
    ... Arbeitest du ... irgendwo mit Zeigern ... Wie sieht die Speichersituation auf dem AVR aus? ...
    Markus - erstmal vielen Dank fr Deine Mhe und Geduld.

    Zweitens: ich habe drei Messdaten-Felder, das dritte ist
    volatile s16 messdat3[100]; // Messwertspeicher fr Tests

    Wenn das "an" ist, dann gibts:
    Program: 11224 bytes (34.3% Full)
    (.text + .data + .bootloader)
    Data: 1960 bytes (95.7% Full)
    (.data + .bss + .noinit)

    ... und die beschriebene Datenausgabepanne.

    Wenn ich dieses Feld streiche (und dessen Benutzung) dann gibts:
    Program: 11080 bytes (33.8% Full)
    (.text + .data + .bootloader)
    Data: 1762 bytes (86.0% Full)
    (.data + .bss + .noinit)

    ... und keine Datenausgabepanne. Nun msste ich dem noch etwas mehr nachlaufen und schauen, ob vielleicht andere Daten noch korrumpiert sind. Mach ich im Moment nicht (faul, Zeitnot etc, Sprungfunktion luft primstens - und ist fast erledigt) und daher

    Dank nochmal und ich hre mit dem Problem und dem leichten Verdacht auf irgendeinen Stackberlauf auf.
    Ciao sagt der JoeamBerg

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beitrge
    1.220
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Dank nochmal und ich hre mit dem Problem und dem leichten Verdacht auf irgendeinen Stackberlauf auf.
    Leichter Verdacht? 1960 von 2048 Bytes belegt erklrt alles! Da ksst der Stack ziemlich sicher deine Daten. Die verbleibenden 88 Byte verknusperst du zum Frhstck mit irgendwelchen Funktionsargumenten, Stringarrays etc. (alleine im Kontext von sprung zhle ich grob berschlagen 29 Byte und ein ISR-Aufruf sichert alle genutzten Register, was auch mal 32 Bytes + Rcksprungadresse kosten kann).

    Tipp: Ich meine im Hinterkopf zu haben, dass statische Strings vom Compiler als Konstanten im RAM abgelegt werden. Du knntest 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

  7. #7
    Erfahrener Benutzer Robotik Visionr Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgu
    Beitrge
    7.554
    Zitat Zitat von markusj Beitrag anzeigen
    ... alleine im Kontext von sprung zhle ich grob berschlagen 29 Byte und ein ISR-Aufruf sichert alle genutzten Register, was auch mal 32 Bytes + Rcksprungadresse 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 darber - 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 mglich sind, die mich dort das eine oder andere Mal wirklich gestrt 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 htte. Wenn ich ber die Testphase drber bin, dann gehen etliche Strings raus oder werden zurckgestutzt; der wesentliche Anteil davon sind Bemerkungen die fr den laufenden (autonomen) Betrieb weniger bis gar keine Bedeutung haben. Da ich ausserdem das Thema PROGMEM immer noch als bhmisches Dorf vor mir herschiebe und meinem Zeitplan hinterherhinke bin ich ber diese ramfressende Methode nicht hinausgekommen.

    Danke fr Deine Untersttzung.
    Ciao sagt der JoeamBerg

  8. #8
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beitrge
    497
    Hallo Joe,

    das mit dem Progmem ist kinderleicht und bewahrt einen wirklich vor bsen 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_ */
    Gendert von sast (21.01.2014 um 15:38 Uhr)

    雅思特史特芬
    开发及研究

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beitrge
    1.220
    Zitat Zitat von sast Beitrag anzeigen
    das mit dem Progmem ist kinderleicht und bewahrt einen wirklich vor bsen 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 verndert. Der EEPROM ist noch langsamer im Zugriff als der Flash, aber bei timingkritischen Anwendungen ist das eben ein relevanter Faktor. Auerdem: Warum so umstndlich mit der zustzlichen Zeigertabelle? Um von den zwei Byte des Pointers ein Byte einzusparen im Tausch gegen schlecht zu debuggende "Magic Numbers"? In dem Fall wre es ratsam, anstatt der Zahlenwerte einen enum zu nutzen.

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

  10. #10
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beitrge
    497
    Markus knntest du das mal bitte an einem konkreten Beispiel zeigen, was du meinst?

    Danke
    sast

    雅思特史特芬
    开发及研究

Seite 1 von 2 12 LetzteLetzte

hnliche Themen

  1. per TV-remote ein "move" programmablauf auslsen..
    Von carlitoco im Forum Robby RP6
    Antworten: 4
    Letzter Beitrag: 01.04.2008, 21:59
  2. Stecker in "Computer-Gre"
    Von danst im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 13.01.2007, 16:19
  3. "Leser stellen sich vor" - Was haltet ihr davon?
    Von Florian im Forum Umfragen
    Antworten: 31
    Letzter Beitrag: 17.03.2006, 17:52
  4. IO-Pins lassen sich nicht richtig mit "bsf"/"
    Von keiang im Forum PIC Controller
    Antworten: 3
    Letzter Beitrag: 21.07.2005, 20:12
  5. AT90S2313 - RX-Interupt - Der "hngt sich auf"
    Von Gottfreak im Forum AVR Hardwarethemen
    Antworten: 10
    Letzter Beitrag: 14.05.2004, 00:32

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhnge hochladen: Nein
  • Beitrge bearbeiten: Nein
  •