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
> 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.
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.
> 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"
> Das ist ein kaputtes Design, das ist Dir klar, oder?
Mal für Blöde. Was ist ein kaputtes Design?
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.
>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.
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.
@ 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
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.
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
@ 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
@ 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
> 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
@ 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
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
@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
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
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.