mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik viritual Stack


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: :emaN (Gast)
Datum:

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

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
genau ja....

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: MSc (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: MSc (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: MSc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Daniel,

ja, ich benutze den Keil-Compiler mit uv3.

Autor: Fabian Scheler (rosepeter)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Keil (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#define STACK_BLOCK_SIZE 16
int error;
int *stack;
int stacksize = STACK_BLOCK_SIZE;
int stackpos = 0;

int initstack()
{
  if(stack) cleanstack();
  stack = malloc(STACK_BLOCK_SIZE*sizeof(int));
  if (!stack) return 0;
  stacksize = STACK_BLOCK_SIZE;
  stackpos = 0;
  error = 0;
  return 1;
}

void cleanstack()
{
  free(stack);
  stack = NULL;
}

int push(int num)
{
  if(stackpos == stacksize)
    {
      stacksize += STACK_BLOCK_SIZE;
      stack = realloc(stack, stacksize*sizeof(int));
      if (!stack) return 0;
    }
  stack[stackpos++] = num;
  return 1;
}

int pop()
{
  if (!stackpos) { error = 1; return 0; }
  return stack[--stackpos];
}

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.