mikrocontroller.net

Forum: Compiler & IDEs Stackeintrag löschen beim MSP430


Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

Ich wollte wissen, ob es möglich ist, beim MSP430 den obersten Eintrag 
im Stack zu löschen.
Ich habe folgendes Problem:
Wenn ein bestimmter Interrupt aufgerufen wird, darf der MSP nach dem 
Interrupt nichtmehr zurück zu der Programmzeile springen, von der er 
gekommen ist.
Deshalb würde ich vom Interrupt aus gerne direkt zu einer anderen 
Funktion springen. Wenn die alte Zeile im Stack aber nicht gelöscht 
wird, würde das einen Overflow verursachen.
Da ich kein wirklich erfahrener Programmierer bin, hab ich keine Ahnung, 
wie das geht, oder ob es überhaupt geht.
Wäre über eure Hilfe sehr dankbar.

Gruß Enton

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn ein bestimmter Interrupt aufgerufen wird, darf der MSP nach dem
> Interrupt nichtmehr zurück zu der Programmzeile springen, von der er
> gekommen ist.

Das ist ein kaputtes Design, das ist Dir klar, oder?

Ansonsten "löscht" man Einträge auf dem Stack durch Manipulation des 
Stackpointers, aber das sollte man in einer Hochsprache --und ich nehme 
an, daß Du in C programmierst-- nicht machen, dazu müsstest Du schon 
sehr genau wissen, was alles auf dem Stack steht. Kleiner Hinweis: Da 
werden nicht nur Rücksprungadressen, sondern auch Registerinhalte und 
bei C automatische Variablen gespeichert.

Autor: Antwortender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht schon.
Man kann den Stackpointer veraendern. Dieser beinhaltet die Addresse des 
obersten Stackeintrages. Die Adresse kannst du um 1 verringern, dann 
zeigt der Stackpointer auf den zweitobersten Eintrag.

Jetzt frag ich mich grad nur ob man nicht die Adresse beim MSP um 1 
erhoehen muss, ich meine mich das der Stack so organisiert ist dass er 
von oben nach unten waechst. Oder ist das Compilerabhaengig??? Da 
solltest du dich vorher noch mal schlau machen, wie dein Stack 
organisiert ist.

Am einfachsten geht die Stackpointermanipulation wohl mit 
Assemblerbefehlen.
Aber das ist schon ein ziemlicher Eingriff in den Ablauf des Programmes. 
Ich hab es auch schon gemacht und dabei viele seltsame Effekte 
beobachtet.

Ich hoffe das hilft dier ein wenig weiter.

Autor: Antwortender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> dazu müsstest Du schon
> sehr genau wissen, was alles auf dem Stack steht. Kleiner Hinweis: Da
> werden nicht nur Rücksprungadressen, sondern auch Registerinhalte und
> bei C automatische Variablen gespeichert.

Dass mein ich mit "Seltsame Effekte"

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das ist ein kaputtes Design, das ist Dir klar, oder?

Mal für Blöde. Was ist ein kaputtes Design?

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, dann ist das wohl mit Vorsicht zu genießen.
Muss ich mir wohl was anderes einfallen lassen.
Mal ne andere Frage:
Der besagte Interrupt tritt nur ein oder zwei mal auf.
Einfach zu springen, ohne den Eintrag im Stack zu löschen wird dann auch 
nicht gehen, oder? Es dürfte zwar kein Overflow geben, aber wenn da 
Variabeln "drunter" gespeichert sind, die noch gebraucht werden, geht 
das ja nicht.

Autor: Klugscheisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Na, dann ist das wohl mit Vorsicht zu genießen.
Ja, wenn überhaupt.
>Muss ich mir wohl was anderes einfallen lassen.
Das wäre nachdrücklich zu empfehlen.

>Mal ne andere Frage:
>Der besagte Interrupt tritt nur ein oder zwei mal auf.
Ändert nichts an obiger Empfehlung.

>Einfach zu springen, ohne den Eintrag im Stack zu löschen wird dann auch
nicht gehen, oder?
Prinzipiell eher nicht. Dann schon eher den Eintrag löschen. Das Problem 
ist ja nicht das löschen selbst. Sondern, das der momentane Stackaufbau 
bis auf einige grundsätzliche Details völlig unbekannt ist. Siehe 
nächster Absatz.

>Es dürfte zwar kein Overflow geben, aber wenn da
>Variabeln "drunter" gespeichert sind, die noch gebraucht werden, geht
>das ja nicht.

