Hallo, bisher sahen meine Mikrocontroller-Programmer immer so aus: 1. In Interrupts wurde alles Hardwarenahe kurz und knapp erledigt. Gab es größere Aufgaben, wurden diese über Messages oder Datenstrukturen an das Hauptprogramm übergeben. 2. Mainloop: Hier wurde alles verarbeitet, was nicht zeitkritisch war. Allerdings habe ich die einzelnen Funktionen im Mainloop auch in Ausführungsblöcke aufgeteilt, damit eine Funktion die länger dauerte, die anderern Funktionen im Mainloop nicht unnötig lange ausbremste (Stichwort: kooperatives Multitasking). Das hat auch immer alles bestens funktionniert. Da ich auf fremde Bibliotheken verzichtet habe, konnte ich darauf achten, daß die einzelnen Funktionen sich immer kooperativ verhielten (Multitasking). Nun aber, da auch Mikrocontrollerbastelleien immer komplexer werden, möchte ich auch auf fremde Bibliotheken zugreifen. Insbesondere Microchip stellt ja eine ganze Reihe von Bibliotheken zur Verfügung. Leider ergibt sich daraus nun ein Problem: Einige Funktionen verlangen nach einer regelmäßigen Ausführung (sagen wir einmal alle 1ms). Andere Funktionen blockieren allerdings den Mainloop mehrere 100ms lang. Dummerweise sind die Funktionen aber nicht asynchron ausgelegt (Funktion starten, Abarbeitung in Interrupts und Ergebnis später vom Hauptprogramm abholbar). Nun würde ich gerne so etwas konstruieren, wie: Prio 1: ISRs wie bisher für zeitkritische Aufgaben Prio 2: Highprio Mainloop (bisheriger Main-Loop, der z.B. 1x pro Milisekunde durchlaufen wird) Prio 3: Standard Mainloop, in dem auch blockierende Funktionen erlaubt sind Dann würden die ISRs zeitunkritische Aufgaben an den Highprio Mainloop abgeben. Dieser soll allerdings eine Art kooperatives Multitasking bewältigen, d.h. dieser Mainloop darf nicht länger als eine bestimmte Zeit (z.B. 1ms oder 10ms) für einen Durchlauf brauchen. Gibt es nun Funktionen, die länger brauchen und kein kooperatives Multitasking unterstützen, sollten diese vom Highprio Mainloop an den Standard Mainloop abgegeben werden können. Dort kann dann die Funktion gern auch mal 1 Sekunde rumwerkeln, bis sie das Ergebnis zurückgibt. Daraus ergibt sich für mich, daß der Inhalt des Highprio Mainloops auch in einen Timerinterrupt niedriger Priorität hineinmuß. Frage ist nun, wie macht man das am besten. Ich habe bereits eine TIMER-ISR, welche alle möglichen Timings erzeugt, von wenigen Mikrosekunden bis hin zu Minuten. Fakt ist, daß die Ausführung der gesamten TIMER-ISR nicht länger dauern darf, als die Zeit, bis der Timer wieder auslöst, und das sind unter umständen nur einige 10µs. Im Grunde könnte diese TIMER-ISR für das Timing des Highprio Mainloops sorgen. Nur muß der Timer bereits wieder auslösen dürfen, während die Funktionen des Highprio Mainloop noch abgearbeitet werden. Wie löse ich so ein Problem am besten? (Ich verwenden zur Zeit einen PIC32 mit dem C32) Ich bin aber auch gern für andere Vorschläge offen. Mir ist nur wichtig, daß solche Funktionen wie Lade_File_von_SD_Karte() den Rest der Schaltung nicht für 1s lahmlegen. Grüße, Bebo
Wird wohl oder übel auf ein präemtives RTOS rauslaufen.
Wieso, gibt es keine Möglichkeit den Interrupt wieder zu enablen? Das würde für's erst schon reichen.
Be Bo schrieb: > Wieso, gibt es keine Möglichkeit den Interrupt wieder zu enablen? Das > würde für's erst schon reichen. Du schriebst doch was von "Priorität ändern" (wenn eine Funktion zu lange braucht) und eben auch die Zeitüberwachung, bzw. dass ein 'Task' nur soundsoviele Millisekunden Laufzeit bekommt, bevor der andere wieder dran ist. Das klingt halt schon ziemlich nach einem Betriebssystem.
> Leider ergibt sich daraus nun ein Problem: Einige Funktionen verlangen > nach einer regelmäßigen Ausführung (sagen wir einmal alle 1ms). Andere > Funktionen blockieren allerdings den Mainloop mehrere 100ms lang. Dann merkst du jetzt wo der Nachteil liegt wenn man fremden Code verwenden will. :-) Natuerlich kann man einiges machen. Du kannst z.b Interrupts mit verschiedenen Prioritaeten verwenden wenn dein Prozessor das kann. Du kannst auch einen Interrupt durch einen anderen unterbrechen lassen. Du kannst auch viele verschiedene TimerIRQs verwenden. Aber das aendert nichts daran das du eine ganze Menge Dinge im Auge behalten musst. Langfristig faehrt man dann am besten wenn man sich seine Funktionen selber schreibt. Oder wenn man etwas uebernehmen will, es so anpassen das es gut an den eigenen Programmstil angepasst ist. Ich denke Faulheit an dieser Stelle muss man sonst wirklich mit einem Betriebssystem und entsprechend dicker Hardware bezahlen. Olaf
Die Standardsachen würde ich ja auch selber machen, aber warum soll man nicht die Bibliotheken des Herstellers verwenden. USB-Firmware, FAT16/32 Stack, Ethernetstack, im Grunde gibt's das bei Microchip schon fertig. Da allerdings Dinge abzuändern würde ich vermeiden wollen. Kommt die nächte Version, kann man von vorn beginnen. Verschiedene Interruptlevel gibt es und mit einem 2. Timer wäre das ganze auch nicht schwierig. Ich würde aber gern darauf verzichten einen Timer nur für diese Funktion zu opfern. Und da ich mal von Nested Interrupts gelesen habe, dachte ich, das wäre das was ich brauche. Ich weiß allerdings nicht, wie man das Programmiert.
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.