Also generell bin ich auch für entsprechende Debugmöglichkeiten.
Nur habe ich in unseren Projekten zu oft erleben müssen, das Breaks und Stepping schlicht Chaos im Programmablauf und ggf. sogar im Gesammtsystem erzeugt haben und oft genug nicht zur Klärung von unerwarteten Abweichungen beigetragen haben. Erfolgreicher waren da Trace-Analysen mit Emulatoren inklusive Aufzeichnung aller interessierender Busdaten und Hardware-Signalen (Logicanalyzer, Speicherscopes). Das alles steht mir privat für den EibPC aber nicht zur Verfügung (von Busaufzeichnung per ETS mal abgesehen) und würde auch mehr Kenntnisse über die Interna des EibPCs voraussetzen, als Enertex bislang veröffentlichen möchte.
OK, Breakpoints und Debug-Code sind besser als nichts, aber ob wirklich hilfreich genug, um den zusätzlichen Entwicklungsaufwand inklusive langer Beta-Tests zu rechtfertigen? Irgend jemand muss prüfen, ob das alles auch korrekt arbeitet. Und das ist sicher nicht trivial.
Ankündigung
Einklappen
Keine Ankündigung bisher.
In der Tiefe: Validierungskonzept
Einklappen
X
-
Es ging ja nur um einen Denkanstoß zur Umsetzbarkeit. Völlig unabhängig von der tatsächlichen Umsetzung (da gibt es soooooo viele Möglichkeiten, dass ich das gar nicht vertiefen möchte) arbeiten wir bei der SW-Entwicklung von Echtzeitsystemen u.a. mit dieser Möglichkeit.Zitat von Tessi Beitrag anzeigenSpezieller Debug-Code auf dem EibPC? Birgt grundsätzlich das Risiko, das dieser Code sich dann nicht exakt gleich dem Standard-Code verhält und schon der ist nicht ganz fehlerfrei, wie würde das erst mit dem (für die meisten ja nicht so wichtigen) Debug-Code werden?
Lass es eine Historie von 300 Zyklen sein (da ändert sich praktisch nichts) und die Rechenleistung um 50% steigen, dann könnte man hiermit immer noch sehr schön den Programmlauf analysieren.
Auch bei einem Echtzeitsystem hat das am Ende keinen Einfluss auf den eigentlichen Einsatz des Systemes, da es ja nicht darum geht, die Echtzeitfähigkeit zu testen -> es kommt nicht auf Echtzeitverfügbarkeit an, denn ich kann ja nachträglich in Ruhe analysieren.
Gründe hierfür sind das Validierungsschema mit den unterschiedlichen Abarbeitungen von Events (teilweise erst im nächsten Zyklus) und das aktualisieren der Variablen erst am Ende des Zyklus, was Debugging über Variablen unmöglich macht.
Das hat erst mal nichts mit C-Programmierern im Allgemeinen zu tun, eher mit PC-Programmierern, die sich nur mit "statischer" SW am PC beschäftigen ... aber auch die haben die gleichen Probleme.Breakpoints im laufenden Code:
Angesichts der Art und Weise wie der Compiler den Code für den EibPC aufbereitet stellt sich mir die Frage, wie das generell funktionieren soll, bzw. ob es dann auch so funktionieren würde/könnte, wie es sich ein C-Programmierer dann so vorstellen würde.
Die Ausführung des Codes zu stoppen ist jetzt ja auch keine neue Erfindung. Es wird immer gerne verwendet um die Programmausführung bis zu einem bestimmten Zeitpunkt zu verifizieren und dann entweder (mit den inzwischen unveränderten oder veränderten Bedingungen) weiter laufen zu lassen.
Das ist auch nicht zwangsläufig der Zweck des Breakpoints. Man will den Status-quo sichten und evtl. per Einzelschritt (was ich noch gar nicht angesprochen habe) die nächsten Schritte anschauen. Ob sich in der restlichen Welt etwas getan hat oder nicht ist ja erst relevant, wenn es auch um Events im Bereich des betrachteten Codes geht. Ob die Rollos (immer noch) richtig laufen, während ich die Lichtsteuerung in der Küche debugge ist ja einerlei.Es handelt sich hier um ein Echtzeitsystem das in einer Echtzeitumgebung läuft, die ihrerseits nichts vom Breakpoint weiß und einfach weiter läuft. Damit verändert ein Break die Situation und eine Fortsetzung des Ablaufs - so es überhaupt noch geht - liefert nicht mehr garantiert die gleichen Resultate, als hätte es den Break nie gegeben.
Neu booten zwar nicht, aber das Programm neu starten ... aber das mach ich beim Programmieren ja ständig, also warum nicht auch nach dem debuggen?Ggf. bekommt der EibPC während des Breaks übertragene Bus-Telegramme nicht mit, dann wird die Sache inkonsistent und der EibPC müsste eigentlich neu gebootet werden...
Ob jemand den Aufwand treiben möchte?
Einen Kommentar schreiben:
-
Also Anzeige aller laufenden Timer: OK.
Spezieller Debug-Code auf dem EibPC? Birgt grundsätzlich das Risiko, das dieser Code sich dann nicht exakt gleich dem Standard-Code verhält und schon der ist nicht ganz fehlerfrei, wie würde das erst mit dem (für die meisten ja nicht so wichtigen) Debug-Code werden?
Historie auf dem EibPC wäre wohl zu viel Datenvolumen. Aber ob der EibPC statt dessen jede Änderung rechtzeitig zwecks dortiger Historie an das EibStudio übermitteln könnte, müsste auch erst einmal geklärt werden. Wegen der zusätzlichen Last wäre das wohl auch nur Debug-Code, mögliche Probleme: siehe oben.
Breakpoints im laufenden Code:
Angesichts der Art und Weise wie der Compiler den Code für den EibPC aufbereitet stellt sich mir die Frage, wie das generell funktionieren soll, bzw. ob es dann auch so funktionieren würde/könnte, wie es sich ein C-Programmierer dann so vorstellen würde.
Und selbst wenn es dann gelänge, das System zu stoppen, was hat man dann davon? Es handelt sich hier um ein Echtzeitsystem das in einer Echtzeitumgebung läuft, die ihrerseits nichts vom Breakpoint weiß und einfach weiter läuft. Damit verändert ein Break die Situation und eine Fortsetzung des Ablaufs - so es überhaupt noch geht - liefert nicht mehr garantiert die gleichen Resultate, als hätte es den Break nie gegeben.
Ggf. bekommt der EibPC während des Breaks übertragene Bus-Telegramme nicht mit, dann wird die Sache inkonsistent und der EibPC müsste eigentlich neu gebootet werden...
Ob jemand den Aufwand treiben möchte?
Einen Kommentar schreiben:
-
Wird es da noch etwas geben?Zitat von saft6luck Beitrag anzeigenZum Thema Debugger hätte ich auch noch 3:
- Anzeige aller aktuell laufender Timer (sehe ich als sehr wichtig an)
- Historie der Variablenwerte (Debugcode und nur augewählter Variablen?)
- Breakpoints (im laufenden Code) auch mit Trigger auf bestimmte Variablenwerte
Einen Kommentar schreiben:
-
Hi,Zitat von SteffiEnertex Beitrag anzeigenWas genau willst Du machen?
Wenn ich das richtig verstehe geht es um:
bei sonnenaufgang aber frühestens um und um x Minuten vorgezogen.
Vor allem will ich diese Zeit dann auch in der Visu darstellen, daher verwende ich (eigentlich) eine einfache Logik um diese 2 Werte, Stunden und Minuten zu berechnen und dann Aktionen davon abzuleiten.
Weitere Aktionen sind eben die Rolläden zu fahren, nicht alle zur gleichen Zeit -> mit kurzen Äbständen starten. Dann den Versatz später dynamisch berechnen zu lassen (Jahreszeitabhängig), den max. Wert über die Visu einzustellen und die Rolos von Terrassenlicht/Öffnungszustand der Türen erst später zu fahren.
Dabei würde ich die Berechnung der Zeiten von den Steuerungen gerne entkoppeln.
Wenn die Überläufe weiterhin nicht dargestellt sind, die je eben auch weiterhin die Probleme verursachenMinute= sunriseminute() - Minute_vorziehen
if sun() and chtime(Stunde,Minute,0) then write(AktorGA, WertGA) endif
gilt doch:
Minute= sunriseminute() - Minute_vorziehen
if chtime(Stunde,Minute,0) then write(AktorGA, WertGA) endif
Oder anders ausgedrückt sun() ist zumindest (= ohne die Anleitung gefragt zu haben) redundant
.
Einen Kommentar schreiben:
-
Guten Morgen Marc,
sunrisehour() wird auch neu berechnet, allerdings ändert sich der Wert (im Moment) nicht; deshalb ändert sich für den compiler nichts.
Was genau willst Du machen?
Wenn ich das richtig verstehe geht es um:
bei sonnenaufgang aber frühestens um und um x Minuten vorgezogen.
Minute= sunriseminute() - Minute_vorziehen
if sun() and chtime(Stunde,Minute,0) then write(AktorGA, WertGA) endif
Negative Werte für Minute müssen natürlich auch hier ausgeschlossen werden; daran hast Du ja schon gedacht.
steffi
Einen Kommentar schreiben:
-
Schönes Beispiel für "Die Verschachtelungen vermeiden" macht alles trivial und hilft immerZitat von SteffiEnertex Beitrag anzeigenich hab den Code noch etwas mit Kommentaren versehen, damit ich auf einzelne Anweisungen besser verweisen kann.
Insgesamt ist das ein wirklich banales Problem, diese Umsetzung aber chaotisch!
Das eigentliche Problem habe ich aber gefunden, denn sunrisehour() wird nicht neu zugewiesen, wenn sind sunriseminute() ändert, allerdings hatte ich die entsprechende Zuweisung erst zum Debuggen entfernt und im Debugger habe ich die Stunden auch immer entsprechend geändert ... bleibt also nur doch nur das init-Problem.
Ich werde einfach mal folgendes testen:
[highlight=epc]
// Rollo - Sonnenaufgang
Rollo_Sonnenaufgang_vorziehen = 7s08
Rollo_Sonnenaufgang_min_h = 07u08
Rollo_Sonnenaufgang_min_m = 00u08
Rollo_Sonnenaufgang_m = 60u08
Rollo_Sonnenaufgang_h = 25u08
Rollo_Sonnenaufgang_h_current = sunrisehour()
Rollo_Sonnenaufgang_m_s = convert( sunriseminute(), 0s08) - Rollo_Sonnenaufgang_vorziehen; /* -> Minuten: -15 <= m <= 44 */
if change( Rollo_Sonnenaufgang_m_s ) or systemstart() then {
Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_h_current;
if ( Rollo_Sonnenaufgang_m_s < 0s08 ) then {
Rollo_Sonnenaufgang_m_s = Rollo_Sonnenaufgang_m_s + 60s08;
Rollo_Sonnenaufgang_h = sunrisehour() - 1u08
} endif;
Rollo_Sonnenaufgang_m = convert( Rollo_Sonnenaufgang_m_s, 0u08 );
if ( ( Rollo_Sonnenaufgang_h == Rollo_Sonnenaufgang_min_h ) and ( Rollo_Sonnenaufgang_m < Rollo_Sonnenaufgang_min_m ) ) then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m
} endif;
if ( Rollo_Sonnenaufgang_h < Rollo_Sonnenaufgang_min_h ) then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m;
Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_min_h
} endif;
} endif
[/highlight]
Einen Kommentar schreiben:
-
Hallo Marc,
ich hab den Code noch etwas mit Kommentaren versehen, damit ich auf einzelne Anweisungen besser verweisen kann.
[highlight=epc]
[EibPC]
// Rollo - Sonnenaufgang
Rollo_Sonnenaufgang_vorziehen = 7s08
Rollo_Sonnenaufgang_min_h = 07u08
Rollo_Sonnenaufgang_min_m = 00u08
Rollo_Sonnenaufgang_m = 60u08
Rollo_Sonnenaufgang_h = sunrisehour()
Rollo_Sonnenaufgang_m_s = convert( sunriseminute(), 0s08) - Rollo_Sonnenaufgang_vorziehen; /* -> Minuten: -15 <= m <= 44 */
Sonne=change( Rollo_Sonnenaufgang_m_s ) or systemstart()
// Anweisung1
//wird beim systemstart durch Anweisung4 überschrieben; da Anweisungen sequenziell abgearbeitet werden
//
// wenn sich sunriseminute() ändert (täglich 1x), wird die Rollo_Sonnenaufgang_m aktualisiert
if Sonne then {
Rollo_Sonnenaufgang_m = convert( Rollo_Sonnenaufgang_m_s, 0u08 )
} endif
// Anweisung2 - wird im Moment nicht aktiv
if ( Rollo_Sonnenaufgang_m_s < 0s08 ) and Sonne then {
Rollo_Sonnenaufgang_m_s = Rollo_Sonnenaufgang_m_s + 60s08;
Rollo_Sonnenaufgang_h = sunrisehour() - 1u08
} endif
// Anweisung3 - wird im Moment nicht aktiv
if ( ( Rollo_Sonnenaufgang_h == Rollo_Sonnenaufgang_min_h ) and ( Rollo_Sonnenaufgang_m < Rollo_Sonnenaufgang_min_m ) ) and Sonne then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m
} endif
// Anweisung4
// da beim Systemstart -> Rollo_Sonnenaufgang_h =6 und Sonne kurz auf EIN geht werden
// Rollo_Sonnenaufgang_m = 0; Rollo_Sonnenaufgang_h=7 gesetzt
if ( Rollo_Sonnenaufgang_h < Rollo_Sonnenaufgang_min_h ) and Sonne then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m;
Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_min_h
} endif
[/highlight]
beim Initialisieren wird durch:
[highlight=epc]
Rollo_Sonnenaufgang_m_s = convert( sunriseminute(), 0s08) - Rollo_Sonnenaufgang_vorziehen; /* -> Minuten: -15 <= m <= 44 */
[/highlight]
Rollo_Sonnenaufgang_m_s = 45 gesetzt
Rollo_Sonnenaufgang_min_h = 6
Rollo_Sonnenaufgang_min_m = 0
Beim Systemstart wird Sonne kurz auf EIN gsetzt
[highlight=epc]
Sonne=change( Rollo_Sonnenaufgang_m_s ) or systemstart()
[/highlight]
Anweisung1 setzt
Rollo_Sonnenaufgang_m = 45
Anweisung4 setzt
Rollo_Sonnenaufgang_m =0
Rollo_Sonnenaufgang_h = 7
=> 7:00
am nächsten Tag wird sunriseminute() neu berechnet.
Dadurch bekommt Rollo_Sonnenaufgang_m_s einen neuen Wert
[highlight=epc]
Rollo_Sonnenaufgang_m_s = convert( sunriseminute(), 0s08) - Rollo_Sonnenaufgang_vorziehen; /* -> Minuten: -15 <= m <= 44 */
[/highlight]
Dadurch wird diese Zuweisung neu ausgeführt:
[highlight=epc]
Sonne=change( Rollo_Sonnenaufgang_m_s ) or systemstart()
[/highlight]
Sonne geht kurz auf EIN
Dadurch wird Anweisung1 ungültig und neu ausgeführt
[highlight=epc]
if Sonne then {
Rollo_Sonnenaufgang_m = convert( Rollo_Sonnenaufgang_m_s, 0u08 )
} endif
[/highlight]
und der Wert für Minuten ändert sich.
=> 7:4x
steffi
Einen Kommentar schreiben:
-
So, ein Tag später und ... das gleiche Problem mit deinem Code. Nach dem Systemstart stimmt es zwar (-> 7:00), heute stehen die Minuten stehen aber auf 48 (->7:48), was erstens der falsche Wert für heute ist (Sonnenaufgang 6:52) und zweitens ja 00 sein sollte.Zitat von enertegus Beitrag anzeigenIch habs mal eingespeist. Das wird aber noch dauern...
Was spricht gegen das: (oder hast Du hier auch ein Problem festgestellt?
[highlight=epc]
// Rollo - Sonnenaufgang
Rollo_Sonnenaufgang_vorziehen = 7s08
Rollo_Sonnenaufgang_min_h = 07u08
Rollo_Sonnenaufgang_min_m = 00u08
Rollo_Sonnenaufgang_m = 60u08
Rollo_Sonnenaufgang_h = sunrisehour()
Rollo_Sonnenaufgang_m_s = convert( sunriseminute(), 0s08) - Rollo_Sonnenaufgang_vorziehen; /* -> Minuten: -15 <= m <= 44 */
Sonne=change( Rollo_Sonnenaufgang_m_s ) or systemstart()
if ( Rollo_Sonnenaufgang_m_s < 0s08 ) and Sonne then {
Rollo_Sonnenaufgang_m_s = Rollo_Sonnenaufgang_m_s + 60s08;
Rollo_Sonnenaufgang_h = sunrisehour() - 1u08
} endif
if Sonne then Rollo_Sonnenaufgang_m = convert( Rollo_Sonnenaufgang_m_s, 0u08 ) endif
if ( ( Rollo_Sonnenaufgang_h == Rollo_Sonnenaufgang_min_h ) and ( Rollo_Sonnenaufgang_m < Rollo_Sonnenaufgang_min_m ) ) and Sonne then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m
} endif
if ( Rollo_Sonnenaufgang_h < Rollo_Sonnenaufgang_min_h ) and Sonne then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m;
Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_min_h
} endif
[/highlight]
Darf ich kurz meinem Unmut freien Lauf lassen?
Einen Kommentar schreiben:
-
Ja, so ähnlich habe ich es jetzt auch.Zitat von enertegus Beitrag anzeigenIch habs mal eingespeist. Das wird aber noch dauern...
Was spricht gegen das: (oder hast Du hier auch ein Problem festgestellt?
Aber es kann doch nicht sein, dass die viel beschworene Event-getriebene Verarbeitung einen Event nicht schrittweise bearbeiten kann.
Von Divide et impera kann man da ja nicht reden, wenn man jeden Event bis ans Ende der Berechnung mitschleifen muss. Wie sieht es denn mit anderen Verschachtelungen aus, z.B. in den Command Fusion Makros?
Einen Kommentar schreiben:
-
Ich habs mal eingespeist. Das wird aber noch dauern...Zitat von saft6luck Beitrag anzeigenIst schon absehbar, wann es für obiges Problem einen Patch gibt? (nicht das Initialisierungsproblem!)
Was spricht gegen das: (oder hast Du hier auch ein Problem festgestellt?
[highlight=epc]
// Rollo - Sonnenaufgang
Rollo_Sonnenaufgang_vorziehen = 7s08
Rollo_Sonnenaufgang_min_h = 07u08
Rollo_Sonnenaufgang_min_m = 00u08
Rollo_Sonnenaufgang_m = 60u08
Rollo_Sonnenaufgang_h = sunrisehour()
Rollo_Sonnenaufgang_m_s = convert( sunriseminute(), 0s08) - Rollo_Sonnenaufgang_vorziehen; /* -> Minuten: -15 <= m <= 44 */
Sonne=change( Rollo_Sonnenaufgang_m_s ) or systemstart()
if ( Rollo_Sonnenaufgang_m_s < 0s08 ) and Sonne then {
Rollo_Sonnenaufgang_m_s = Rollo_Sonnenaufgang_m_s + 60s08;
Rollo_Sonnenaufgang_h = sunrisehour() - 1u08
} endif
if Sonne then Rollo_Sonnenaufgang_m = convert( Rollo_Sonnenaufgang_m_s, 0u08 ) endif
if ( ( Rollo_Sonnenaufgang_h == Rollo_Sonnenaufgang_min_h ) and ( Rollo_Sonnenaufgang_m < Rollo_Sonnenaufgang_min_m ) ) and Sonne then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m
} endif
if ( Rollo_Sonnenaufgang_h < Rollo_Sonnenaufgang_min_h ) and Sonne then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m;
Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_min_h
} endif
[/highlight]
Einen Kommentar schreiben:
-
Ist schon absehbar, wann es für obiges Problem einen Patch gibt? (nicht das Initialisierungsproblem!)
Einen Kommentar schreiben:
-
Ehrlich gesagt habe ich das schon probiert, nur wird der Code (der Ausschnitt ist ja nur ein kleiner Teil) dann schon ziemlich gestelzt.Zitat von enertegus Beitrag anzeigenSorry, da war ich in Eile... streich das einfach.
Wird beim Intialsieren ausgwertet (unabhängig von der übergeordneten if-Anweisung).
Workaround ist nur die Verschachtelung vermeiden, wenn sie sich so wie bei Dir auswirkt.
Es ist auch etwas sonderbar, dass aus dem Code:
if ( Rollo_Sonnenaufgang_h < Rollo_Sonnenaufgang_min_h ) then {
Rollo_Sonnenaufgang_m = Rollo_Sonnenaufgang_min_m;
Rollo_Sonnenaufgang_h = Rollo_Sonnenaufgang_min_h
} endif;
scheinbar nur der rote Teil nicht ausgeführt wird ... liegt evtl. an der vorausgehenden Zuweisung?
EDIT: Heute sind die Minuten auch falsch (1. eigenständige Änderung seit gestern): 7:48 -> da ist der Wurm drin! Mit dem Debugger kann ich eine Änderung anstoßen und dann klappt es.
Einen Kommentar schreiben:
-
Sorry, da war ich in Eile... streich das einfach.Zitat von saft6luck Beitrag anzeigenHm, was: "wird ... auf einmal ausgewertet" bedeutet verstehe ich nicht. Meinst du 'in einem Stück' oder 'plötzlich'?
Wird beim Intialsieren ausgwertet (unabhängig von der übergeordneten if-Anweisung).
Workaround ist nur die Verschachtelung vermeiden, wenn sie sich so wie bei Dir auswirkt.
Einen Kommentar schreiben:
-
Hm, was: "wird ... auf einmal ausgewertet" bedeutet verstehe ich nicht. Meinst du 'in einem Stück' oder 'plötzlich'?Zitat von enertegus Beitrag anzeigenDas Problem im Code ist ein (sicher unschönes) Verhalten der Verschachtelten if-Abfrage beim Initialisieren (siehe die vorigen mails): Einfach gesprochen: Jede if-Abfrage wird beim Initalisierungsvorgang auf einmal ausgewertet, egal ob verschachtelt oder nicht. Wir haben das auf dem Radar fürs nächste Relase.
Egal, gibt es einen Fix? change( sunriseminute() ) löst es jedenfalls nicht, auch wenn du das im angegebenen Posting geschrieben hast.
Einen Kommentar schreiben:

Einen Kommentar schreiben: