Hat das schon jemand bei einem Controller in C gemacht? Ich weiss grundsätzlich wie das funktioniert, doch gibts noch sachen die man speziell beachten muss? Hat jemand ein Beispiel in C (egal für welchen Controller oder compiler, geht mir ums prinzip....) mfg Daniel
Virtual Stack? Du meinst sicher eine Virtual Stack Machine - also z.B. ein FORTH-Interpreter?
das ganze funktiniert mir nicht wirklich... doch was mach ich falsch Stack overflow: >>while( SP < STKUN) >>{ >> stack[uwStackIndex] = _pop_(); >> uwStackIndex = uwStackIndex + 1; >>} muss ja im prinzip nur den stackinhalt lesen (pop) sonstwo speichern..., ich speichere dies hier in einem vordefinierten speicherbereich auf dem Ram... oder sonst noch was? wie siehts aus, bin ja bei einem stackoverflow in einem Interrupt, wie siehts grundsätzlich aus wenn der controller wieder zurück an die stelle wo er vor dem stack overflow gewesen ist, springen muss, braucht er da daten vom stack? oder wie schaut das aus?
Keiner kann in Deinen Kopf schauen. Erzähl doch erstmal, was Du machen willst. In C sind PUSH und POP verbotene Befehle, die gehören dem Compiler ganz allein. Nach einem Stackoverflow kannst Du nicht zurück, da ja schon ein ungültiger Bereich benutzt wurde. Du kannst ne Fehlermeldung ausgeben und vielleicht noch nen RAM-Dump (ohne Unterfunktionen !) und dann ein Reset machen (Sprung zu 0x0000 oder Watchdog). Peter
Hallo Peter, verwende eine C167CR-LM, mit einem u3v compiler von keil. Im prinzip ist mein stack nicht zu klein... Habe aber das problem, dass ich ab und zu immer wieder einen stack overflow erhalte, einer wo keiner sein sollte (überschreib ich den oberen teil des stackbereichs mit 0xAAAA beim booten) und lese ich dann den stack bei einem stack overflow aus, sind die wörter in welche ich das 0xAAAA schrieb, immer noch auf 0xAAAA... was für mich heisst, das eigentlich kein stack overflow stattgefunden habe dürfte, was aber trotzdem der fall ist... --> Da ich das Problem nicht in den griff bekommen will, und ich hier im forum auch keine ideen erhalten habe, mit welchen ich das problem lösen könnte, war die idee, den stack weiter zu vergrössern, indem ich ihn bei einem stack overflow ins externe ram lade, und beim unterflow wieder zrückhohle... Wäre auch wenns funktioniert keine wirklich saubere lösung ok, aber weiss sonst schlichtwegs nicht wie ich die stack overflows in den Griff kriegen soll... (wäre für hinweise oder anregungne sehr dankbar...) >>In C sind PUSH und POP verbotene Befehle, die gehören dem Compiler ganz >>allein. naja die sind im Handbuch des Compilers aufgeführt... die funktion wird über eine library aufgerufen... müsste von daher schon passen... oder sehe ich da was falsch?
Hi, sowiet ich mich errinnern kann bedeutet ein Stack-Overflow, wenn der Stackpointer auf eine zu kleine Adresse dekrementiert wird. Ist im Handbuch nachzulesen. Für dein Problem musst du ober und unterhalb vom Stack deine KEnnung reinschreiben und auslesen. Du kannst aber die Größe des Stacks beim 167 einfach über das inifile vergrößern. Grüße, Michael
Michael wie das mit dem stack funktiniert hab ich nachgelesen (hoffe auch begriffen... :-) ) ja ist mir bekannt, dass ich die stackgrösse ändern kann (aber im inifile???? mach das im startupfile (*.A66)... funktioniert soweit auch (lese die entsprechenden werte jeweils über die serielle schnittstelle aus...) >>Für dein Problem musst du ober und unterhalb vom Stack deine KEnnung >>reinschreiben und auslesen. äh das ist mir jetzt nicht ganz klar... meine wenn ich eine kennung in den oberen bereich des stacks schreibe, muss diese doch bei einem allfälligen stack overflow zwangsweise überschrieben werdne nicht? Wie ich in einem buch gelsen habe, sind je nach dem die 2-3 Wörter oberhalb des STKOV für rücksprungadresse reserviert und müssen daher freigehalten werden...
Hi, ja, habe das startup-file damit gemeint. Zur Erklärung der Trap-funktionen kannst du im Handbuch auf der Seite 5-31 nachlesen wann welcher Trap gesetzt wird und da steht es mit dem Stack Overflow so drinnen wie oben beschrieben. Btw. Warum hast du eigentlich einen Stack overflow, habe das noch nicht zusammengebracht. Sind deine Funktione vielleicht zu tief geschachtelt? Grüße, Michael
Michael, ahhh ok... warum ich einen stack overflow habe? keine ahnung..., das versuch ich rauszufinden... meine funktionen sind zwar leicht geschachtelt, aber gehe eigentlich davon aus, das sonst ein fehler vorliegt..., zumindes von den werten her, welche ich jeweils auslese... benutzt zu auch u3v den keil compiler?
Daniel wrote: >>>In C sind PUSH und POP verbotene Befehle, die gehören dem Compiler ganz >>>allein. > naja die sind im Handbuch des Compilers aufgeführt... die funktion wird > über eine library aufgerufen... müsste von daher schon passen... oder > sehe ich da was falsch? Himmel, völlig egal was da irgendwo als Intrinsic definiert ist, was denkst du wohl was passiert, wenn du sowas machst (unter der Annahme, dass der Compiler die Rücksprungadresse auf den Stack schreibt, also keine Link-Register oder ähnliches verwenden kann): void f() { __pop__(); } wenn man auf einem uC arbeitet, braucht man einfach ein gewisses Grundverständnis davon, wie ein Compiler Unterprogramme implementiert. BTW: meines Wissens hat der C167 zwei Stacks einen System- und einen User-Stack, welcher läuft denn eigentlich über? Verwendest du Rekursion oder übrigbst große Sachen per Value? Ciao, Fabian
Für einen Stack-Overflow gibt es eigentlich nur einen Grund: Zu tief verschachtelte Funktionsaufrufe. Meistens hervorgerufen von rekursiven Funktionen. Man sollte auf µCn NIE rekursiv programmieren. Oder benutzt du den Hardwarestack etwa für die implementation deiner Virtual Stack Machine? Das solltest du nicht tun. Der Hardware Stack dient einzig und allein dem Zeck der Speicherung der Rücksprungaddresse oder temporären Variablen. Der User sollte NIE direkt auf den Hardwarestack zugreifen. In dem Fall empfehle ich einen einfachen Software Stack zu verwenden:
1 | #define STACK_BLOCK_SIZE 16
|
2 | int error; |
3 | int *stack; |
4 | int stacksize = STACK_BLOCK_SIZE; |
5 | int stackpos = 0; |
6 | |
7 | int initstack() |
8 | {
|
9 | if(stack) cleanstack(); |
10 | stack = malloc(STACK_BLOCK_SIZE*sizeof(int)); |
11 | if (!stack) return 0; |
12 | stacksize = STACK_BLOCK_SIZE; |
13 | stackpos = 0; |
14 | error = 0; |
15 | return 1; |
16 | }
|
17 | |
18 | void cleanstack() |
19 | {
|
20 | free(stack); |
21 | stack = NULL; |
22 | }
|
23 | |
24 | int push(int num) |
25 | {
|
26 | if(stackpos == stacksize) |
27 | {
|
28 | stacksize += STACK_BLOCK_SIZE; |
29 | stack = realloc(stack, stacksize*sizeof(int)); |
30 | if (!stack) return 0; |
31 | }
|
32 | stack[stackpos++] = num; |
33 | return 1; |
34 | }
|
35 | |
36 | int pop() |
37 | {
|
38 | if (!stackpos) { error = 1; return 0; } |
39 | return stack[--stackpos]; |
40 | }
|
ok danke für die antworten, hab das problem gelöst.... hat als vorlage für mein print layout ein (angeblich funktionierendes) eines kollegen... der NMI Pin war daher in der luft... wiso nun ein stack overflow kam ist mir immer noch schleierhaft. hab den Nmi trap interrupt rausgenommen (naja wiso unnnötig speicher verschwenden), und aus einem mir unerklärlichen grund, kam dann bei einem NMI interrupt einfach ein stack overflow, hab ich den NMI interrupt eingefügt, kam dieser... (die haben zwar das gleiche interruptregister, aber ist trotzdem völlig unverständlich für mich, wiso der falsche interrupt kommen kann...) würd mich noch wunder nehmen, jemand ne idee...?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.