Hallo, ich überlege für ein Projekt eine Art Betriebssystem zu verwenden oder selber zu schreiben. Meine Idee war folgende: - Folgende Komponenten sollten angesteuert werden: - LC-Display - I²C-Peripherie (mehrere ICs) - UART-Kommunikation (38.400 Baud) - Auswertung des/der ADC - Steuern von Peripherie - Berechnung von Werten aus den Daten der I²C-Peripherie - Der UART muss wegen des kleinen Puffers eine hohe Priorität haben - Da viele ICs am I²C-Bus hängen, dürfte dort viel gewartet werden auf ankommende Daten - Es soll pro Aufgabe einen Thread geben, der einfach angehalten wird, wenn auf die Fertigstellung einer Sache (z.B. das Absenden eines Bytes über den I²C-Bus und das Ack des Slaves) gewartet wird, sodass z.B. das nächste Zeichen für das LC-Display auf den Bus gelegt werden kann - Es werden Statusbytes verwendet, sodass ein Thread weiß, ob er weiterarbeiten darf oder z.B. auf die Aktualisierung eines Wertes warten muss. - Praktisch gesehen könnte in der Mainloop eine Liste an Threads nacheinander oder Priorisiert gestartet werden und es wird immer bis zum nächsten "Breakpoint" gerechnet und dann zurück zur Mainloop gesprungen. Dann wird der nächste Thread wieder angestoßen. - Es würde dann (für jeden einzelnden Thread) entweder - Eine Integervariable die aktuelle Position speichern und über swtich/case ein entsprechender Block gestartet (dürfte bei vielen Blöcken viele Rechnungen ergeben) - Die aktuelle Position wird in einer Variable gespeichert und dorthin wird beim erneuten Aufruf gesprungen - Ein Array beinhaltet Pointer auf Funktionen, die die Teilaufgaben eines Threads sind. Somit erreicht man sofort die "Unterfunktion" eines Threads Alternativ könnte man natürlich zu den sog. Real-Time-Betriebssystemen greifen. Gelesen habe ich z.B. von FreeRTOS. Jedoch habe ich davon keine Erfahrung und würde ggf. lieber auf eine performantere Eigenentwicklung setzen. Was für Vorschläge habt Ihr? Ich würde mich sehr über Anregungen und Kritik freuen ;-) Mit freundlichen Grüßen Mats Marcus
Mats Marcus schrieb: > - Da viele ICs am I²C-Bus hängen, dürfte dort viel gewartet werden auf > ankommende Daten "dürfte" sollte ein Programmierer nicht verwenden, sondern "wissen". Du mußt ausrechnen, wie hoch der benötigte Datendurchsatz ist. Vielleicht ist ja I2C garnicht geeignet für Deine Anforderungen. Eine Lösung ist das Round-Robin Verfahren. Du legst im SRAM Schattenregister für alle I2C-Peripherie an. Und der I2C-Interupt schreibt und liest alle ICs immer der Reihe nach. Das Main benutzt dann nur die Werte in den Schattenregister. Peter
Nennt sich State Machine, was DU da vor hast und ist schon sehr fortgeschrittene Programmierkunst. Die Hardware unterstützt aber schon einige der Funktionen, z.B. TXC- / RXC-Interrupts.
zur zeit steht leider noch nicht fest, wie viele I²C-ICs an den Bs angeschossen werden und wie oft die Daten benötigt werden. Bei 400kHz dürften es ja ca. 20-25kByte/s sein, wenn die Übertragung 1 Adressbyte + 1 Datenbyte groß ist. Ich denke dass ggf. ADCs noch etwas Wartezeit benötigen (müsste da mal in die Datenblätter schauen). Es wird also schon schnell genug sein aber bei der Anzahl der Komponenten denke ich, macht es schon sinn, sich mit dem Gedanken der Threads zu beschäftigen. Mit freundlichen Grüßen
Mats Marcus schrieb: > Es wird also schon schnell genug sein aber bei der Anzahl der > Komponenten denke ich, macht es schon sinn, sich mit dem Gedanken der > Threads zu beschäftigen. Hast Du denn mehrere I2C-Busse? Peter
nein, nur den einzigen Hardware-Bus (ATMega 2560). Allerdings habe ich auch andere Hardware wie die LCD-Displays
Mats Marcus schrieb: > Alternativ könnte man natürlich zu den sog. Real-Time-Betriebssystemen > greifen. Gelesen habe ich z.B. von FreeRTOS. Jedoch habe ich davon keine > Erfahrung und würde ggf. lieber auf eine *performantere Eigenentwicklung* > setzen. Um diesen Plan beurteilen zu können, muss man wissen, was für dich "performant" bedeutet. Und wieso du glaubst, erprobte Systeme wie FreeRTOS mal so eben übertreffen zu können. Mats Marcus schrieb: > - Praktisch gesehen könnte in der Mainloop eine Liste an Threads > nacheinander oder Priorisiert gestartet werden und es wird immer bis zum > nächsten "Breakpoint" gerechnet und dann zurück zur Mainloop gesprungen. > Dann wird der nächste Thread wieder angestoßen. Was du da "Thread" nennst, ist nach verbreiteter Definition kein Thread, sondern eher ein "Job". Der gerade laufende Job hat dabei die absolute Macht. Er entscheidet, wie lange er läuft und wann (und ob überhaupt) er die Kontrolle an die Mainloop zurückgibt. Mats Marcus schrieb: > - Folgende Komponenten sollten angesteuert werden: > - LC-Display > - I²C-Peripherie (mehrere ICs) > - UART-Kommunikation (38.400 Baud) > - Auswertung des/der ADC > - Steuern von Peripherie > - Berechnung von Werten aus den Daten der I²C-Peripherie Das sind recht viele Anforderungen, die sich auch voneinander stark unterscheiden. Dein "Jobsystem" muss so allgemein sein, dass es das alles ermöglicht. Und dann auch noch performant. Keine kleine Aufgabe. > - Der UART muss wegen des kleinen Puffers eine hohe Priorität haben > - Da viele ICs am I²C-Bus hängen, dürfte dort viel gewartet werden auf > ankommende Daten > - Es soll pro Aufgabe einen Thread geben, der einfach angehalten wird, > wenn auf die Fertigstellung einer Sache (z.B. das Absenden eines Bytes > über den I²C-Bus und das Ack des Slaves) gewartet wird, sodass z.B. das > nächste Zeichen für das LC-Display auf den Bus gelegt werden kann > - Es werden Statusbytes verwendet, sodass ein Thread weiß, ob er > weiterarbeiten darf oder z.B. auf die Aktualisierung eines Wertes warten > muss. Also priorisierte Aufgaben und Aufgaben, die zwischendurch unterbrochen werden können und bei Eintreten einer Bedingung fortgesetzt werden sollen. Das ist das typische Anforderungsprofil für ein RTOS. Ich würde dringend empfehlen, dass du dich erst mal mit einem RTOS beschäftigst. FreeRTOS ist ein guter Kandidat. Und erst, wenn es sich als untauglich erweist, solltest du über eine Eigenerfindung nachdenken. Gruß, willibald
Es gibt viele Scheduler und kleine OS für AVRs. Ich arbeite mit pico]OS, v.a. weil mir die Lizenz am besten passt, der Kernel gut konfigurierbar ist, die Sourcen lesbar sind (C). Eine Herausforderung ist noch, den Stack für die Threads zu verwalten. Mit der Standardeinstellung (128 Bytes Stack pro Thread) ist man zwar auf der sicheren Seite, verbrennt aber viel kostbares SRAM. Wenn du einen atmega mit 1K SRAM oder mehr einsetzt, reicht das aber ne Weile. Wenn du einen Thread pro Funktionsblock verwendest, reicht das locker noch für ein paar Message Boxen, Mutexen, Ringpuffer etc. Für die Peripherie kannst du ja mal mit der avrlib schauen und abkupfern, ausser du willst alles von Grund auf selbst implementieren. :)
Ich denke dass der Einsatz eines vorhandenen OS (habe auch FemtoOS im Auge) viele Vorteile mit sich bringen wird. Ich werde mich da auch als nächstes erst mal einlesen und dann überlegen, ob ich den Aufwand eingehen möchte, selber was zu schreiben :-) Vielen Dank für Eure Hinweise Mit freundlichen Grüßen Mats Marcus
Hallo Marcus, bin bin auch so einer, der lieber selbst was optimales schreibt/baut. Aber dann doch bei FreeRTOS hängen geblieben, um (irgendwann) meine Heizung mit damit zu steuern. Das ist zwar nicht 100% optimal auf die AVR's zugeschnitten, weil es eben auch andere unterstützt, man könnte das ein oder andere Byte RAM sparen, usw. Aber am Ende habe ich statt Mega32 einen 644 (ein 1284 liegt auch schon da) genommen und geniese, dass es jemanden gibt, der das Ding pflegt. Auch bei der Hardware hab ich mich zu fertigem durchgerungen: MicroSPS. Die kann man ja auch in gnuC(++) befehligen. Die shared die Anschlüsse von LCD und Tasten. ADC oversampled, wegen Temperaturmessung mit LM335 auf 12bit und ca. 10 samples/s auf 4 Kanälen, nach Korrektur eines Designfehlers in der MicroSPS. UART über OS-Queue geht. Treiber für I2C ist designed, aber wartet noch auf Implementierung. Soweit wäre ich alleine nie gekommen. (Auch wenn ich schon seit 35 Jahren Lötkolben halten kann und seit 25 Jahren alles von Mainframe bis runter zu AVR programmiere.) Gruß, Jürgen
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.