Hallo, folgende Sache: Mein System arbeitet eine im EEPROM gespeicherte Sequenz ab. Ein Sequenz Schritt sieht z.b. so aus: <ID> <u16_value> 3 3218 "gebe an da ausgang 1 (id:3) den wert 3.218 V (3218) aus" nun besteht die sequenz-abarbeitung aus folgenden schritten: 0. Display Anzeige initialisieren 1. Display partiell aktualisieren (aktueller schritt) 2. Schritt aus EEPROM laden 3. schritt ausführen weiter mit 1 bis letzter schritt erreicht. Eigentlich recht simpel. Das Problem ist allerdings die Geschwindigkeit! Die Display-Aktualisierung dauert ca. 2 ms (!) weil der schritt in einen string umgerechnet werden muss! Zur Verbesserung aktualisiere ich die Anzeige nur alle 10 schritte. ein anderes problem ist das deterministische verhalten. Der ganze "prozess" laueft in einer state-machine wobei jeder schritt ein zeitfenster von 2 ms hat. jede optimierung die also nur alle 10 oder 100 schritte passieren kann ist für das deterministische verhalten wiederum schlecht. Das Problem ist also determinismus gegenüber performance... natürlich ist der golgende mittel-weg der richtige, aber der ist zu langsam ;-) ein Ansatz: eeprom schritte blockweise lesen, dann würde aber in der sequenz immer ein punkt erreicht werden, der länger braucht als die anderen...? Habt ihr da eine Idee wie man das ganze elegant optimieren könnte?? Vielen Dank für die Tipps! MFG (und schönen Feierabend ;-) )
wenn du es mit einem microcontroller machst, implementiere deine statemachine in einer timer-interrupt routine, die in regelmäßigen abständen aufgerufen wird. das display-update machst du im main-loop. dann wird das display-update durch den timer-interrupt unterbrochen, und die abarbeitung deiner "eigentlichen" aufgabe ist garantiert.
>Der ganze "prozess" laueft in einer state-machine wobei jeder schritt >ein zeitfenster von 2 ms hat. So schnell kannst du gar nicht schauen. Also ist so schnelles Updaten der Anzeige gar nicht nötig. Du hast noch den falschen Programmierstil. Ändere den mal (wie bereits vorgeschlagen): Die nebenläufigen Tätigkeiten (also das Userinterface) laufen in der Main-Loop. Zeitkritische Aufgaben, also deine Hauptarbeit (Schritt 2 und 3) musst du zügig und zeitgenau ausführen --> Interrupt. Ob die Anzeige, die in der Main-Loop aktualisiert wird, da 100ms hinterherhinkt, ist absolut uninteressant.
Ja. Du brauchst eine zweite Schrittkette für das Display. Und eine übergebende Funktion. Dein Schritt 1 ist nur ein Funktionsaufruf, zb so:
1 | func_Display ( neuer anzuzeigender Wert) |
Dieser Aufruf dauert nur kurz, denn diese Funktion schreibt die Werte nur in irgendeinen (µC internen FIFO-Puffer) Die Abarbeitung erfolgt dann mittels der zweiten Schrittkette: 0) Init | \|/ Init fertig 1) warten | \|/ ist was im FIFO drin 2) schreiben in Display | \|/ DIsplay fertig geschrieben zurück zu 1) So löse ich alles, was zulange dauert. Das nenne ich dann einen Handler.
2ms für eine Stringumwandlung finde ich arg lang. Schau dir mal die Funktion an, oder schreibe sie selber. Gerade bei sprintf(...) ist ein riesen overhead drin für alle möglichen Parameter. Da ist es oft einfacher selber eine schnelle inttostr zu schreiben und eventuelle Texte anzufügen. JL
hi! Danke für eure Antworten. diese sequenz-abarbeitung habe ich in einer art "task" alle meine "tasks" laufen in der rtc interrupt routine, die mit 1 ms getriggert ist. Leider habe ich somit auch keine Prioritäten, auch werden die Prozesse untereinander nicht unterbrochen. aber ihr habt mich auf die idee gebracht.. "langsame" tasks wie die display-aktualisierung in die main auszulagern. diese möglichkeit hatte ich noch nicht bedacht. Ich habe ein modul das nennt sich "system-manager" der schaltet "taks" je nach System-Zustand zu oder weg. Das Laden von EEPROM Blöcken habe ich mir gedacht könnte ich asynchron zu meinem Task machen. Auftrag ans EEPROM Modul übergeben, dieser läuft getriggert durch den I²C Interrupt. Somit wär das auch entkoppelt. danke schon mal für die tipps, werde mir das morgen genauer anschauen! bis denn!
So ich habe jetzt noch etwas über die ganze Sache nachgedacht.. auf der einen seite will ich ein paar Prozesse "managen" aber auf der anderen seite ein determinstisches verhalten garantieren. Meine momentane Sequenz-Abarbeitung läuft schon sehr deterministisch, jeder schritt läuft mit genau 10 ms. ich denke mal ein Echtzeit Betriebssystem in C zu implementieren ist gar nicht so ohne. Aber eine grundsätzliche Frage hätte ich dazu: Zuerst brauch ich eine Task Status Definition: tyedef enum Ich lege mir z.b. eine Struktur an typdef enum os_state_etag{ idle = 0, run = 1, wait = 2 } os_state_e; typedef struct os_task_stag{ u8 u8_priority; u8 u8_exec_counter; void (*func_pointer) (void); os_state_e e_state; } os_task_s; das ganze kommt dann in ein arry mit 10 "Task" os_task_s[10]; wenn nun mein RTC ISR kommt könnte ich den Task mit der höchsten Priorität und dem Zustand "wait" suchen und diesen aufrufen { ... ( * os_taks_s[TASK_9].func_pointer ) (); ... } Jetzt eure Meinung: - So ein Suchen in einer Interrupt Routine, ist sowas aufwendig, oder erzeugt es soviel overhead dass das ganze eigentlich keinen Mehrwert mehr hat. es könnten dann aufruge verhungern... ausserdem ist das ganze ja dann nicht mehr besonders "echtzeitfähig"... ausser eben diese Taks die hoch-prior sind ;-) naja, war nur mal so ne Idee.. ich denke nciht, dass ich es umsetzen werden.. aktuell läuft es ja, nur noch nicht schnell genug :-) thx
Nur an einem umpassenden System kleben zu bleiben weil es nichts taugt ist etwas mager. Wenn etwas nicht passt muss man es auch hiterfragen. Einen Schritt der nur 10ms dauert muss man nicht anzeigen, den sieht man eh nicht. Allenfalls muss man debugmode/Einzelschritt und normalen Mode unterscheiden. Wenn ich anzeigen will, dass etwas geht, kann ich auch alle alle 100ms eine Zahl incrementieren. Ober eine einzelnen Punkt anzeigen.
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.