Hallo Zusammen, ich habe mal eine allgemeine Frage. Ich habe mir mittlerweile viele Headerdatein geschrieben und möchte diese nun in verschiedenen Programmen verwenden. Aber diese sollen dann strukturiert aufgerufen werden. Ich denke die beste Methode ist es dafür ein OS zu schreiben, oder!? Wenn ja, wie würdet ihr so ein OS aufbauen? Im Pollingbetrieb? Oder strukturierte Abarbeitung der verschiedenen Funktionen? Ich weiß das ist wieder Anwendungsbedingt, vorallem bei Echtzeitanwendungen, aber ich wüßte zur zeit nicht einmal wie ich den Pollingbetrieb aufbauen soll!! Hat jemand vielleicht mal Beispiele wie man sowas entwickeln kann? Oder macht ihr das dann über Timer mit denen Ihr eine ISR auslöst und die Funktionen bedingt an einem Zählerstand aufruft? Ich fänd es gut wenn, mir vielleicht jemand irgendeine Hilfestellung geben kann! Beispiel ist bei mir eine Schrittmotorsteuerung für eine Isolationsfräse, bei der ich ein Echtzeitsystem haben muss, wegen der Sicherheitsfunktionen. Schließlich muss der Motor stehen, wenn der Notausgedrückt wird und nicht erst wenn die Funktion abgearbeitet ist. Danke und Gruß Benjamin
Schau dir einfach ein quell- und dokumentationsoffenes RealTimeOperatingSystem an z.B. FreeRTOS... http://www.freertos.org/
Ich hoffe für den Benutzer der Maschine, dass die Not-Aus Funktion nicht nur in Software hinterlegt ist. Je nach Gefährdungspotential ist dies auch gar nicht zulässig.
keine Angst die Notaus-Funktion wird über Interrupt und direkte Trennung der Versorgungsspannung für die Antriebe realisiert!!! ich werde keinen Gefährden... Aber ich wollte nur mal ein Beispiel nehmen was verdeutlichen kann was Realtime bedeutet!!
Realtime bedeutet doch nur, dass das OS innerhalb einer garantierten Zeit reagiert. Wie groß diese Zeit ist, um noch als RealTime durchzugehen, hängt immer von den Anforderungen des Projektes ab. Ob die Abschaltung eines Motors nun 30us oder 100us dauert ist doch ziemlich egal, wenn man die Nachlaufzeit des Motors da ins Verhältnis setzt.
@Andre: das war mir schon klar wie RealTime definiert ist, aber ich suche halt ein Beispiel wie Ihr sowas aufbauen würdet... Wenn ich die Definition Notaus habe, dann sollten die Antriebe nicht nachlaufen sondern sofort stehen. Dafür gibt es verschiedene Möglichkeiten bei Antrieben... Kurzschlißen der Wicklungen, Gleichstrombremsen oder mechanische Bremsen... usw.. Auf dem Gebiet kann man so viel machen. @All: Ich würde lieber wissen wie Ihr Euren Quellcode aufbauen würdet um dies zu realisieren. Also ich meine, würdet Ihr ähnlich einer Schrittkette die Funktionen nacheinander aufrufen und bearbeiten lassen und die Interrupts nur nutzen um z.B. die Endlagen, Notaus usw. zu erkennen. Oder würdet Ihr zb. einen Timer in genau definierten Abständen einen Interrupt auslösen lassen (zb. 100us) und mit dem Interrupt einen Zähler hochzählen lassen. Der ausserhalb der Interruptroutine mit Konstanten verglichen wird, die ein Auslösen einer gewissen Funktion zusammenhängen... Beispiel "main": if (ucCounter < 256) { //Taster, Endlagenabfrage ... //Frage die Taster alle 100us ab } if (ucCounter == 10) { //Wenn kein Taster gedrückt ... //Gebe jede 1ms einen Tackt aus } usw. oder wie würdet ihr das machen? Gruß Benjamin
Die Frage ist doch, ob du tatsächlich ein "vollwertiges" OS brauchst. Wenn ich dich richtig verstehe, hast du eine kritische Anforderung: den Notaus. Dieser soll innerhalb kürzester Zeit bearbeitet werden. Ich würde den dann also in eine Interrupt-Routine packen. Die restlichen Funktionen deiner Anwendung sollen in einer bestimmten Reihenfolge durchlaufen werden. Selbst die Endschalter musst du nicht unbedingt mit einem Interrupt abarbeiten, wenn du die Funktion, die den Endschalter überwacht, nur häufig genug aufrufst. Vielleicht würde das sogar für den Notaus funktionieren. Es kommt ganz darauf an, welche Laufzeit deine einzelnen Funktionen haben, welche Vorschubgeschwindigkeit du hast und ob dir die resultierende Abfragehäufigkeit ausreicht. Beispiel:
1 | while (1) |
2 | {
|
3 | endschalter(); |
4 | funktion1(); |
5 | endschalter(); |
6 | funktion2(); |
7 | endschalter(); |
8 | funktion3(); |
9 | }
|
Wenn du mit einem Timer arbeiten möchtest, dann musst du spätestens in der Auswertefunktion deine (ganzen) Register sichern und wieder herstellen. Denn du weißt nicht, in welcher Funktion du gerade den Prozessor unterbrichst und welche Register belegt sind. Ich weiß von einem sicherheitsrelevanten Steuergerät (Bremsassistent), da ist das "OS" ähnlich implementiert, da werden keinerlei Interrupts verwendet, alles über Polling, sogar der Datentransfer auf dem Systembus.
"oder wie würdet ihr das machen?" Ich würde es so machen, wie es in bewährten OSen gemacht wird. Also bestimmt nicht Variante #1.
@Stefan Danke für den Kommentar: "Ich würde es so machen, wie es in bewährten OSen gemacht wird." Ich würde nicht danach fragen, wenn ich wüßte wie die "bekannten" OS aufgebaut sind!!! @Andre Danke für die Info!! Aber meinst du die Bearbeitung ist wirklich schnell genug?? Dann werde ich das wohl so aufbauen. Aber ich denke um den Regelprozess für die Motoren nicht zu stören, sollte ich das Display an der Controllereinheit vielleicht über einen seperaten Controller ansteuern... Sonst bremst das LCD alles aus, oder was denkst Du? Danke noch mal!!! Gruß
Mit dem Display wird die Sache schon etwas komplizierter, was das Timing angeht. Die Frage dabei ist, wie oft und wann die Anzeige aufgefrischt wird, wieviele Daten dann an das Display gesendet werden, wie schnell die Schnittstelle zum Display ist, welche Wartezeiten durch das Display entstehen. - Wird das Display nur beim Einschalten initialisiert und dann nur gelegentlich 2..3 Zahlen aufgefrischt? Dann könnte es mit dem obigen Ansatz klappen pro Schleifendurchlauf einmal das Display aufzufrischen. - Gibt das Display nur Statusmeldungen aus? zB "Betriebsbereit", "In Arbeit", "Fertig". Dann muss das Display nicht in der Schleife aufgefrischt werden, hat also da keinen Einfluss auf die Steuerung. Gerade wenn ein Display ins Spiel kommt, kann es tatsächlich nützlich sein auf ein RTOS zu setzen. Dann wird die Ansteuerung für das Display als Task mit niedriger Priorität implementiert. Alle anderen Tasks erhalten eine höhere Priorität. Dann wird unter Umständen das Display verzögert aufgefrischt, aber die anderen Tasks werden mit garantierten Zeiten bearbeitet. (Das stimmt aber auch nur bedingt. Es kann dann zB zu Problemen mit Prioritäts-Inversion[1] kommen.) Grundsätzlich behält aber immer der Task mit der höchsten Priorität die Kontrolle über die CPU. Du musst dabei aber immer im Kopf behalten, dass ein RTOS dir zusätzlichen Overhead verursacht(Zeit- und Speicherverbrauch), und du musst dich in das RTOS einarbeiten. [1] http://netrino.com/Publications/Glossary/PriorityInversion.html
"Ich würde nicht danach fragen, wenn ich wüßte wie die "bekannten" OS aufgebaut sind!!!" Das weiss ich. Ich würde deshalb auch dort nachsehen. Ich verstehe aus meinen Lernstrategien heraus nicht, warum du das nicht machst. Es ist doch eigentlich normal, dass man sich in ein unbekanntes Thema auch einliest. Aber wir haben hier ein Metakommunikationsproblem und ich klinke mich daher jetzt aus.
@benjamin ich bin zur zeit dabei mir mein eigenes kleines "os" (wenn es denn diesen namen verdient) zu schreiben. grundelemente in JEDEM os sind folgende : - scheduler (egal ob unterbrechend oder kooperativ) - signale - zeitgeber - fifos so habe ich mein system aufgebaut : mein scheduler ist kooperativ. d.h. das laufende programm wird nicht unterbrochen, sondern gibt die kontrolle freiwillig ab. das erfodert etwas nachdenken, vor allem bei operationen die "länger" dauern und andere programmteile nicht blockieren dürfen. der scheduler schaut nur nach ob signale gesetzt sind, und ruft die hinter den signalen stehenden prozeduren auf. die signale selbst sind jeweils nur jeweils ein bit (pro prozess bzw. prozedur). die timer (z.b. 1ms, 10ms, 1sek) erzeugen für sich genommen nur signale (die dann vom scheduler aus die prozeduren aufrufen). mit fifos verhält es sich ähnlich. man kann bei einem neuen geschriebenen byte ins fifo ein signal auslösen, oder bei einem gelesenen. die fifos benötige ich für kommunikation per uart, für tasten-buffer, für event buffer und div. andere steuer-sachen. fifos und signale eignen sich wunderbar zum "entkoppeln" von interrupts und ausführung der interrupt-funktionen (sofern die bedeutung des interrupts nicht zeitkritisch ist, also eine ausführung im bereich von <1ms bis 10ms kein thema ist). weiterhin habe ich noch elemente wie statemachines (wunderbar geeinget um bediener-oberflächen und applikationen zu schreiben), devices (das sind dann die einzelnen hardware-stückchen, welche alle über eine zentrale funktion aufberufen werden. hat den vorteil das die schnittstelle einheitlich ist, und leicht neue devices; sprich hardware; hinzugefügt werden kann) und einen parser/dispatcher. das ganze system (ohne statemachines und devices) braucht auf einem msp430 knapp 1 kB. hoffe ich konnte dir anregungen geben
@stefan: ich finde es nett das du mich auf ein fertiges RTOS hinweist..., aber ich wollte mich nicht erst in die strukturen eines ARM und dem hinterlegten RTOS einarbeiten... Wenn dies jetzt für einen AVR vorhanden gewesen wäre, hätte ich damit keine probleme gehabt... aber ich bin ein newbie im gegensatz zu manch anderem hier!! ich bin froh das ich meinen displaytreiber und verschiedene andere sachen zusammen bekomme. darum verweigere ich mich in eine RTOS für ein anderes system einzuarbeiten!! ich möchte erst einmal eines verstehen!!!! @TheMason: vielen dank für die detailierten informationen. das hat mir schon ein wenig weitergeholfen... ich glaube ich sollte noch ein informatik-studium hinterherschieben... dann komme ich vielleicht besser in die struktruen hinein!! Gruß Benjamin
@benjamin so schwer ist das nicht. um strukturierte abläufe zu gewährleisten benötigst du wie gesagt eigentlich nur : - scheduler - signal-variablen (bei mir ist das pro task eine char-variable (signal gesetzt oder nicht), und einen funktionszeiger (welche funktion aufgerufen wird) - prozeduren die ein signal setzen/löschen bzw. alle signale initialisiert - den scheduler selbst (eine kleine schleife die prüft ob ein signal gesetzt ist, und die entsprechende funktion aufruft und anschließend das signal weder zurücknimmt) - zeitgeber - timer-variablen (datenstruktur die die verstrichene zeit und die "overflow" zeit hält, eine signalnummer, und einen status (läuft periodisch, läuft nur einmal, läuft gar nicht bzw. stop) - 1 prozedur um alle timer-variablen definiert zu resetten. - 1 prozedur um eine timervariable um x ms zu erhöhen und ggf signal setzen und timer-werte neu zu setzen - 1 interrupt-prozedur die alle timer bearbeitet (sprich oben genannte prozedur für alle vorhanden timer-variablen aufruft) - fifos - 2 fifo-datenstrukturen (eine steuer-struktur mit den schreib/lesezeigern, eine daten-struktur die den fifo-buffer (oder einen zeiger daruf) sowie die größe und das auszulösende signal enthält) - prozeduren die die fifo-buffer initialisieren, ein byte in den fifo schreiben (und ein signal setzen), ein byte aus dem buffer lesen es dreht sich alles letztenendes um die signale und den scheduler. alles was signale "auslöst" ist nur nettes (aber wichtiges) beiwerk. mit so einem "konglomerat" an funktionen (wobei es wirklich recht wenig funktionen sind die zu implementieren sind, ich habe insgesamt knapp 20-25 kleine funktionen, von denen nur 10-15 nach "draußen" exportiert bzw. bekanntgegeben werden). das mal als etwas detaillierteren umriss meines systems. je nach anforderung kann man mit so einem system schon einiges realisieren. vor allem ablaufsteuerungen können recht schnell realisiert werden (durch die fifos, in denen drehgeber-events, tasten-events, uart-events, timer-events eingetragen werden können, und diese fifos dann quasi als ereignis-queue arbeiten) ein kleines mini-os ist wirklich kein hexenwerk (vor allem wenn man sich für kooperatives multitasking entscheidet wird der gesamte code sehr einfach). ob es deinen anforderungen genügen wird weiß ich nicht. gruß rene
@ Benjamin Das Target hattest du nicht angegeben. Ich wollte auf diesem Mangel nicht herumhacken und hatte stattdessen auf FreeRTOS hingewiesen. Bei FreeRTOS gibt es Portierungen für relativ viele Targets und ich dachte, dass deine Plattform vielleicht dabei ist. Wenn du wie jetzt geschrieben auf AVR aus bist... war meine Überlegung korrekt, denn es gibt auch zwei FreeRTOS Ports für AVR und "tausend" andere Targets.
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.