www.mikrocontroller.net

Forum: Codesammlung Shared Timer

Autor: BPDI (Gast)
Datum: 12.06.2008 12:06
Dateianhang: sharedTimer.c (4,9 KB, 232 Downloads) | formatierter Code

Dieses Modul dient zur gemeinsamen Nutzung eines Timers.

Im wesentlichen besteht der SharedTimer aus einer priorisierten Queue
von Benachrichtigungs-Elementen, die aufsteigen nach dem jeweiligen
Auslösezeitpunkt sortiert werden.

Daraus ergibt sich das in der Regel nur der Auslösezeitpunkt der oberste
Benachrichtigung überprüft werden muss, ist dieser erreicht oder wurde
er bereits überschritten, wird die Benachrichtigung aus der Queue
abgerufen und die übergebene Funktion ausgeführt.

Über die Methode shared_timer_init(...) wird das Modul initialisiert.

Die Methode shared_timer_tick(...) muss regelmäßig durchlaufen werden,
denn hier findet die Überprüfung und Auslösung der eingestellten
Benachrichtigungen statt. Über den Parameter time wird die aktuelle
Systemzeit übergeben, diese wird zum Zeitvergleich mit den
Auslösezeitpunkten der Benachrichtigungen benötigt.

Über die Methoden shared_timer_notifyEach(...),
shared_timer_notifyAt(...) können Benachrichtigungen eingestellt werden.
Über shared_timer_notifyEach(...) kann eine regelmäßige Benachrichtigung
eingestellt werden, über den Parameter seconds wird das Interval der
Benachrichtigung angegeben. Über shared_timer_notifyAt(...) wird eine
einmalige Benachrichtiung eingestellt, der Parameter time legt den
Auslösezeitpunkt fest.

Im aktuellen Versionsstand verwende ich eine Variable vom Typ unsigned
long welche die fortlaufende Systemzeit hält. Und in meier aktuellen
Anwendung des SharedTimers wird diese Systemzeit im Sekundentakt
hochgezählt.

Da ich mit meinen C Kenntnissen nach am Anfang stehe bitte ich euch
einmal den Code zu beurteilen.
Autor: Wasweissich (Gast)
Datum: 13.06.2008 15:39

Ich muss schon sagen, das Du Dir augenscheinlich viel Mühe gemacht hast
gut zu strukturieren. Und das Ganze ist sicherlich nach einigen
Verbesserungen gut brauchbar.

Dennoch gibt es ja immer etwas zu verbessern. Vielleicht überdenkst Du
die folgenden Punkte und entscheidest Dich dann ob Du meine Kritik
zutreffend findest.

1. Namenswahl
An verschiedenen Stellen finde ich Namen von Variablen, Funktionen und
Makros die mir nicht passend erscheinen.

Zuerst möchte ich aber vorausschicken, dass mir hier "enqueue" und
"dequeue" zutreffend zu sein scheint. Denn dies ist ja fast der Prototyp
einer Warteschlange.

1.a. LEFT, PARENT
Als ich das gelesen habe, habe ich ganz instinktiv nochmal in die
Definition der Struktur geguckt, ob ich darin Zeiger auf linke oder
Rechte Knoten finde. Die Terminologie kenne ich von Bäumen. Es handelt
sich hier aber nicht um Bäume. Da die einzelnen Einträge keinen
Zusammenhang haben, es handelt sich um unabhängig voneinander laufende
"Timer" haben die keinen linken Nachfolger oder einen Parent
(Elternteil).
Auch die andere mögliche Bedeutung von "LEFT", nämlich "verbleibend"
oder etwas unschärfer "Rest" scheint mir hier nicht zuzutreffen.
Die Berechnung in LEFT und PARENT scheint mir eher auf ein binäres
Sortieren als auf BubbleSort hinzuweisen.

