Forum: Mikrocontroller und Digitale Elektronik Programmwechsel per ISR


von Novex X. (novex)


Lesenswert?

Hallo Leutz...


hoffe mir kann jemand helfen...

ich möchte bei einem attiny24 in der ISR das programm welches in er main 
läuft wechseln.....

ISR(INT0_vect)
{

  if(bla ==0)
  {
   bla = 1;
  fu_pointer = (myfcnptr) blaufadeinout;
  }
  else
  {
  bla = 0;
  fu_pointer = (myfcnptr) rotf;
  }
}

das funktioniert auch soweit..in der main wird einfach dauernd dieser 
funktionspointer aufgerufen!!


Jedoch erfolgt der wechsel des programms erst bei beenden des gerade 
laufenden programms.

Gibt es eine möglichkeit den wechsel sofort auszuführen??

Also den wechsel in der main , ich will die funktion nicht in der ISR 
aufrufen da es bei mehreren programmen dann wohl etwas zu zeitaufwändig 
für ne ISR wird....

gruß noveX

von Novex X. (novex)


Lesenswert?

Keiner eine Idee?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> Jedoch erfolgt der wechsel des programms erst bei beenden des gerade
> laufenden programms. Gibt es eine möglichkeit den wechsel sofort
> auszuführen??

Ja, die vom Funktionspointer adressierte Unterroutine muss ebenfalls 
möglichst oft und regelmäßig das Statusflag bla prüfen und sich 
graziös beenden, wenn der Status durch INT0 gewechselt wurde.

von Huch (Gast)


Lesenswert?

Ob und wie man das macht hängt von den fraglichen Funktionen ab. Für 
einen Anfänger (Du schreibst leider nichts über den Umfang Deiner 
Erfahrungen) ist es aus einer Reihe von Gründen nicht empfehlenswert das 
zu tun. Einer der wesentlichen Gründe dafür ist, das man sicherstellen 
muss, das die Funktionen bzw. die von Ihnen behandelten und erzeugten 
Daten immer in einem konsistenten Zustand hinterlassen werden müssen, 
falls und wenn der Interrupt den Programmfluss umgesteuert hat. Selbst 
Fortgeschrittene werden dieses Verfahren nicht oder nur "unter Zwang" 
anwenden, wenn überhaupt.

Eine viel bessere, weil übersichtlichere, Möglichkeit ist es die beiden 
Funktionen als eine Vereinigung von zwei Zustandsmaschinen zu 
implementieren und in den in Frage kommenden Zuständen einen Übergang zu 
anderen Zuständen in Abhängigkeit von einem Flag, das im Interrupt 
gesetzt wird, zu implementieren. Das ist nur eine einfache Erweiterung 
des Entwurfsschemas, das sowieso zu bevorzugen ist, in dem eine in main 
abgehandelte Zustandsmaschine abgearbeitet wird und Zustandswechels auch 
von in INTs gesetzten Flags abhängen.

Ich möchte Dir ernsthaft empfehlen das Problem in dieses Schema 
einzupassen.

Die Probleme bei dem ursprünglich von Dir angedachten Weg sind nur mit 
hohem Aufwand zu beherrschen. Gehe diesen Weg lieber nicht.

von Oliver (Gast)


Lesenswert?

Zunächst mal die Standardfrage bei solchen Ideen:

WARUM? willst du das?

Wenn du das neue Programm "jungfräulich" starten willst, ohne das es im 
vorherigen Zustand weitermachen soll, dann schreib den neuen 
Funtionspointer in der ISR ins EEPROM, und ziehs dann über einen Pin 
Reset auf GND ;)

Im Hauptprogramm liest du den Pointer aus dem EEPROM, und springst dann 
dahin.

Oliver

von Novex X. (novex)


Lesenswert?

Oliver schrieb:
> Zunächst mal die Standardfrage bei solchen Ideen:
>
> WARUM? willst du das?
>
> Wenn du das neue Programm "jungfräulich" starten willst, ohne das es im
> vorherigen Zustand weitermachen soll, dann schreib den neuen
> Funtionspointer in der ISR ins EEPROM, und ziehs dann über einen Pin
> Reset auf GND ;)
>
> Im Hauptprogramm liest du den Pointer aus dem EEPROM, und springst dann
> dahin.
>
> Oliver

Wird zwar funktionieren ....jedoch hört es sich nicht so optimal an den 
controller nur wegen einem internen programmwechsel gleich zu reseten 
:-/

von Novex X. (novex)


Lesenswert?

