Forum: Compiler & IDEs OS Aufbau


von Benjamin (Gast)


Lesenswert?

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

von Stefan (Gast)


Lesenswert?

Schau dir einfach ein quell- und dokumentationsoffenes 
RealTimeOperatingSystem an z.B. FreeRTOS...
http://www.freertos.org/

von Thomas (Gast)


Lesenswert?

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.

von Benjamin K. (benjaminklimmek)


Lesenswert?

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!!

von Andre S. (dg2mmt)


Lesenswert?

Interessant könnte auch dies sein:
http://picoos.sourceforge.net/

von Andre S. (dg2mmt)


Lesenswert?

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.

von Benjamin K. (benjaminklimmek)


Lesenswert?

@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

von Andre S. (dg2mmt)


Lesenswert?

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.

von Stefan (Gast)


Lesenswert?

"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.

von Benjamin K. (benjaminklimmek)


Lesenswert?

@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ß

von Andre S. (dg2mmt)


Lesenswert?

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

von Stefan (Gast)


Lesenswert?

"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.

von TheMason (Gast)


Lesenswert?

@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

von Benjamin K. (benjaminklimmek)


Lesenswert?

@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

von TheMason (Gast)


Lesenswert?

@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

von Stefan (Gast)


Lesenswert?

@ 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
Noch kein Account? Hier anmelden.