1.b. Heap
"Heap" heisst ja Haufen. Eine ungeordnete Menge von Dingen. Da hier aber
eine Array (schon aus der Deklaration erkennbar) vorliegt und auch die
Elemente geordnet sind scheint mir das nicht passend. Ausserdem hat das
Wort Heap schon zwei Verwendungen. In dem nämlich dies ein Bereich von
Speicher ist, von dem zur Laufzeit eines Programmes Variablen
angefordert werden (malloc, free) oder auch eine Baumstruktur gemeint
ist. (Siehe Wikipedia).

2. Als zweites sind mir einige Punkt bei der Programmierung aufgefallen:

2.a. In dequeue_notification prüfst Du als erstes ob in dem Array der
Timer noch welche vorhanden sind. Das aber ist in shared_timer_tick
schon die Vorbedingung zum Aufruf von dequeue_notification. Es braucht
also nicht noch ein zweites Mal aufgerufen werden.

2.b. Was mir merkwürdig vorkommt, ist das ein abgelaufener Timer durch
dequeue_notification behandelt werden muss. Er könnte doch einfach
gelöscht werden.

2.c. In dem Zusammenhang ist es besser zu prüfen ob ein Timer in der
Liste verbleiben muss (bei einem zyklischen Timer) bevor man das ganze
dequeue_notification und enqueue_notification laufen lässt.

2.d. Das Ganze könnte etwas einfach sein, wenn man einen Ringbuffer
verwendet.

2.e. Das Programm prüft nicht ob noch weitere Timer mit der gleichen
Ablaufzeit vorliegen. Ein evtl. weiterer Timer würde dann erst eine
Sekunde später ablaufen. Ein folgender mit der gleichen Ablaufzeit
wiederum eine Sekunde später.

2.f. Das Programm könnte universeller (und schneller sein), wenn nicht
die absolute Zeit des Ablaufens sondern die Anzahl der Sekunden _bis zum
ablaufen_ gespeichert wird. Die Variable könnte dann kleiner sein und
die Verarbeitung wäre schneller.


Ich hoffe Du findest die Kritik hilfreich.

Gruss
Autor: BPDI (Gast)
Datum: 16.06.2008 07:27

Hallo

Vielen Dank für Die Hinweise, Kritik. Werde versuchen an Hand der
Vorschläge das ganze noch einmal zu überarbeiten.
Autor: Ralf Schwarz (spacedog) Benutzerseite
Datum: 16.06.2008 07:51

@Wasweissich, zu Punkt 1.a/b.:

Mensch, nur weil du nicht verstehst, was BPDI gemacht hat, heisst noch
lange nicht, dass eine Heap-Struktur nicht geeignet ist. Das ganze
implementiert halt einen Heap-Sort, welcher es ermöglicht, dass man in
ca. O(log(n)) Zeit Daten hineinschreiben kann und auch in O(log(n))
Daten herauslesen kann. Die Zeit zur Sortierung der Timer-Ereignisse
wird somit gerecht verteilt zwischen dem Zeitpunkt wo ein neues Ereignis
in die Queue kommt und dem Zeitpunkt wo das nächste Ereignis eintrifft.
Dies kann in vielen Fällen sehr sinnvoll sein. Lern also erst mal
Programmieren, Wasweissich.


@BPDI:

Wirklich super. Dass du mit deinen C-Kenntnissen noch am Anfang stehst
macht ja nichts, denn du kennst dich aus mit Datenstrukturen und
Algorithmen. Ich hoffe dich noch oft hier anzutreffen im Forum, solche
Leute wie dich kann man brauchen. Denn leider hat es viele Besserwisser
hier und manchmal etwas zu wenig solche die wirklich verstehen, worüber
sie reden.
Autor: Peter Dannegger (peda)
Datum: 16.06.2008 08:59

Ralf Schwarz wrote:

> Lern also erst mal
> Programmieren, Wasweissich.


Was ist denn mit Dir los?

Na klar, das hier ist ein Forum nur für die Super-Gurus, alle anderen
haben gefälligst die Klappe zu halten.
Es liegt in der Natur des Menschen, daß man nicht alles versteht, dann
kannst Du das doch vernünftig sagen und erklären.