> Eine viel bessere, weil übersichtlichere, Möglichkeit ist es die beiden
> Funktionen als eine Vereinigung von zwei Zustandsmaschinen zu
> implementieren und in den in Frage kommenden Zuständen einen Übergang zu
> anderen Zuständen in Abhängigkeit von einem Flag, das im Interrupt
> gesetzt wird, zu implementieren. Das ist nur eine einfache Erweiterung
> des Entwurfsschemas, das sowieso zu bevorzugen ist, in dem eine in main
> abgehandelte Zustandsmaschine abgearbeitet wird und Zustandswechels auch
> von in INTs gesetzten Flags abhängen.


Ja so hab ich es mir auch erst gedacht...jedoch ist das problem dabei 
wenn funktion1 ein programm ist das 4 sekunden lang dauert und ich 
drücke nach einer sekunde den taster dauert es noch 3 sekunden bis das 
programm wechselt.....

Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was 
ja auch nicht gerade eine schöne lösung ist..

von Edding (Gast)


Lesenswert?

Wenn du dir wirklich selber in den Fuß schiessen willst:

Beim Funktionswechsel in der ISR: Per Inline-ASM den Stackpointer 
zurücksetzen, goto main;

(Gibt es eigentlich setjmp/longjmp in der avr-libc?)

von Karl H. (kbuchegg)


Lesenswert?

Kevin Rombach schrieb:

> Ja so hab ich es mir auch erst gedacht...jedoch ist das problem dabei
> wenn funktion1 ein programm ist das 4 sekunden lang dauert und ich
> drücke nach einer sekunde den taster dauert es noch 3 sekunden bis das
> programm wechselt.....
>
> Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was
> ja auch nicht gerade eine schöne lösung ist..

Das alles sind ernsthafte Indizien, dass deine jetzigen Einzelprogramme 
schon Mist sind. Wahrscheinlich wimmelt es nur so von _delay Aufrufen 
und das ist jetzt die Quittung dafür.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was
> ja auch nicht gerade eine schöne lösung ist..

Wenn du funktion1 unschön abwürgen willst, ohne ihr eine Chance zu 
geben, sich sauber zu beenden, dann benutz die Lösung von Oliver.

Die ist wenigstens sicher, weil funktion2 einen sauberen Stack und 
initialisierte Daten vorfindet.

Den Reset an sich kannst du auch über den Watchdog auslösen.

von Edding (Gast)


Lesenswert?

Edding schrieb:
> (Gibt es eigentlich setjmp/longjmp in der avr-libc?)

Ja gibt es ;)

Also ohne inline-asm:
1
jmp_buf return_to_main;
2
3
ISR(xxx) {
4
  ....
5
  ... fptr umbiegen;
6
  longjmp(return_to_main,1);
7
}
8
9
10
void main() {
11
  ... init ..
12
  setjmp(return_to_main);
13
  sei()
14
  while (true) { fptr aufrufen... }
15
}

von Huch (Gast)


Lesenswert?

>Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was
>ja auch nicht gerade eine schöne lösung ist..

Ob das nun "schön" ist oder nicht, darüber lässt sich nicht streiten, da 
"schön" nicht objektivierbar ist.

Die Aussage, das eine Funktion 4 Sekunden lang einen nicht 
unterbrechbaren Vorgang durchführt halte ich zumindest für 
hinterfragbar. Was ist das genau für ein Vorgang? Wie sieht er aus? Wie 
ist er programmiert? Eine Schleife? Ein Delay?

Und die Frage "wozu" das Ganze ist hier auf jeden Fall interessant.

Ehrlich gesagt möchte ich mich da ohne weitere Angaben und genaue 
Beschreibung nicht weiter auf Diskussionen einlassen. Erfahrungsgemäß 
beruhen solche Fragestellungen auf ungenügendem Verständnis von 
Algorithmen und Programmierschemata. Wenn Du darauf nicht eingehst halte 
ich jede weitere Diskussion für nutzlos.

von Novex X. (novex)


Lesenswert?

Karl heinz Buchegger schrieb:
> Kevin Rombach schrieb:
>
>> Ja so hab ich es mir auch erst gedacht...jedoch ist das problem dabei
>> wenn funktion1 ein programm ist das 4 sekunden lang dauert und ich
>> drücke nach einer sekunde den taster dauert es noch 3 sekunden bis das
>> programm wechselt.....
>>
>> Ich müsst an mehreren stellen in funktion1 abfragen zum flag machen was
>> ja auch nicht gerade eine schöne lösung ist..
>
> Das alles sind ernsthafte Indizien, dass deine jetzigen Einzelprogramme
> schon Mist sind. Wahrscheinlich wimmelt es nur so von _delay Aufrufen
> und das ist jetzt die Quittung dafür.


