www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Möglichkeiten um Sequenzabarbeitung zu erhöhen


Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;-) )

Autor: 11833 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja. Du brauchst eine zweite Schrittkette für das Display. Und eine 
übergebende Funktion.

Dein Schritt 1 ist nur ein Funktionsaufruf, zb so:
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.

Autor: jl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Na sowas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.