mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Dritte Hierarchiestufe?


Autor: Rumkugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

normalerweise hat man mit Interrupts ja zwei Hierarchiestufen:
1. Interrupts
2. Alles was im Main-Loop steht

Ich habe nun ein Programm, das genau so bereits funktioniert (Interrupts 
setzen Flags, diese werden dann in ziemlich langen Funktionen innerhalb 
des Main-Loops ausgewertet).

Jetzt möchte ich die verbliebene Kapazität aber noch für ein paar 
zusätzliche Dinge gebrauchen, die die bisherige Funktion aber nicht 
beeinflussen sollen, also praktisch eine dritte Stufe unter den 
bisherigen Funktionen aus der Main-Loop einrichten.

Hab ich mich klar genug ausgedrückt?
Gibts dazu irgendwelche Ideen?

Grüße!

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UNTER der Main-Loop kannst du vergessen (das wäre dann deine Main-Loop) 
aber oberhalb kannst du natürlich noch eine Ebene einziehen.

main-loop: Wenn sonst nichts zu tun ist
1. Interrupt-Hierarchie: Unwichtigeres
2. Interrupt-hierarchie: Schnell zu bearbeitende Ereignisse

Deine bisherige Main-Loop läuft einfach rum, nehmm ich an,
du musst also entscheiden, WANN sie rumlaufen soll,
und sie vermutlich auf einen Timer setzen.

Eventuell synchronisuert sie sich schon aktiv an eine Zeit
oder ein sonstiges Ereignis. Dann musst du dieses Ereignis
eben zu einem Interrupt machen (oder einen schneleren
Interrupt nachgucken lassen, ob das Ereignis eingetreten ist,
und dann zur Ausführung flaggen).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hab ich mich klar genug ausgedrückt?

Ich vermute mal, du meinst so etwas wie 'Idle-Processing'.
Also Dinge, die ablaufen, wenn es sonst nichts zu tun gibt.

