Ankündigung

Einklappen
Keine Ankündigung bisher.

ESP8266 KNX mit ETS

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

  • mumpf
    antwortet
    Hi,

    Zitat von OutOfSync Beitrag anzeigen
    Vielleicht reden wir aber auch aneinander vorbei...
    ich glaub schon, dass das die richtige Ecke ist. Dynamisch von der ETS vergeben... das kann natürlich sein. Ich muss nochmal die Kommunikation verifizieren, ich hab nie eine Längenangabe gesehen, aber auch nicht speziell drauf geachtet.

    Ich wollte eigentlich feste Speicherbereiche, damit partiell programmieren immer klappt (und weil ich mit festem Speicherbereich auch besser testen kann). Ich werde mich über Ostern mal durch die Programmierung durchdebuggen und hoffentlich neue Erkenntnisse gewinnen.

    Die von Dir erwähnten Stellen schaue ich mir nochmal an, aber ich glaube, da war ich schon überall mal.... Bin aber immer davon ausgegangen, dass die Größe (oder zumindest eine Initiale Größe) irgendwo angegeben sein muss.

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • OutOfSync
    antwortet
    Hi Waldemar,

    ok, ich verstehe was Du meinst. Ich dachte das wird dynamisch nach dem Programmieren mit der ETS alloziert je nach benötigter Größe (letztendlich TableObject::allocTable) und mit TableObject::initializeProperties initialisiert. Ich hatte die MaxEntries beider Tabellen in der knxprod von 256 auf 512 hochgesetzt und konnte dann einfach ohne irgendeine Änderung am Stack (nach ETS Neuprogrammierung) damit arbeiten. Die Länge der Tabelle wird im Index 0 abgelegt (AddressTableObject::entryCount). Ich erinnere mich nicht dass da ein Wert im Stack hartkodiert wäre. Die Lage der Tabellen im EEPROM wird von der Speicherverwaltung verwaltet, daher ist nach Änderung der Tabellengröße auch eine Neuprogrammierung der physikalischen Adresse/Applikationprogramm nötig damit die Blöcke an der richtigen Position gefunden werden. Die Größe wird in den Metadaten bei TableObject::saveSize() berechnet. Das ist aber alles aus dem Kopf raus geschrieben. Vielleicht reden wir aber auch aneinander vorbei...

    Gruß, Julius

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi Julius,

    danke, aber die Info in der knxprod ist für die ETS. Aber irgendwo muss auch in der Firmware, also in dem knx-Stack, auch hinterlegt sein, wie groß die beiden Tabellen sind. Ich habe z.B. rund 450 KO, brauche also 2 Byte um diese zu adressieren. Und wenn ich mehr als 255 GA haben will, muss diese auch mit 2 Byte adressiert werden. Wenn meine Tabellen aber nur 256 Byte auseinander liegen, dann passen da nur 128 Objekte rein, das ist schlecht. Deswegen suche ich die Stelle im Coding, wo ich das neu setzen kann, ich finde die nur nicht.

    Es geht also um den Stack, nicht um die knxprod.

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • OutOfSync
    antwortet
    Zitat von mumpf Beitrag anzeigen
    Hi,

    weiß jemand, wo im Stack die initiale Größe für das address_table_object und das association_table_object gesetzt wird? Ich hab mir gestern den Wolf gesucht, aber nichts gefunden!

    Aus den Antworten an die ETS (PID_TABLE_REFERENCE) mit 0x0117 und 0x0217 sehe ich, dass die 0x100, also 256 Byte groß sind, aber ich will die auf 2048, also 0x800 setzen. Über einen Tipp würde ich mich freuen.

    Gruß, Waldemar
    Hi Waldemar,

    wird die nicht im knxprod im "applicationprogramm.xml" definiert und dann beim Hochladen genutzt? In meinen Projekten steht da z.B.

    Code:
    <AddressTable MaxEntries="255" />
    <AssociationTable MaxEntries="255" />
    Gruß, Julius

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi,

    weiß jemand, wo im Stack die initiale Größe für das address_table_object und das association_table_object gesetzt wird? Ich hab mir gestern den Wolf gesucht, aber nichts gefunden!

    Aus den Antworten an die ETS (PID_TABLE_REFERENCE) mit 0x0117 und 0x0217 sehe ich, dass die 0x100, also 256 Byte groß sind, aber ich will die auf 2048, also 0x800 setzen. Über einen Tipp würde ich mich freuen.

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • OutOfSync
    antwortet
    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

    Einen Kommentar schreiben:


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

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • thewhobox
    antwortet
    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

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    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

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    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

    Einen Kommentar schreiben:


  • Ing-Dom
    antwortet
    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 ?

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    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


    Einen Kommentar schreiben:


  • mumpf
    antwortet
    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

    Einen Kommentar schreiben:


  • thesing
    antwortet
    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.

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    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

    Einen Kommentar schreiben:

Lädt...
X