[Solved] for loop stürzt ab



  • Hallo!
    Ich habe eine sehr interessante/verrückte Frage: Wie kann es passieren, dass sich eine einfache for loop aufhängt bzw. ihre Bedingungen nicht einhält?

    Folgender Code:

    uint8_t i;
    
    for(i=0; i<=5; i++) {
         vek[i].X=0; 
         vek[i].Y=0; 
         vek[i].Z=0; 
    }
    

    hängt sich einfach auf. Beim debuggen nimmt i die Werte 0, 1, 2, 0(!!), 1, 2, 3, 4, 5 ein und hängt danach. Ersetzt man uint8_t mit short, dann passiert genau das gleiche, nur das i auch einfach größer als 5 wird und der Prozessor irgendwann einfach einen reset macht.

    Diese Schleife läuft als Funktion auf einem atmel avr tadellos, wird Sie allerdings nicht direkt von der Main Funktion aus gestartet, sondern von einer Funktion die unterhalb von Main liegt (also Main -> foo -> bar -> bla -> schleife) dann funktioniert Sie nicht mehr.

    Klingt verrückt, aber wenn ihr wollt, dann kann ich ein Video vom debugger uploaden.

    Irgendwelche Ideen wie das passieren kann?

    Danke!



  • Das kann daran liegen, dass vek zu klein ist und du über die Grenze hinaus schreibst (wo wohl zufällig gerade i liegt).



  • Mhm, das ist zwar eine mögliche Erklärung, aber doch eher unwahrscheinlich.

    IK_Point3d vek[6];
    
    typedef struct IK_Point3d{
         float X;
         float Y;
         float Z; 
    } IK_Point3d;
    

    Sollte doch passen, oder hab ich irgendwo einen dummen Fehler.



  • Dann zeig doch einfach mal den kompletten Code (oder ein Minimalbeispiel, das den Fehler aufweist), dann kommen wir sicher schnell dahinter.



  • War da nicht was bei Compilern für Systeme und Programmiersprachen mit wenig Speicher mit der maximalen Verschachtelungstiefe von Schleifen und/oder Unterprogrammen/Funktionen?

    Auf deinem Amtel avr kommt doch ein besonders optimierter C-Compiler zum Einsatz oder?

    MfG f.-th.



  • So sieht das normalerweise aus für einen int-Vektor mit 5 Elementen:

    int i;
    int vek[5];
    
    for(i=0;i<5;i++)
    {
       vek[i].X=0; 
       vek[i].Y=0; 
       vek[i].Z=0; 
    }
    

    Wie kann eine for-Schleife abstürzen? Ausser man macht darin etwas, was zum Absturz führt. Warum für die Laufvariable i kein normales int? Ich verstehe das Problem nicht. 😮



  • Er hat uns sicher nicht alles gezeigt, ist doch klar.

    P.S.: die Entsprechung für uint8_t ist natürlich unsigned char, nicht (unsigned ) short...



  • @f.-th.: Ja stimmt, ist der win-avr 20070525 (gcc 4.1.2). An so ein Problem hab ich auch schon gedacht, allerdings wunderts mich, dass so ein Fehler schon in der 5. Verschachtelungstiefe auftritt. Ich meine, dass man keine tiefen Rekursionen durchführen kann ist mir klar, aber 5 Verschachtelungen sollten doch gehen?

    @berniebutt: Es ist ja auch kein Array mit 5 Werten sondern eins mit 6, von daher sollte das doch stimmen!? int hab ich deswegen nicht genommen, weil auf der Hardware sowieso Speicherplatz eher rar ist und ich für die Zahlen von 0 - 5 das ja eigentlich nicht brauche... Mit Abstürzen meine ich, dass sich der Prozessor resetet, sprich er beginnt mit dem kompletten Programm von vorne bzw, dass er sich aufhängt, als wie wenn er in einer Endlosschleife wäre, auch der Debugger bleibt einfach stecken.

    Ausschauen tut das ganze in etwa so:

    main.c

    int main (void)
    {
    
       float speed = 10, stepx, stepy;
       X3_Point3d leg[6], vek[6];
       RC_GamePadData Joystick;
       X3_LockStruct mutex[2];
    
       //initialize all modules
       Init();
    
       X3_LockInit(X3_TripodMoveBeat, 0, mutex);
       X3_LockInit(X3_TripodMoveCircleBeat, 1, mutex);
    
       ....
       ....
    
       for(;;)
       {
          //Receive data from GamePad
          Data = RC_GetGamePadButtons();
          Data ^= 0xFF;
          RC_GetGamePadData(&Joystick);
    
          ...
          ...
          //Move hexapod according to input
          X3_TripodMoveBeat(leg, vek, stepx, stepy, speed, delaytime, mutex);
    
          ...
          ...
       }
    
       return 0;
    }
    

    legs.h:

    ...
    //Structure for Points/Vectors in 3D space
    typedef struct X3_Point3d {
    	float X,Y,Z;
    } X3_Point3d;
    ...
    

    legs.c:

    ...
    //Set vector movement to zero
    void X3_SetVectorMovementZero(X3_Point3d *vek)
    {
     //IN DIESER FUNKTION TRITT DER FEHLER AUF:
    	uint8_t i;
    	for (i = 0; i <= 5; i++)
    	{
    		vek[i].X = 0;
    		vek[i].Y = 0;
    		vek[i].Z = 0;
    	}
    }
    ...
    

    tripod.c:

    void X3_TripodMoveBeat (X3_Point3d *leg, X3_Point3d *vek, float stepx, float stepy, float speed, uint8_t delaytime, X3_LockStruct *mutex)
    {
       uint8_t i;
       //Check if there are any locks set and if so remove them
       X3_CheckLocks(mutex, 0, leg, vek, speed, delaytime);
       switch (mutex[0].lock)
       {
         case 0:
            ....
            //Lock in current beat
            X3_Lock(0, mutex);
            break;
         case 1:
            ....
            //unlock again
            X3_Unlock(0, mutex);
            break;
       }
      //Set movement between Beats to zero
      X3_SetVectorMovementZero(vek);
    }
    

    mutex.h

    ...
    //Structure for the Lock
    typedef struct X3_LockStruct {
    	uint8_t lock;    //indicates if there are any locks and if so how many --> beat
    	void (*key) ();  //function which is able to solve this locks
    } X3_LockStruct;
    ...
    

    mutex.c

    //Initialize the lock with key (function that unlocks the mutex) and unlock it by default
    void X3_LockInit(void* key, uint8_t index, X3_LockStruct *mutex)
    {
    	mutex[index].key = key;
    	mutex[index].lock = 0;
    }
    
    //Set a lock 
    void X3_Lock(uint8_t index, X3_LockStruct *mutex)
    {
           ....
    	mutex[index].lock++;
          ....
    }
    
    //Check if there are any locks (except my own one) and if so then remove them
    void X3_CheckLocks(X3_LockStruct *mutex, uint8_t index, X3_Point3d *leg, X3_Point3d *vek, float speed, uint8_t delaytime)
    {
    	uint8_t i, j;
    	j=1;
    	for(i = 0; i <= j; i++)
    	{
    		if (i != index)
    		{
    			while (mutex[i].lock != 0)
    			{
    				mutex[i].key(*leg, *vek, 0, 0, speed, delaytime);
    			}
    		}
    	}
    
    }
    
    //Unlock
    void X3_Unlock(uint8_t index, X3_LockStruct *mutex)
    {
            ....
    	mutex[index].lock = 0;
           ....
    }
    

    Ich hoffe man versteht alles und es ist halbwegs programmtechnisch in passend gelöst (bin nur ein autodidaktischer Programmierer). Ich weiß nicht ob das mit den Mutex überhaupt so funktionieren kann, es war nur eine Idee, die ich durch diesen Fehler bisher nie testen konnte.

    Danke für eure Hilfe!



  • void X3_CheckLocks(X3_LockStruct *mutex, uint8_t index, X3_Point3d *leg, X3_Point3d *vek, float speed, uint8_t delaytime)
    {
    ... 
    //mutex[i].key(*leg, *vek, 0, 0, speed, delaytime); //  !!! FALSCHE PARAMETER (1+2) !!!
      mutex[i].key( leg,  vek, 0, 0, speed, delaytime);
    ...
    }
    


  • Oh, herzlichen Dank! Jetzt funktioniert alles tadellos, Pointer sind nicht so wirklich meine Stärke, vor allem weil so ein kleiner Stern alles zerstören kann.

    Danke nochmals.


Anmelden zum Antworten