Das ist eben das Grundproblem. Zu dem Zeitpunkt zu dem der Interrupt 
ausgelöst wird, weisst Du ja nicht ohne weiteres wie der Stack aussieht. 
Aus welcher Funktion ist der uc herausgerissen worden? Wieweit ist der 
Stack-Frame überhaupt gerade aufgebaut worden? Oder abgebaut? Sowas 
dauert ja auch seine Zeit.

Du solltest das Design grundsätzlich verabschieden, das darauf beruht, 
das aus einem Interrupt an eine völlig andere Stelle im Programm 
gesprungen wird. Vielleicht schreibst Du mal warum das überhaupt eine 
Alternative war. Dann kann man vielleicht noch weitere Wege beschreiben.

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, der Sinn des ganzen ist folgendes:
Ich habe einen Eingangspuffer, der von einem Generator geladen wird.
Ist der vollständig geladen, bekommt der MSP einen Interrupt und er 
aktiviert eine Ladungspumpe. Diese lädt dann 3 andere Puffer. Während 
des Ladens führt der MSP ein paar Befehle aus und geht dann in den sleep 
Modus. Sobald die 3 Puffer geladen sind, bekommt der MSP wieder einen 
Interrupt und dann macht er mit dem restlichen Programmablauf weiter. 
Normalerweiße reicht die Energie im Eingangspuffer um die drei anderen 
Puffer zu laden, dann ist das alles kein Problem. Falls aus 
irgendwelchen Gründen die Spannung vom Eingangspuffer jedoch zu niedrig 
wird, bekommt der MSP auch einen Interrupt und dann soll er die 
Ladungspumpe abschalten und warten bis der Eingangspuffer wieder geladen 
ist. Wenn er dann aber wieder an die alte Stelle zurück springt, kann es 
sein, dass er dort in den sleep Modus geht und wartet, bis er den 
Interrupt bekommt, der ihm sagt, das die 3 Puffer geladen sind. Wenn die 
Ladungspumpe aber aus ist, wird das nie passieren. Momentan hab ich's 
jetzt so gemacht, dass der Watchdog ihn dann aus seinem " Dornröschen 
Schlaf" reist und das Programm wieder von vorne startet. Das ist zwar 
nicht das gelbe vom Ei, aber was anderes ist mir nicht eingefallen.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Daniel Schillinger (enton)

>Ladungspumpe aber aus ist, wird das nie passieren. Momentan hab ich's
>jetzt so gemacht, dass der Watchdog ihn dann aus seinem " Dornröschen
>Schlaf" reist und das Programm wieder von vorne startet. Das ist zwar
>nicht das gelbe vom Ei, aber was anderes ist mir nicht eingefallen.

Das kann man alles easy ind SAUBER per State Machine und Sleep Mode 
lösen, keinerlei Notwendigkiet für Stackgefummel.

MFG
Falk

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wie?

Ich komm da auf keine Lösung.
Wenn ich in den alten State zurückspringe und er dann in den Sleep geht 
und auf einen Interrupt wartet, der nie kommen wird, kann es ja nicht 
gehen.
Sorry, wenn ich mich hier ein bischen blöd anstelle, aber bei sowas hab 
ich relativ wenig Erfahrung.

Autor: Daniel Schillinger (enton)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hab mal meinen Flowchart in den Anhang gepackt.
Die 3 Puffer heißen MSP Funk und Sensorpuffer. S speichert den Status, 
F0,F1 und F7 liefern einen Interrupt, wenn ein Puffer geladen ist.
F3 liefert einen Inerrupt wenn der Einganspuffer geladen ist( Pin geht 
auf 1) und einen, wenn der Eingangspuffer entladen ist( Pin geht auf 0).
Ich hoffe man kann so einigermaßen erkennen was ich mach.
Teilweiße wird es wohl etwas unklar sein, aber ich hoffe es reicht. Die 
ganze Schaltung zu erklären, wäre ein halber Roman.

Gruß Enton

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Daniel Schillinger (enton)

>Und wie?

Da musst du halt mal ein klein wenig Ruhe bewahren und drüber 
nachdenken.
Und mal die empfohlenen Artikel studieren.

>Ich komm da auf keine Lösung.

Was schonmal gar nichts heisst.

>Wenn ich in den alten State zurückspringe und er dann in den Sleep geht
>und auf einen Interrupt wartet, der nie kommen wird, kann es ja nicht
>gehen.

Sicher, aber wer sagt denn, dass es so gehen muss?
Schau dir di Artikel an, denk drüber nach, morgen reden wir weiter.

>Sorry, wenn ich mich hier ein bischen blöd anstelle, aber bei sowas hab
>ich relativ wenig Erfahrung.

Siehe oben.

Mfg
Falk

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Daniel Schillinger (enton)