Z.B. die Idee mit der Differenzzeit statt der absoluten Zeit ist nicht
nur Ressourcen sparender, sondern macht auch keine Fehler beim
Timerüberlauf.
O.k. bei 1ms Zeitbasis tritt der Überlauf nur alle 50 Tage auf, aber
Fehler bleibt Fehler.
Und wenn alle 50 Tage die Bestrahlzeit eines medizinischen Gerätes
falsch ist, dann entschuldige Dich bitte Du dafür bei den
Hinterbliebenen.


Peter
Autor: Peter Dannegger (peda)
Datum: 16.06.2008 09:04

Ralf Schwarz wrote:

> @BPDI:
>
> Wirklich super. Dass du mit deinen C-Kenntnissen noch am Anfang stehst
> macht ja nichts

Also ehrlich gesagt, auf mich wirkt der Code definitiv nicht wie der
eines Anfängers.
Die Benutzung von Macros und Pointern ist nicht der typische
Anfängerstil.
Das Programm sieht einfach zu elegant aus für einen Anfänger.


Peter
Autor: BPDI (Gast)
Datum: 16.06.2008 11:19

Hallo

Grundlage zum Thema priorisierte Warteschlangen findet man auch unter
Wikipedia. Vorlage oder auch Muster für meinen Code, war eine Lösung die
schon einmal unter VB6 entstanden ist. Ein paar Lösungen in der
Programmiersprache C findet man auch im Netz, wo auch Macros angewendet
wurden.
Als Anfänger möchte man natürlich irgendwann mal ein Ergebnis erreichen
und verwendet Code aus Beispielen, die man unter Umständen noch nicht
vollständig verstanden hat. So entsteht dann Code der zwar in einem
gewissen Kontext funktioniert, aber unter Betrachtung von Code Sytle,
Bennungskonventionen, Ressourcenverbrauch nicht sauber ist. Und die
Pointer Problematik ist für Anfänger auch eine Hürde die zu
Unsicherheiten führt.

Zu den Punkten:

>2.e. Das Programm prüft nicht ob noch weitere Timer mit der gleichen
>Ablaufzeit vorliegen. Ein evtl. weiterer Timer würde dann erst eine
>Sekunde später ablaufen. Ein folgender mit der gleichen Ablaufzeit
>wiederum eine Sekunde später.

In meiner Anwendung ist die verzögerter Auslösunge von Timern mit
gleicher Ablaufzeit nicht kritisch, daher habe ich immer nur das oberste
Benachrichtigungselement überprüft.

Die Lösung mit der Differenzzeit von Benachrichtigungselement zu
Benachrichtigungselement ist sicherlich ein bessere Weg und auch
Ressourcen schonender.
Autor: Wasweissich (Gast)
Datum: 17.06.2008 18:57

@ Ralf Schwarz

Deinen Kommentar hättest Du auch freundlicher formulieren können.

Mag ja sein, das ich nicht erkannt habe, das hier HeapSort angewendet
worden ist, aber ist das ein Grund mich dermassen anzugreifen und
abzuqualifizieren? Machst Du nie Fehler?

Wenn ich programmieren lernen muss musst Du erstmal soziales Verhalten
lernen.
Autor: Wasweissich (Gast)
Datum: 17.06.2008 19:01

Im übrigen fällt mir noch ein,
das die Timer ja eigentlich immer sortiert sind,
wenn ein neuer Timer eingetragen wird.
(Nicht gleich in der Luft zerreissen,
wenn das nicht zutrifft).
Vielleicht würde dann eine BinarySort ausreichen.
Autor: Wasweissich (Gast)
Datum: 17.06.2008 19:09

Ich schrieb:
>Vielleicht würde dann eine BinarySort ausreichen.
Haben beide die selbe Komplexität. Naja.
Hoffentlich liest Ralf Schwarz das nicht.

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net