erster Ansatz:
int main()
{
  ...

  while( 1 ) {

    isIdle = true;   // Annahme: es gibt nichts wichtiges zu tun

    if (Jobflag)
    {
       mach irgendetwas ganz wichtiges

       isIdle = false;   // die Annahme war falsch
    }

    if (UpdateLCD)   // noch ein Jobflag
    {
       update das LCD

       isIdle = false;   // auch hier: die Annahme war falsch
    }

    ....


    if (isIdle)         // wenn es in diesem Durchgang nichts wichtiges
                        // zu tun gab, dann mach jetzt die unwichtigen
                        // Sachen unter der Annahme, dass ein wenig
                        // Zeit bleibt
    {
                        // Allerdings wichtig: Immer nur kurze Dinge
                        // erledigen, damit die Abfrage der Jobflags
                        // möglichst schnell wieder startet
       ....
     }
  }

Ganz auf 0 bringst du die Beeinflussung nicht. Aber das hast du ja auch 
so, dass die Abarbeitung eines Jobflags die Abarbeitung eines anderen 
Jobflags ein wenig verzögert.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Multitasking

Autor: Rumkugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ich vermute mal, du meinst so etwas wie 'Idle-Processing'.
> Also Dinge, die ablaufen, wenn es sonst nichts zu tun gibt.

Eigentlich meine ich genau das. Bei dem angegebenen Code würde ich aber 
Probleme bekommen, wenn die Aufgaben niedriger Prioriät sehr viel Zeit 
in Anspruch nehmen. Dann kann meine Hauptaufgabe im nächsten Durchlauf 
nicht rechtzeitig ausgeführt werden.

Eine Lösung könnte es sein, die bisherigen Aufgaben aus dem Main-Loop in 
einen Interrupt zu verschieben. Hier bekomme ich dann aber Probleme, 
weil diese Aufgaben ziemlich lang sind (ca 0.5ms) und die übrigen 
Interrupts nicht ausgelöst werden können.

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> und die übrigen Interrupts nicht ausgelöst werden können.

Natürlich können andere Interrupts ausgelöst werden, selbst beim uralten 
PIC geht das in 2 Stufen, in dem du sie eben zu Beginn deiner 
Interrupt-Funktion wieder freigibst.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich vermute mal, Du meinst standard AVRs ohne Prioritäten.

Die Main ist immer das langsamste.

Mittelschnelle Tasks kannst Du aber in nem Timerinterrupt aufrufen.
Der muß dann erst sich selbst disablen, Interrupts global enablen und 
nach den Tasks dann wieder umgekehrt.
Damit können ihn andere Interrupts unterbrechen, er sich selber aber 
nicht.


Peter

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rumkugel schrieb:
> Karl heinz Buchegger schrieb:
>> Ich vermute mal, du meinst so etwas wie 'Idle-Processing'.
>> Also Dinge, die ablaufen, wenn es sonst nichts zu tun gibt.
>
> Eigentlich meine ich genau das. Bei dem angegebenen Code würde ich aber
> Probleme bekommen, wenn die Aufgaben niedriger Prioriät sehr viel Zeit
> in Anspruch nehmen.

Genau deshalb habe ich auch geschrieben: Die dürfen nur sehr kurz sein
Eventuell könnte man sich auch dadurch retten, dass die Nebenaufgabe an 
strategischen Stellen abgebrochen wird, wenn eines der Jobflags auf true 
geht. Die Nebenaufgabe überprüft quasi laufend, ob es nicht etwas 
wichtigeres zu tun gibt und bricht ab, wenn dem so ist. Vielleicht kann 
man auch die Nebenaufgabe in eine Art Statemachine verpacken, die ihre 
Aufgabe in mehreren States abarbeitet und so automatisch immer wieder 
zur Hauptschleife zurückkommt.

Autor: Rumkugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Ich vermute mal, Du meinst standard AVRs ohne Prioritäten.

Ich habe die Frage mal ganz bewusst allgemein gestellt, in der vagen 
Hoffnung für mein Problem auf eine ganz neue Idee zu kommen.

Konkret läuft das auf einem ARM9 (STR91) und ich habe bereits versucht 
die mittlere Stufe als unterbrechbaren Interrupt zu schreiben, 
allerdings steige ich bei der Implementierung nicht ganz durch und es 
funktioniert natürlich nicht vernünftig.

Es ist natürlich auch kein absolut triviales Ziel mehr, aber es wäre 
halt gut wenn ich es trotzdem hinbekommen würde.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rumkugel schrieb:
> Konkret läuft das auf einem ARM9 (STR91) und ich habe bereits versucht
> die mittlere Stufe als unterbrechbaren Interrupt zu schreiben,
> allerdings steige ich bei der Implementierung nicht ganz durch und es
> funktioniert natürlich nicht vernünftig.


Wenn Du eine CPU mit Prioritäten hast, ist das ganz einfach. Du hast 
soviel Stufen, wie Du Prioritäten hast.

Du nimmst also nen Timerinterrupt und weist ihm die niedrigste Priorität 
zu, dann können ihn alle anderen Interrupts unterbrechen. Er selber kann 
aber nur das Main unterbrechen.
Und in diesem Interrupt machst Du alle Tasks der mittleren 
Hirarchiestufe.

Wie man beim ARM Prioritäten festlegt, weiß ich nicht. Beim 8051 setzt 
man einfach nur 1 oder 2 Bits in den Prioritätenregistern, fertig ist 
die Laube. Die Interrupthardware kümmert sich dann um alles andere.


Peter

Autor: Rumkugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Wenn Du eine CPU mit Prioritäten hast, ist das ganz einfach. Du hast
> soviel Stufen, wie Du Prioritäten hast.

Prioriäten habe ich zugewiesen. Das Problem ist nur, dass diese 
Prioritäten nur gebraucht werden, wenn mehrere Interrupts anstehen. Die 
Interrupts unterbrechen sich standardmäßig nicht gegenseitig. Damit sie 
das tun muss man offenbar etwas tricksen und das bekomme ich nicht ganz 
hin.

Peter Dannegger schrieb:
> Du nimmst also nen Timerinterrupt und weist ihm die niedrigste Priorität
> zu, dann können ihn alle anderen Interrupts unterbrechen. Er selber kann
> aber nur das Main unterbrechen.
> Und in diesem Interrupt machst Du alle Tasks der mittleren
> Hirarchiestufe.

So ähnlich hatte ich es eigentlich geplant. Doch leider funktioniert das 
nicht ganz so einfach, soweit ich das verstanden habe

Gruß

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  ch habe bereits versucht die mittlere
> Stufe als unterbrechbaren Interrupt zu schreiben

1 3 2 ?

> Es ist natürlich auch kein absolut triviales Ziel mehr

Stimmt schon, richtiges Anordnen von Zahlen macht man erst nach dem 
Kindergarten.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Rumkugel (Gast)

>So ähnlich hatte ich es eigentlich geplant. Doch leider funktioniert das
>nicht ganz so einfach, soweit ich das verstanden habe

Warum liest du nicht den Artikel Multitasking ?

MfG
Falk

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rumkugel schrieb:
> Doch leider funktioniert das
> nicht ganz so einfach, soweit ich das verstanden habe

Das ist auch ein Hinderungsgrund, warum ich keine große Lust habe, auf 
ARMse umzusteigen.
Sie mögen zwar irgendwelche dirty Tricks erlauben, aber für 99,9% der 
Anwendungsfälle ist das ganze monstermäßige Interruptgedöns viel zu 
kompliziert.

Interrupthandler müssen wohl auch selber immer bestimmte Bits in einer 
ganz bestimmten Reihenfolge anfassen, damits nicht kracht.

8-Bitter löschen dagegen Interruptflags automatisch beim Einsprung und 
höher priorisierte Interrupts bleiben automatisch enabled.
Der Interrupthandler muß rein garnichts mit den Interrupt-Registern 
rummachen, alles läuft ganz von alleine rund.


Peter

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.