so ein schwachsinn hier... da ist nicht ein delay drin du Held!!!! Es 
geht hier um eine RGB LED steuerung....und wenn ich nunmal mehrere 
farben nacheinander ein und ausfaden lasse und farbspiele betreibe geht 
ne funktion nunmal nicht nur 200ms !!!!!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Kevin Rombach schrieb:

> so ein schwachsinn hier... da ist nicht ein delay drin du Held!!!!

Oha, schnell weg hier, nicht dass ich auch noch zum Helden mutiere.

von Edding (Gast)


Lesenswert?

Kevin Rombach schrieb:
> so ein schwachsinn hier... da ist nicht ein delay drin du Held!!!! Es
> geht hier um eine RGB LED steuerung....und wenn ich nunmal mehrere
> farben nacheinander ein und ausfaden lasse und farbspiele betreibe geht
> ne funktion nunmal nicht nur 200ms !!!!!

So ein Schwachsinn.

Die funktion braucht nur ein paar µs. Neue PWM-Werte berechnen, in die 
Register schreiben, fertig.
das ganze Faden, Farbwechsel, Animationszeug aussenrum: State Machine, 
wie dir schon mehrfach geraten wurde.


Davon abgesehen: Deine Wunschlösung hab ich dir gepostet. Werd damit 
glücklich.

von Novex X. (novex)


Lesenswert?

Es handet sich einfach um eine Kleine Platine an die Über den Attiny24 
und einer ULN2803 4 RGB LED´s und 2 WW LEDS gesteuert werden sollen...

Die FarbwechselProgramme der RGB´s sin halt über PWM und schleifen in 
denen die PWM werte erhöht und gesenkt werden .... und das dauert nunmal 
wenn ich schöne übergänge von zwischen den 4 RGB´s erzeugen will!!

SO darum geht es....

Und wenn ich nun den taster drücke und das Farbprogramm wechseln will 
und das programm dann erst nach ein paar sekunden gewechselt wird wirkt 
das ganze so träge und ist nicht so toll..

von Edding (Gast)


Lesenswert?

Kevin Rombach schrieb:
> Und wenn ich nun den taster drücke und das Farbprogramm wechseln will
> und das programm dann erst nach ein paar sekunden gewechselt wird wirkt
> das ganze so träge und ist nicht so toll..

Deswegen: State Machine.

Davon abgesehen: Deine Wunschlösung hab ich dir gepostet. Werd damit
glücklich.

von Karl H. (kbuchegg)


Lesenswert?

Kevin Rombach schrieb:

> SO darum geht es....

Und er ganze Ansatz ist Unsinn, du Antiheld.

Mach dich mal über State-Maschinen schlau und wie man sowas macht.
AUch wenn du keinen _delay drinnen hast, so hast du doch Warteschleifen 
und genau da hakt es jetzt eben.

Wie ich schon sagte: Dein ganzer Programmansatz ist Mist.
Das muss bereingt werden und auf einmal wird dann dein "Problem" ganz 
einfach.

von Novex X. (novex)


Lesenswert?

Wie soll ich sonst eine schrittweise erhöhung der PWM werte machen wenn 
nicht in einer schleife  ? Rekursiv ? irgendwo muss ja ne wiederholte 
anweißung sein um das zu realisieren ?

von Novex X. (novex)


Lesenswert?

Karl heinz Buchegger schrieb:

> AUch wenn du keinen _delay drinnen hast, so hast du doch Warteschleifen
> und genau da hakt es jetzt eben.
>

Naja in den Schleifen wird ja immerhin bei jedem durchlauf der PWM wert 
erhöht...somit wird ja nicht nur gewartet ?

von Edding (Gast)


Angehängte Dateien:

Lesenswert?

Novex Xevon schrieb:
> irgendwo muss ja ne wiederholte
> anweißung sein um das zu realisieren ?

In der State Machine, zum Xten mal.

Hab dir ein Beispiel, ich glaube hier aus der Codesammlung, angehängt.
Farbwechsler (HSV-Farbmodell) mit Soft-PWM für RGBW-LED auf Tiny13.

Die Schleife in der main läuft ständig durch, nur wenn der (250Hz-)Timer 
Bescheid gibt, werden die Farbwerte geändert.
Auf Tastendrücke könnte innerhalb von µs reagiert werden.

von Huch (Gast)


