Forum: Mikrocontroller und Digitale Elektronik viritual Stack


von Daniel (Gast)


Lesenswert?

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

von :emaN (Gast)


Lesenswert?

Virtual Stack? Du meinst sicher eine Virtual Stack Machine - also z.B. 
ein FORTH-Interpreter?

von Daniel (Gast)


Lesenswert?

genau ja....

von Daniel (Gast)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

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

von Daniel (Gast)


Lesenswert?

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?

von MSc (Gast)


Lesenswert?

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

von Daniel (Gast)


Lesenswert?

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

von MSc (Gast)


Lesenswert?

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

von Daniel (Gast)


Lesenswert?

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?

von MSc (Gast)


Lesenswert?

Hallo Daniel,

ja, ich benutze den Keil-Compiler mit uv3.

von Fabian S. (rosepeter)


Lesenswert?

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

von Keil (Gast)


Lesenswert?

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
}

von Daniel (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.