>Dateianhang: Flowchart1.jpg (256 KB, 1 Downloads)

Literaturtipp des tages: Bildformate.

>Teilweiße wird es wohl etwas unklar sein, aber ich hoffe es reicht. Die
>ganze Schaltung zu erklären, wäre ein halber Roman.

Dein Flow Chart ist keine State Machine, bestenfalls ein verzweigter 
Ablauf.
Eine State Machine hat einen zentralen Punkt (die endlose 
Hauptschleife), welcher immer wieder erreicht wird, um zu entscheiden, 
in welchen Sate als nächstes gesprungen wird, abhängig vom aktuellen 
State und den Eingangsvariablen.

Das sollte als Wink mit dem Zaunspfahl genügen.

MFG
Falk

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Und mal die empfohlenen Artikel studieren.
Wo wurden mir hier Artikel empfohlen? Meinst du den Sleep Mode Artikel?
Nen anderen kann ich nicht entdecken.

Gruß Enton

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Daniel Schillinger (enton)

>Wo wurden mir hier Artikel empfohlen? Meinst du den Sleep Mode Artikel?

Ja, dort ist ein Flussdiagramm drin. Und der Artikel Interrupt 
sollte auch ein wenig erhellen.

MFG
Falk

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In den Artikeln stand leider auch nichts neues drin.

Nochmal kurz zu meinem Vorgehen:
Im Interrupt werden die Variabeln F0,1,3,7 gesetzt. Das sind meine 
Eingänge.
In der Varialbe S speicher ich den Status.
In meiner Hauptroutine habe ich ne case abfrage. Je nach Status und 
Eingang, führe ich dann den entsprechenden State aus. Das ist doch 
soweit richtig, oder?
Die Verzweigungen in meinem State Diagramm haben folgenden Sinn.
Wenn die Ladungspumpe an geht, ist nicht gesagt, dass die Puffer auch 
entladen sind. Sind sie das nicht, würde es keinen Interrupt geben. 
Deshalb frage ich nach, ob sie geladen sind. Falls ja, wird zum nächsten 
State gesprungen, wenn nicht, wird der aktuelle State ausgeführt.
Um das Problem mit dem Dornröschenschlaf zu vermeiden, könnte ich 
höchstens jedesmal bevor ich in den Sleep gehe, nachfragen, ob der 
Eingangspuffer entladen ist. Das würde aber relativ viel Rechenzeit 
kosten. Da das ganze ne low Power Anwendung ist, sollte der MSP so wenig 
wie möglich im aktive Mode sein.

Vieleicht könntest du mir ja sagen, wo genau der Fehler bei meinem 
Vorgehen ist, bzw. was ich besser/anderst machen sollte.

Gruß Enton

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Daniel Schillinger (enton)

>Eingang, führe ich dann den entsprechenden State aus. Das ist doch
>soweit richtig, oder?

Ja.

>Um das Problem mit dem Dornröschenschlaf zu vermeiden, könnte ich
>höchstens jedesmal bevor ich in den Sleep gehe, nachfragen, ob der
>Eingangspuffer entladen ist. Das würde aber relativ viel Rechenzeit
>kosten.

Wieviel denn?

> Da das ganze ne low Power Anwendung ist, sollte der MSP so wenig
>wie möglich im aktive Mode sein.

Sicher, aber ein paar ms machen da das Kraut nicht fett. Wenn man sich 
per Timer z.B. 50 Mal pro Sekunde wecken lässt und dann prüft ist das 
OK.

MFG
Falk

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:
> @Daniel Schillinger (enton)
>
>>Eingang, führe ich dann den entsprechenden State aus. Das ist doch
>>soweit richtig, oder?
>
> Ja.
>
>>Um das Problem mit dem Dornröschenschlaf zu vermeiden, könnte ich
>>höchstens jedesmal bevor ich in den Sleep gehe, nachfragen, ob der
>>Eingangspuffer entladen ist. Das würde aber relativ viel Rechenzeit
>>kosten.
>
> Wieviel denn?
>
>> Da das ganze ne low Power Anwendung ist, sollte der MSP so wenig
>>wie möglich im aktive Mode sein.
>
> Sicher, aber ein paar ms machen da das Kraut nicht fett. Wenn man sich
> per Timer z.B. 50 Mal pro Sekunde wecken lässt und dann prüft ist das
> OK.
Ok. Dann würdest du es also auch über eine Abfrage machen. Hatte 
gedacht, du würdest das ganze Programm komplett anderst strukturien.
Gut zu hören, das es doch nicht so falsch ist, was ich gemacht habe:-)

Gruß Enton

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.