[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 geradei
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.