Lesenswert?

@ Novex Xevon

Bitte beachte, das K. H. Bucheregger Deinen Programmieransatz als "Mist" 
bezeichnet hat und nicht Dich persönlich angegriffen hat.

Deine Reaktion "Schwachsinn" bringt uns hier nicht weiter und ist gerade 
in Bezug auf K.H. Buchegger absolut unangebracht. Denn gerade er ist 
einer derjenigen, die auch auf den unangemessensten Lösungsansatz noch 
hilfsbereit und geduldig reagiert (Ich hoffe es geht ihm nicht schon auf 
den Nerv, das ich ihn wieder mal verteidige, aber er ist darin mein 
Vorbild :-)

Vielmehr solltest Du die in vieler Hinsicht übereinstimmende Reaktion 
von erfahrenen Leuten hier zum Anlass nehmen unseren Gedankengängen 
zumindest probeweise mal zu folgen und als Anfänger und Unerfahrerener, 
als der Du Dich hier darstellst, versuchen ob Du dies nicht mit Gewinn 
tuen kannst anstelle Dich auf eine einmal vorgefasste Meinung zu 
versteifen.

von Huch (Gast)


Lesenswert?

Nimm mal an, Du hast eine einfache Schleife vorliegen.
1
for (i = 0; i <10; i++)
2
   Funktion_1 (i);
3
Funktion_2 ();

Wie kannst Du die als Statemachine darstellen?

1
int i = 0;
2
int state = 0;
3
4
switch (state) {
5
   case 0:
6
     Funktion_1 (i);
7
     i++;
8
     if (i >= 10)
9
        state = 1;
10
     break;
11
   case 1:
12
     Funktion_2 ();
13
     break;
14
   default:
15
     break;

Du siehst, das eine scheinbar nicht unterbrechbare Schleife doch als 
unterbrechbare Statemachine programmierbar ist.

(Syntaxfehler mal vorbehalten).

von Edding (Gast)


Lesenswert?

@Huch:

Scheibar hat novex auch eine Leseschwäche, sonst würde er nicht nur 
immer auf den letzten Post reagieren, sondern auch die dazwischen lesen.

Dann hätte er sich z.B. schon mit setjmp/longjmp aus dem Staub machen 
können. Exakt die Lösung, die er sich gewünscht hat... aber trotz 
mehrfachen erneuten Hinweisen, keine Reaktion dazu.

Klar, ist keine schöne Lösung, aber hey, er wollte es so.

von Novex X. (novex)


Lesenswert?

>
> switch (state) {
>    case 0:
>      Funktion_1 (i);
>      i++;
>      if (i >= 10)
>         state = 1;
>      break;
>    case 1:
>      Funktion_2 ();
>      break;
>    default:
>      break;
> [/c]
>
> Du siehst, das eine scheinbar nicht unterbrechbare Schleife doch als
> unterbrechbare Statemachine programmierbar ist.
>
> (Syntaxfehler mal vorbehalten).

Okay.... so in der art hatte ich es auch mal...bzw. ich hatte halt eine 
globale variable welche halt den status des hauptpgrogrammes bestimmt 
hat!! jedoch war halt da das problem das der zustand des proramms nicht 
direkt beim tastendruck verändert wurde :-/

und nein ich habe KEINE Leseschwäche!!

von Huch (Gast)


Lesenswert?

>jedoch war halt da das problem das der zustand des proramms nicht
>direkt beim tastendruck verändert wurde :-/

Aha. Ist das eine Frage oder ein Einwand? Oder ist es Dir jetzt klar, 
wie Du die Reaktionszeit minimierst?

Denke daran, das eine Reaktionszeit von ca. 100 bis 200ms für den 
Benutzer nicht wirklich als Verzögerung bemerkt wird.
Bei diesem Ansatz musst Du natürlich die in den einzelnen Zuständen 
auszuführenden Aktionen auf eine solche Zeit begrenzen. Dann gehts.

von Patrick (Gast)


Lesenswert?

Novex Xevon schrieb:
> Okay.... so in der art hatte ich es auch mal...bzw. ich hatte halt eine
> globale variable welche halt den status des hauptpgrogrammes bestimmt
> hat!! jedoch war halt da das problem das der zustand des proramms nicht
> direkt beim tastendruck verändert wurde :-/

Tja, dann... gibt es wohl keine Loesung fuer Dein Problem.

In dem Fall wuerde ich Dir raten, dein Gebastel wegzuschmeissen und Dir 
nen fertigen RGB-Controller zu kaufen.


Patrick

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.