- 12V Akku mit 280 Ah bauen         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: Mit goto aus ISR

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    19.06.2013
    Beiträge
    8

    Frage Mit goto aus ISR

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Grüezi

    In meiner Timer0-Overflow ISR (OVF0) wird der Zustand eines Pins abgefragt. Je nach Zustand dieses Pins sollte der Programmcode an einem anderen Ort weitergeführt werden. Da dieser Timer-Overflow an jeder beliebigen Stelle im Programm auftreten kann, kann ich ja nicht einfach eine Variable setzen, mit Return aus der ISR raus und anschliessend an den richtigen Ort springen.
    Die erste Idee ist natürlich, den ISR per Goto zu verlassen. Aber irgendwie habe ich ein schlechtes Gefühl dabei. Einerseits werden bei Eintritt des ISR ja die Register 0-11, 16-31 auf den Stack gepusht und ohne ein sauberes Verlassen nicht mehr entfernt. Durch Nosave sollte ich dieses Problem umgehen können, aber wie finde ich die überschriebenen Register heraus, welche ich dann manuell absichern muss? Und was gibt es sonst noch zu beachten, wenn ich einen ISR mit Nosave aufrufe?

    Oder wäre es in dem Fall einfacher, in der ISR irgendwie den PC zu manipulieren, dass nach dem RETI dann an unterschiedliche Orte gesprungen wird?

    Besten Dank für eure Inputs bereits im Voraus

  2. #2
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    73
    Beiträge
    11.077
    Hallo!

    Ich bin ein ASMan mit k.A. über BASCOM, der aber BASIC kennt. Beim Interrupt wird die Adresse (PC) auf dem Stapel abgelegt und nach deren beendigung (RETI) wird genau an die Stelle, wo Programm unterbrochen wurde, zurück gesprungen. In der Praxis um irgendwas aus ISR dem ganzen Programmn "mitzuteilen" setzt man in ISR ein s.g. Flag (Hilfsvariable) die in ganzem Programm jederzeit geprüft und daran reagiert werden kann.
    MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    09.09.2006
    Alter
    35
    Beiträge
    841
    Blog-Einträge
    1
    Genau das schreibt er ja oben. Wenn er aber ein Programm mit den Befehlen

    A
    B
    C
    D

    hat, nach A springt er in die ISR. Er will aber, dass dann z. B. C ausgeführt wird. Beim normalen Rücksprung müsste erjetzt vor jedem Befehl den Zustand des Flags (Beziehungsweise den Rückgabewert) prüfen, ob Befehl A, B, C oder D ausgeführt werden soll.

    Wieviele Möglichkeiten gibt es denn? Wenn es sich im Rahmen hält, würde ich alle Befehle per IF einklammern und das Flag vorher prüfen.

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Der Sprung per Goto aus der ISR heraus ist an sich keine so gute Idee. Man weiss nicht wie die Hardware gerade eingestellt ist, und auch wie viele Daten ggf. auf dem Stack sind, weiss man auch nicht. Wenn man Pech hat wird auch gerade ein Integer Zahl oder ähnliches mit mehr als 1 Byte Länge verändert - das gibt dann ggf. Datenmüll weil alte und neue Daten gemischt werden. Die richtigere Lösung wäre die Struktur des Programms so zu ändern das der Sprung nicht mehr nötig ist. Ggf. einfach in der ISR ein Flag setzen und dann im Hauptprogramm das Flag an den Stellen kontrollieren wo es passt.

    Wenn es unbedingt sein muss, dass man aus der ISR verzweigt, müsste man schon fast so etwas wie einen Rest machen, also die Hardware ggf. neu initialilisieren, den Stackpointer neu auf den passenden Wert setzen. Auch im Hauptprogramm müsste man an vielen Stellen Interrupts sperren, z.B. immer wenn man eine Variable mit mehr 1 Byte verändert oder in 16 Bit HW Register (z.B. 16 Bit PWM Werte) schreibt.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Das lässt sich bestimmt auch elegant lösen. Jedoch fehlen für einen guten Lösungsvorschlag mehr Details. Warum soll sofort eine andere Sub aufgerufen werden, was sind das überhaupt für zwei Subs? Compilierfähiger Code?

    Trotz Allem: Sowas habe ich noch nie gebraucht.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  6. #6
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    34
    Beiträge
    3.501
    Blog-Einträge
    9
    Hey,

    wie schon mehrfach gesagt, ist ein Goto zum Abbruch einer ISR sehr schlecht und kann zu Fehlern führen.
    Eventuell kannst du ja eine If-Abfrage mit einem Return einbauen, sprich wenn ein bestimmtes Ereignis während eines Interrupts ausgelöst wird springt der Controller aus der ISR raus.
    Damit wird sie "sauber" abgebrochen.
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.08.2008
    Ort
    DE
    Beiträge
    523
    Wie schon gesagt, einfach über ein Flag etc. machen, aber NIEMALS vorzeitig aus einer ISR rausspringen. Diese muss immer mit reti beendet werden!

    mfg

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    19.06.2013
    Beiträge
    8
    Vielen Dank für alle eure Antworten. Ich versuche es mal mit einer Flag in der ISR und werde an verschiedenen Orten in der Routine, in welcher der Timer-Overflow vorkommen kann, dieses Flag abfragen. Noch nicht ganz optimal elegant denke ich, aber sollte klappen. Ansonsten melde ich mich gerne nochmal konkreter

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    19.06.2013
    Beiträge
    8
    Irgendwas funktioniert noch nicht ganz so, wie es sollte. Das Problem hat vereinfacht folgende Struktur.
    Die Hauptschleife ruft eine Sub auf, welche unter Umständen lange dauern kann. Falls alles läuft wie geplant, beendet die innerhalb einer gewissen Zeit und alles geht weiter wie gewohnt.
    Sollte es aber länger dauern als erlaubt, dann wird der Timer0 Overflow aufgerufen. Dieser unterscheidet den Zustand des Pins und springt dann an unterschiedliche Sprungadressen.

    Mit Flags wäre die einzige mir in den Sinn kommende Möglichkeit, dass ich in der Routine1 immer wieder ein bestimmtes Flag polle und nur dieses in der ISR setze. Aber das finde ich nicht ganz so elegant. Wie löst man ein solches Problem typischerweise?

    Code:
    'Mainloop
    Do
    Label1:
      {anweisungen}
    Label2:
      {anweisungen}
      {...}
      Gosub Routine1
      {...}
    Loop
    
    Routine1:
       For I = 0 To 100
          Start Timer0
          {ganz Viele Anweisungen}
       Next I
       Stop Timer0
    Return
    
    Isr_ovf0:
       If Pinb.1 = 0 Then
          Goto Label1
       Else
          Goto Label2
       End If
    Return

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von HeXPloreR
    Registriert seit
    08.07.2008
    Ort
    Bad Bramstedt
    Alter
    45
    Beiträge
    1.369
    Hallo,

    mal abgesehen davon dass das hier nur der halbe Code ist...startest Du den Timer0 in der For-Next Schleife 100mal neu... um ihn dann einfach nach dem Next anzuhalten?? Hast Du irgendeine Zeit berechnet- die vergehen darf/soll?

    Also, ich denke normalerweise würde man für Dein Problem einen Interrupt abstellen...und das ist völlig unabhängig von irgendeinem Timer. Und das ganze dann in der Hauptschleife. Sobal Interrupt auslöst geht es in die ISR und mit Return wieder raus...woher der return (z.B. if Bedingung) kommt ist völlig egal. In der ISR setzt man die entsprechende Variable A B C oder D = 1 (=Flag; um mal im obigen Beispiel zu bleiben) - und im Hauptprogramm kann man dann auf diese Variablen testen und in neuen Programmteile verzweigen.

    Vielleicht, wenn es kein ultra geheimes Projekt ist, kannst Du ja nochmal besser beschreiben was Du eigentlich genau machen möchtest?

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Sprung aus ISR?
    Von Robtec im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 24
    Letzter Beitrag: 18.12.2009, 12:25
  2. Timer mit ISR programmieren ATTiny2313
    Von Speedfreak-mml im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 12.07.2009, 11:43
  3. Goto vermeidbar? Graphische Menüführung mit Touch
    Von Bauteiltöter im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 8
    Letzter Beitrag: 23.04.2009, 20:25
  4. if then else Schleife möglich mit goto zu verlassen?
    Von mat-sche im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 27
    Letzter Beitrag: 14.04.2009, 10:17
  5. Falscher Rücksprung aus ISR
    Von Furtion im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 10.01.2009, 19:00

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests