Ankündigung

Einklappen
Keine Ankündigung bisher.

ESP8266 KNX mit ETS

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Hi,
    ich glaub wir reden hier aneinander vorbei. Ich weiß sehr wohl (und vor allem sehr hardwarenahe) was Ram, Flash, Eprom bzw. Eeprom ... ist.
    Aber egal, aus meiner Sicht ist es jedenfalls sehr sinnvoll für Parameter welche das wiederkehrende (über einen Powercycle hinaus gültige) Abspeichern einzelner Werte zur Laufzeit notwendig machen eine eeprom Simulation zu verwenden, zumindest eben wenn hierfür klassisches Flash (Page Erase) verwendet werden soll. Da bei einer eeprom Simulation das LESEN von Werten teils länger benötigt als das schreiben (es muss beim lesen der jeweils letzte gültige Eintrag gesucht werden) bedingt eine eeprom Simulation meisst ohnehin ein RAM Backup.

    VG,
    Walter




    Kommentar


      Zitat von Techi Beitrag anzeigen
      sehr sinnvoll für Parameter welche das wiederkehrende (über einen Powercycle hinaus gültige) Abspeichern einzelner Werte zur Laufzeit notwendig machen
      korrekt.
      Das ist aber nicht das, was wir hier üblicherweise unter Parameter verstehen - wir reden über die "KNX" Parameter, und die werden zur Laufzeit eben nicht wiederkehrend, sondern sehr selten geschrieben.
      OpenKNX www.openknx.de | NanoBCU und OpenKNX-HW verfügbar

      Kommentar


        Es ist im Grunde ganz einfach. Die Konfiguration liegt im Flash. Beim SAMD ist der Flash direkt adressierbar. Bei der EEPROM-Emulation wird ein Teil des Flashs in dem RAM kopiert. Da nach der Konfiguration durch ETS diese Daten nicht mehr geändert werden müssen sie nicht im RAM vorliegen. Also verschwendet die EEPROM-Emulation nur RAM.

        Kommentar


          Das ist perfekt auf den Punkt gebracht .

          Gruß, Waldemar
          OpenKNX www.openknx.de

          Kommentar


            Arbeitet eigentlich jemand hier mit einem ESP32 und WIFI, also IP? Ich hatte die Demo nach zahlreichen Versuchen irgendwann mal am Laufen. Dann habe ich darauf aufbauend für meine Applikation die knxprod mit weiteren Parametern und KOs angepasst. Soweit so gut.

            Beim Programmieren aus der ETS5 habe ich jetzt folgendes Verhalten: Nur physikalische Adresse funktioniert. Wenn ich anschließend das Applikationsprogramm laden möchte, kommt keine Antwort vom ESP32, ETS bricht mit Timeouts ab. Programmiere ich phys. Addresse und Applikationsprogramm läuft alles fehlerfrei durch. Beim anschließenden Neustart kommt vom ESP32 ein abort() beim Initialisieren der Groupobjects. Ich konnte herausfinden, dass die Variable goCount auf FFFF steht. Dafür reicht der RAM natürlich nicht, daher der abort(). Ich habe in meiner knxprod nur 3 KOs drin. Der Bereich, der beim SAVE gespeichert wird und beim RESTORE zurückgelesen wird ist identisch. Bei mir sind das 130 Bytes. Die letzten 20 stehen allerdings auf FF.
            Habt ihr einen Tipp für mich, wo ich bei der Fehlersuche ansetzen kann?
            Gruß Stefan

            Kommentar


              Hi,

              ich bin über ein paar Aussagen von Klaus Gütter gestolpert, die eine Optimierung beim partiellen Programmieren von Parametern erlauben würden:
              • Die ETS kann bei SystemB auch Parameter partiell programmieren, genauer gesagt ist die Einheit hier ein Memory-Block.
              • Es hat was mit der Implementierung von PID_MCB_TABLE zu tun
              • Die ETS würde dann nur geänderte Memory-Blöcke übertragen
              Ich hab dazu was in der KNX-Spec 3.5.1, Kapitel
              4.14.3 Application Program – Realisation Type 7 Used by: System B
              gefunden, aber nicht wirklich verstanden. Hat jemand eine Idee, was hier zu implementieren wäre? Ich hatte gehofft, im Stack auch Implementierungen für PID_MCB_TABLE bei group_object_table_object und association_table_object zu finden, weil dieses Property auch dort enthalten ist und ich Klaus so verstanden hatte, dass System B das implementieren muss. Scheint aber nicht so zu sein, ist bei dem Stack hier nicht drin.

              Was ich auch nicht verstehe: Parameter werden ja nicht mehr nach dem Programmieren verändert, so dass es eigentlich reichen sollte, wenn man passende Memory-Blöcke in der knxprod definiert und die ETS sollte selber wissen, welchen Memory-Block sie übertragen muss. Ich habe auch aus der Spec nicht rauslesen können, wie die ETS den CRC des jeweiligen MemoryBlocks ausliest. Einen Versuch, einfach mehrere Memory-Blöcke in der ETS zu definieren, habe ich gemacht, aber es wurden trotzdem alle übertragen...

              Wenn jemand hier Tipps hat, was man ausprobieren könnte bzw. wie man das implementieren könnte oder gar irgendwo ein Beispiel-Coding, dann wäre ich sehr dankbar, da mit diese Optimierung sehr interessieren würde.

              Derzeit übertrage ich auch bei einem geänderten Paramter immer alle 8800 Byte, mit der Optimierungen wären es 110 Byte.

              Gruß, Waldemar
              OpenKNX www.openknx.de

              Kommentar


                Weltenbummler Ich weiß nicht wie gut ESP32 funktioniert. Möglicherweise gibt es noch ein Endianess-Problem bei Speichern/Laden. Am besten mal bei memory.cpp debuggen.

                mumpf Mir geht es genau so. Am einfachsten wäre es eine knxprod zu nehmen die diese MCB-Blöcke nutzt, und die in ETS zu importieren, und dann das Geräte mit dem Stack zu emulieren. Dann muss man nicht parallel auf beiden Seiten (ETS und Gerät) rumprobieren.

                Kommentar


                  Zitat von thesing Beitrag anzeigen
                  Am einfachsten wäre es eine knxprod zu nehmen die diese MCB-Blöcke nutzt, und die in ETS zu importieren, und dann das Geräte mit dem Stack zu emulieren.
                  Ich werde mir mal einige knxprod anschauen, auch schon aus privatem Interesse. Aber ich bin noch keinem Gerät begegnet, bei dem offensichtlich Parameter-Deltas übertragen werden.

                  Falls ich was finde, melde ich mich nochmal.

                  Gruß, Waldemar
                  OpenKNX www.openknx.de

                  Kommentar


                    Hi allerseits,

                    im Rahmen meiner Analysen und Nachforschungen zur optimierten Programmierung bin ich auch darauf gestoßen, warum die APDU von 254 Bytes von der ETS nicht bei meinem SAMD genutzt wird: Der Serial1-Buffer ist nur 64 Byte groß. Meine MDT-Schnittstelle macht 2 Versuche, jeweils 63 Byte Nutzdaten zu schicken und fällt dann auf 12 Byte-Telegramme zurück.

                    Wenn man in der device_object.cpp die PID_MAX_APDU_LENGTH auf 56 setzt, funktioniert alles prima (mit 53 Byte Nutzdaten). Bei mir ist damit die Programmierzeit bei einem Gerät von 97 Sekunden auf 38 gesunken, also gut 2.5 mal schneller. APDU 57 funktioniert nicht mehr, es werden also scheinbar 8 Byte Verwaltungsinformationen gebraucht.

                    Trotzdem verstehe ich nicht
                    • wieso die ETS, obwohl sie PID_MAX_APDU_LENGTH = 254 bekommt, mit nur 63 Bytes schreibt (hängt das von der APDU der MDT-Schnittstelle ab?)
                    • wieso es nicht mit 63 Byte funktioniert, obwohl ich bei SAMD die SERIAL_BUFFER_SIZE auf 256 gesetzt habe
                    • wieso bei APDU 56 nur 53 Byte Nutzdaten übertragen werden (da wird sicher das Protokoll eine Rolle spielen und ich habe einfach noch nicht den eigentlichen Grund gefunden).
                    Ich bin erstmal zufrieden(er), aber wenn jemand weiß, wieso beim SAMD das Setting mit SERIAL_BUFFER_SIZE 256 nicht funktioniert, dann bitte Bescheid geben.

                    Gruß, Waldemar


                    OpenKNX www.openknx.de

                    Kommentar


                      Zitat von mumpf Beitrag anzeigen
                      Ich bin erstmal zufrieden(er), aber wenn jemand weiß, wieso beim SAMD das Setting mit SERIAL_BUFFER_SIZE 256 nicht funktioniert, dann bitte Bescheid geben.
                      wie hast du denn SERIAL_BUFFER_SIZE auf 256 erhöht? Welche Änderung genau in welchem File ?
                      OpenKNX www.openknx.de | NanoBCU und OpenKNX-HW verfügbar

                      Kommentar


                        Hi,

                        Zitat von SirSydom Beitrag anzeigen
                        Welche Änderung genau in welchem File ?
                        ich hatte in platfromIO.ini ein -DSERIAL_BUFFER_SIZE=256 gesetzt (compiler-define). Daraufhin gab es viele "redefinition-warnings" bei Uart.h und bei RingBuffer.h. In den beiden habe ich dann ein folgendes eingefügt:
                        Code:
                        #ifndef SERIAL_BUFFER_SIZE
                        #define SERIAL_BUFFER_SIZE 64
                        #endif
                        Daraufhin sind die "redefinition-warnings" weg gewesen. Normalerweise funktioniert das Pattern gut, um bestimmte Parameter erst zur compilezeit zu bestimmen, aber falls Du einen Tipp hast, immer her damit.

                        Ich hab auch im knx-Stack nochmal gesucht, aber da beziehen sich die relevanten Teile auf
                        Code:
                        #define MAX_KNX_TELEGRAM_SIZE 263
                        zumindest soweit ich es nachvollziehen konnte.

                        Irgendwo ich noch eine 64 dazwischen...

                        Gruß, Waldemar

                        OpenKNX www.openknx.de

                        Kommentar


                          Hi,

                          hier nochmal ein paar Infos, wie man die ETS zum schnelleren Programmieren bewegen kann mit partieller Programmierung. Das sind erstmal Versuche und Zwischenergebnisse, mir ist noch nicht klar, was alles im Stack gemacht werden muss, damit das alles rund läuft. Vor allem auch, weil es wohl hier noch ein Issue gibt: https://github.com/thelsing/knx/issues/93. Aber ich wollte mit euch die Erkenntnisse teilen, auch wenn ich noch nicht wirklich weiß, was ich da mache.

                          Ich habe eine SysetmB-Applikation bei meinen Geräten gefunden (MDT-IP-Schnittstelle, die 2. Applikation, also der email-client und Zeitserver). Da hab ich nur einen Parameter geändert und war beeindruckt, dass beim partiellen Programmieren nur 1-Byte vom Parameterblock übertragen wurde !!!

                          Code:
                           [TABLE]
                           	 		[TR]
                           			[TD]#[/TD]
                           			[TD]Zeit[/TD]
                           			[TD]Dienst[/TD]
                           			[TD]Flags[/TD]
                           			[TD]Prio[/TD]
                           			[TD]Quelladresse[/TD]
                           			[TD]Quellname[/TD]
                           			[TD]Zieladresse[/TD]
                           			[TD]Zielname[/TD]
                           			[TD]Rout[/TD]
                           			[TD]Typ[/TD]
                           			[TD]DPT[/TD]
                           			[TD]Info[/TD]
                           		[/TR]
                           		[TR]
                           			[TD]155[/TD]
                           			[TD]27.03.2021 14:29:22,131[/TD]
                           			[TD]zum Bus[/TD]
                           			[TD] [/TD]
                           			[TD]System[/TD]
                           			[TD]1.0.250[/TD]
                           			[TD]ETS[/TD]
                           			[TD]1.0.3[/TD]
                           			[TD]SCN-IP000.02 IP Interface mit Email Funktion[/TD]
                           			[TD]6[/TD]
                           			[TD]MemoryWrite (S=7)[/TD]
                           			[TD] [/TD]
                           			[TD][MARKIEREN]Count=1, Address=$16E9, Data=$0A[/MARKIEREN][/TD]
                           		[/TR]
                           	 [/TABLE]
                          Ich hab auch den Parameter von 9 auf 10 geändert!
                          Programmierzeit war hier nur 7 Sekunden, der Parameterblock ist eigentlich   Size="3972" , also fast 4k.
                          Code:
                          Start: 14:29:19
                          Ende: 14:29:26
                          Man erkennt bei der Programmierung, dass Property 27 (PID_MCB_TABLE) mehrfach abgefragt wird, vor der Programmierung
                          Code:
                           [TABLE]
                           	 		[TR]
                           			[TD]#[/TD]
                           			[TD]Zeit[/TD]
                           			[TD]Dienst[/TD]
                           			[TD]Flags[/TD]
                           			[TD]Prio[/TD]
                           			[TD]Quelladresse[/TD]
                           			[TD]Quellname[/TD]
                           			[TD]Zieladresse[/TD]
                           			[TD]Zielname[/TD]
                           			[TD]Rout[/TD]
                           			[TD]Typ[/TD]
                           			[TD]DPT[/TD]
                           			[TD]Info[/TD]
                           		[/TR]
                           		[TR]
                           			[TD]109[/TD]
                           			[TD]27.03.2021 14:29:20,980[/TD]
                           			[TD]vom Bus[/TD]
                           			[TD] [/TD]
                           			[TD]System[/TD]
                           			[TD]1.0.3[/TD]
                           			[TD]SCN-IP000.02 IP Interface mit Email Funktion[/TD]
                           			[TD]1.0.250[/TD]
                           			[TD]ETS[/TD]
                           			[TD]6[/TD]
                           			[TD]PropertyValueResponse (S=13)[/TD]
                           			[TD] [/TD]
                           			[TD]ObjectIndex=4, PropertyId=27, Count=1, StartIndex=1, Data=00 00 0F 84 00 FF 56 3E[/TD]
                           		[/TR]
                           	 [/TABLE]
                          wie auch nach der Programmierung
                          Code:
                           [TABLE]
                           	 		[TR]
                           			[TD]#[/TD]
                           			[TD]Zeit[/TD]
                           			[TD]Dienst[/TD]
                           			[TD]Flags[/TD]
                           			[TD]Prio[/TD]
                           			[TD]Quelladresse[/TD]
                           			[TD]Quellname[/TD]
                           			[TD]Zieladresse[/TD]
                           			[TD]Zielname[/TD]
                           			[TD]Rout[/TD]
                           			[TD]Typ[/TD]
                           			[TD]DPT[/TD]
                           			[TD]Info[/TD]
                           		[/TR]
                           		[TR]
                           			[TD]178[/TD]
                           			[TD]27.03.2021 14:29:22,734[/TD]
                           			[TD]vom Bus[/TD]
                           			[TD] [/TD]
                           			[TD]System[/TD]
                           			[TD]1.0.3[/TD]
                           			[TD]SCN-IP000.02 IP Interface mit Email Funktion[/TD]
                           			[TD]1.0.250[/TD]
                           			[TD]ETS[/TD]
                           			[TD]6[/TD]
                           			[TD]PropertyValueResponse (S=13)[/TD]
                           			[TD] [/TD]
                           			[TD]ObjectIndex=4, PropertyId=27, Count=1, StartIndex=1, Data=00 00 0F 84 00 FF BD C8[/TD]
                           		[/TR]
                           	 [/TABLE]
                          Mit jeweils unterschiedlichen CRC-Werten. Aber die Applikation hat nur einen Parameter-Block. Allerdings steht da irgend ein serialisierter Wert in der knxprod, den ich nicht verstehe:
                          Code:
                                      <Code>
                                        <RelativeSegment Id="M-0083_A-0133-10-8772_RS-04-00000" Offset="0" Size="3972" LoadStateMachine="4">
                                          <Data>BQAAAAAAAAAAAgEBDwAAAAAAAAAAAAAAAAAAAAAAAAAA ...</Data>
                                        </RelativeSegment>
                                      </Code>
                          Ich hab das <Data> abgekürzt, scheint der Parameterblock als Binärwert irgendwie encoded dargestellt zu sein. Ich denke, in Relation dazu werden die Deltas berechnet.

                          Für die Abfrage des Property 27 ist folgender Teil der knxprod verantwortlich:
                          Code:
                                        <LoadProcedure MergeId="7">
                                          <LdCtrlLoadImageProp ObjIdx="1" PropId="27" />
                                          <LdCtrlLoadImageProp ObjIdx="2" PropId="27" />
                                          <LdCtrlLoadImageProp ObjIdx="3" PropId="27" />
                                          <LdCtrlLoadImageProp ObjIdx="4" PropId="27" />
                                        </LoadProcedure>
                          und für das unterschiedliche Handling für komplette Programmierung und partielle Programmierung der Teil:
                          Code:
                                        <LoadProcedure MergeId="2">
                                          <LdCtrlRelSegment LsmIdx="4" Size="3972" Mode="1" Fill="0" AppliesTo="full" />
                                          <LdCtrlRelSegment LsmIdx="4" Size="3972" Mode="0" Fill="0" AppliesTo="par" />
                                        </LoadProcedure>
                                        <LoadProcedure MergeId="4">
                                          <LdCtrlWriteRelMem ObjIdx="4" Offset="0" Size="3972" Verify="true" AppliesTo="full,par" />
                                        </LoadProcedure>
                          Warum ich mir da so sicher bin: Ich habe beide Teile in meine knxprod eingebaut (natürlich mit der korrekten Size) und prompt bei Programmieren die Fehlermeldung bekommen, dass versucht wird, auf einen geschützten Speicherbereich zuzugreifen, unmittelbar nach dem Versuch, PID 27 zu lesen. Dann habe ich nur die Einträge für LoadProcedure mit MergeId 7 entfernt und MergeId 2 und 4 so gelassen und schon hat die ETS beim kompletten Programmieren (Applikationsprogramm übertragen) den gesamten Parameterblock übertragen, beim partiellen aber nur ein Delta. Das ich aber kein Data-Tag im RelativeSegment bei mir habe, wurde das Delta scheinbar relativ zu einem Parameter-Block voller Nullen (0x00) gebildet. Zumindest sieht es so aus, als ob nur Parameter != 0 übertragen werden.
                          Das geht schon wesentlich schneller (17 Sekunden statt 38), ich bin mir nur nicht sicher, ob das alles korrekt funktioniert. Vor allem muss ich testen, ob ein Parameter, den ich setze und später zurücknehme (also auf 0x00 setze), dann noch mit der 0x00 übertragen wird.

                          Bevor ich den Thread jetzt hier zumülle: Kann sonst noch jemand was mit den Erkenntnissen anfangen? Ich kann auch komplette ETS-Gruppenmonitor-Aufzeichnungen liefern, aber das muss man auch verstehen können. Ich verstehe zwar nach und nach immer mehr, aber sicherlich noch nicht genug. Und ich weiß immer noch nicht, was ich daraus ableiten kann, um eventuell fehlende Teile im Stack zu implementieren.

                          Deswegen hier erstmal Schluß für heute,
                          Gruß, Waldemar
                          OpenKNX www.openknx.de

                          Kommentar


                            Hallo Waldemar,

                            Ich lese das was du rausgefunden hast mit großer Begeisterung ^^
                            Wäre natürlich auch für mich interessant, dass in meine Kaenx einzubauen, damit die Ladezeiten verkürzt werden können. (Momentan hab ich auch noch keinen Support für das Extended Frame...)
                            Vll könnte man das auch in eine separaten Threas auslagern?
                            Hab auch nen MDT IP Schnittstelle und schaue mir das in den Ferien auch mal an.

                            Gruß Mike
                            OpenKNX www.openknx.de | Kaenx-Creator | Dali-GW

                            Kommentar


                              thewhobox: Guter Vorschlag, hab meine Findings in diesen Beitrag ausgelagert: https://knx-user-forum.de/forum/%C3%...-programmieren

                              Gruß, Waldemar
                              OpenKNX www.openknx.de

                              Kommentar


                                Zitat von Weltenbummler Beitrag anzeigen
                                Arbeitet eigentlich jemand hier mit einem ESP32 und WIFI, also IP? Ich hatte die Demo nach zahlreichen Versuchen irgendwann mal am Laufen. Dann habe ich darauf aufbauend für meine Applikation die knxprod mit weiteren Parametern und KOs angepasst. Soweit so gut.

                                Beim Programmieren aus der ETS5 habe ich jetzt folgendes Verhalten: Nur physikalische Adresse funktioniert. Wenn ich anschließend das Applikationsprogramm laden möchte, kommt keine Antwort vom ESP32, ETS bricht mit Timeouts ab. Programmiere ich phys. Addresse und Applikationsprogramm läuft alles fehlerfrei durch. Beim anschließenden Neustart kommt vom ESP32 ein abort() beim Initialisieren der Groupobjects. Ich konnte herausfinden, dass die Variable goCount auf FFFF steht. Dafür reicht der RAM natürlich nicht, daher der abort(). Ich habe in meiner knxprod nur 3 KOs drin. Der Bereich, der beim SAVE gespeichert wird und beim RESTORE zurückgelesen wird ist identisch. Bei mir sind das 130 Bytes. Die letzten 20 stehen allerdings auf FF.
                                Habt ihr einen Tipp für mich, wo ich bei der Fehlersuche ansetzen kann?
                                Gruß Stefan
                                Hi Stefan,

                                ich habe mit ESP32 und IP schon einige Projekte umgesetzt. Das mit dem goCount auf FFFF hatte ich schon ein paar Mal. Benutzt Du in Deinem Projekt auch knx.setSaveCallback() und knx.setRestoreCallback() für eigene Daten? Falls ja kannst Du mal meinen Fork ausprobieren: https://github.com/OutOfSync1/knx. Ich habe da nach längeren Debuggingsessions drei Änderungen am ESP32 EEPROM Verhalten eingebaut:
                                • Esp32Platform hat ein EEPROM.getDataPtr() vor dem EEPROM.commit() um das dirty Flag zu setzen. Ohne dies wird nichts gespeichert, soweit ich es sehe sollte es hier keine anderen Seiteneffekte geben.
                                • in knx_facade.h habe ich einen #define für USERDATA_SAVE_SIZE eingebaut. Dies dient dazu um schon beim Compilieren die _saveSize richtig zu setzen. Die war vorher auf 0 gesetzt und wurde glaube ich nirgendwo anders gesetzt. Der Wert sollte natürlich groß genug für alle Deine Userdaten sein.
                                • in knx_facade.h habe ich den (für Save und Restore) gemeinsamen SaveRestoreCallback in getrennte SaveCallback und RestoreCallback typedef geteilt. Der restore benutzt jetzt einen const uint8_t* buffer. Irgendwann in meinen Versuchen hatte ich gesehen dass der restore gar nicht aufgerufen wurde; das hatte irgendwas mit dem SaveRestore template zu tun wo dann nur die Basisklasse aufgerufen wurde. Ich erinnere mich nicht mehr genau dran, das ist schon vor ein paar Monaten gewesen. Aber mit dieser Änderung (und den anderen) läuft es gut, also schadet es wohl auch nicht
                                Das Ganze habe ich erst vorgestern auf die neueste Version der Library portiert, es ist daher noch nicht sehr lange getestet. Über eine Rückmeldung würde ich mich aber freuen, dann kann ich das endlich mal zu einen Pull-Request verarbeiten. Bei Fragen bitte gerne fragen!

                                Viele Grüße
                                Julius

                                Kommentar

                                Lädt...
                                X