nein, wird die nicht. D.h. entweder 2 Suites oder am besten gleich auf die neue Library version updaten. (Aus Sketch-Schreiber Perspektive sind die Änderungen minimal... byte zu int ändern...)
Ankündigung
Einklappen
Keine Ankündigung bisher.
Entwicklungsblog Beta5/Final 1.0.0
Einklappen
X
-
Bedenkt bitte, dass die Version nicht umsonst das "beta" im Namen trägt. Wie Eugen schon schrieb: Am besten dann updaten. Macht keinen/wenig Sinn Devices im haus zu haben, die noch mit einer alten Beta Version arbeiten.
Beta5 wird hoffentlich der Vorläufer zum "finalen, stabilen 1.0 Version" sein. Sprich: Wenn nach beta5 nix mehr gravierendes auffällt, wird daraus 1.0 gemacht.
Bin nebenbei wieder an der Implementierung dran. Hab so einige Bugs in der großen Code-Umstellung von beta5 behoben. Und wie es so ist: Die beste Planung hilft nix, man muss es ausprobieren: Hab leider ein kleines, konzeptionelles Problem entdeckt das ich auch noch beheben muss:
https://wiki.konnekting.de/index.php...ogramming_Mode
Schaut man sich die Grafik an gibt es zwei Wege nach unten: Mit Adresse oder ohne Adresse (also mit ProgButton) programmieren. Und im weiteren Verlauf wird dann die Property-Page vom Device gelesen um Manufacturer ID und CO. abzugleiche. Doch das erfordert eine Adresse. Wenn ich jetzt aber ohne Adresse programmiere, geht das schief. Also muss ich das Konzept ein wenig umstellen/über den Haufen werfen. Dürfte aber nix wildes sein.
Gruß
Alex
- Likes 1
Kommentar
-
So, nach einigem Umbau auf Suite-Seite, bedingt durch den SystemType und behebung von einigen kleinen Flüchtigkeitsfehlern, hab ich beide Seiten wieder soweit, dass man
a) das Device mit der Suite programmieren kann
b) das Device wieder auf Nachrichten vom Bus reagiert und entsprechend die Daten loggt.
Der Code ist nun soweit, dass er zwar mehrere GAs pro KO aufnehmen kann, aber nur die erste GA verwendet/beachtet.
Muss hier und da noch aufräumen und "hübsch" machen, dann kanns mit dem Multi-GA-Ansatz losgehen.
Stay tuned.
Eugenius
Code ist nicht eingecheckt. Muss den erst aufräumen.
- Likes 1
Kommentar
-
Lesen hier auch erfahrene C Entwickler mit?
Ich hab gerade folgendes Problem:
Ich habe eine Klasse A und eine Klasse B.
In Klasse A hat es Funktionen die ich in Klasse B brauche. Soweit kein Problem. Das was ich brauche ist aber bisher nur in A verwendet worden und ist somit "privat". Kann man "public" machen. Aber A ist die "Haupt-Klasse" der Bibliothek und alles was da "public" ist, wäre Teil der öffentlichen API. Die Funktionen die ich in B aber brauche sollen aber nicht Teil der Public-API sein.
In Java würde ich so einen Fall über "package-private" lösen: Alle Klassen aus dem selben Package (bzw. Namespace) können drauf zugreifen, Otto-Normal-User, der seinen Code in einem anderen Package liegen hat, sieht nichts davon.
Gibt's da einen einfachen Ansatz in C?
Oder muss ich das irgendwie anders umschiffen?
Kommentar
-
Ich denke ich hab erstmal eine brauchbare Lösung:
ich habe den Code den ich in B schreiben wollte nach A verlagert und das Ergebnis in eine statische "public" Variable gesteckt, die ich von B aus zugreifen kann.
Das betrifft zwar auch wieder das public-api, aber besser nur eine Variable veröffentlichen (die eh keiner benutzt), als eine Funktion in die API aufnehmen, die da nicht hingehört.
Kommentar
-
Vielen Dank nochmal an Steph . Die Sache mit "Friend" klappt prima.
Bin in der Entwicklung wieder ein Stück weiter. Ich hab den Algorithmus (binäre suche) für die Suche nach den passenden KO-Nummern zu einer eingehenden GA mittlerweile Implementiert. Dabei fällt mir gerade meine simple Hashmap auf die Füße. Mir war total entfallen dass es da ja so etwas wie Kollisionen geben kann und praktisch auch gibt. *facepalm*
Nachdem ich nun wieder weiß wie man eine HashMap "richtig" implementiert, bin ich mir nicht mehr sicher ob das eine gute Idee ist.
Aktuell würde ich sie nutzen, um zu einer Gruppenadresse schnell die interne ID zu ermitteln, um damit die passenden KOs zu suchen. Aber eine "gute Hashmap" die mit Kollisionen sauber umgehen kann erkauft man sich mit noch mehr RAM Nutzung, hat aber den Vorteil, dass man verdammt schnell von der GA auf die zugehörige ID kommt, weil man nicht groß suchen muss.
Werde das bis auf weiteres auf "ohne hashmap" umbauen. Das spart RAM (der gerade auf Nicht-SAMD Controllern immer knapp ist), geht aber etwas zu lasten der CPU Zeit, denn ich muss nun auch die GA-ID "suchen". Sprich:
1. Suche: GA als Input, GA ID als Output
2. Suche: GA ID als Input, sämtliche zugehörigen KOs als Output
(siehe auch: https://wiki.konnekting.de/index.php..._Memory_Layout)
Denke aber das ist noch schnell genug. In Tests muss sich das ganze dann erstmal beweisen. GIbt ja noch andere dinge als die einfache, "Binäre Suche" die ich momentan einsetze.
Soviel dazu. genug für heute. Stay tuned for more ...
- Alex
- Likes 2
Kommentar
-
Neuer Tag, neues Problem:
Ich hab wohl irgendwo in meiner ArrayList Implementierung ein Speicher-Problem... Und ich hab noch nicht herausgefunden warum. Aber von vorne:
Wir müssen dem KO sagen welche GA es hat. Aber nur, damit wie über das KO vom Code aus ein Telegramm senden können. Aufruf im Stil von
Code:Knx.write(1, state);
Ein Sendendes KO kann aber nur eine GA haben. Das ist bei offiziellen Geräten auch so. Sonst müssten X Telegramme gesendet werden, an jede GA eines. Ist aber irgendwie "verboten". Also nur ein KO. an dieser Stelle.
Bisher hab ich in Beta5 hier eine ArrayList eingesetzt. Jedes KO hat eine. Beim Start wird im EEPROM geschaut welche GAs das KO hat und die GAs Stück für Stück in die ArrayList geschrieben.
Kurz zur ArrayList:
Die ArrayList ist im Prinzip ein festes Array das "wachsen" kann. Am Anfang ist dieses noch 0 Einträge groß und braucht keinen Speicher. Mit dem ersten Eintrag wird das Array in der ArrayList mit Größe 1 allokiert (=Speicher im RAM dafür reserviert). Mit dem zweiten Eintrag wird ein neues Array angelegt mit Größe 2, alles wird vom alten Array in das neue umkopiert, und das alte Array wird weggeräumt (Speicher wird wieder freigegeben). Das wiederholt sich mit jedem weiteren Eintrag: Neu allokieren, umkopieren, altes freigeben.
Im Prinzip kann das den RAM Speicher "fragmentieren". Ich geh jetzt nicht darauf ein WAS das ist, könnt ihr googlen. Wer aber schon mal eine Festplatte "defragmentiert" hat müsste sich ein Bild machen können.
Nun ja. Aus dem Gesichtspunkt dass ein Sendendes KO nur eine GA haben kann, ist es quatsch dem KO eine ArrayLilst mit GAs zu verpassen. Es reicht eine GA und damit braucht man keine ArrayList (mal davon abgesehen dass ich im EEPROM schauen könnte wieviele GAs für das KO da sind und das ganze einmalig allokieren könnte statt ein dynamisch wachsendes Array zu verwenden, aber das ist eine andere Geschichte).
Anderer Fall: Empfang von Daten vom Bus.
Da fragen wir aber eigentlich nicht alle KOs nach ihrer GA, sondern wir schauen welche "ID" die GA hat die da rein kommt (https://wiki.konnekting.de/index.php..._Memory_Layout). Gibt es in unserer Address-Tabelle diese GA nicht, hat auch kein KO so eine ID. Also interessiert uns diese GA folglich nicht.
Gibt es aber diese ID, wird in der "Association Table" geschaut welche KOs diese GA-ID haben. Hier kann es also 1 bis n Treffer geben. Eben weil eine GA mehrere KOs adressieren kann.
Hier kommt aktuell auch die ArrayList zum Einsatz.
Zurück zu meinem Problem mit der Arraylist und dem Speicher:
Der Arduino hängt sich aktuell nach ein paar Programmier-Telegrammen auf. Und zwar an dem Punkt, wo die ArrayList gerade aufgeräumt wird. Ich glaube zwar fast nicht dass nach so wenig Telegrammen bei einem 32kilobyte großen RAM Speicher des SAMD der Speicher schon fragmentiert ist und es hier nun Probleme gibt.... ABER ich stelle mir gerade die Frage: Kommen wir auch ohne ArrayList aus?
Wenn wir einfach definieren würden, wieviele KOs die gleiche GA haben dürfen, könnte ich einfach ein fixes Array anlegen, welches ich NIE aufräumen und neu allokieren müsste. Das würde einer Fragmentierung definitiv positiv entgegen wirken.
Aber eigentlich will ich nicht noch eine Limitierung einführen die es bei KNX sonst nicht gibt, und hier einfach mal ein Array mit 100 anlegen verschwendet auch Speicher.
Deshalb die Frage in die Runde:
* Kennt jemand ein offizielles Limit in dieser Richtung, welches wir übernehmen könnten?
* Was meint ihr: Wie viele KOs sollten maximal die gleiche Adresse bekommen?
* Kennt sich jemand mit Heap-Fragmentierung auf Microcontrollern aus?
Gruß
Alex
Kommentar
-
Ideen die mir gerade durch den Kopf gehen:
Statisches Array, aber die Größe wird festgemacht an:
* Wie viele KOs gibt es überhaupt in diesem Sketch? Das Array hat dann maximal diese Größe. Und für den Worst-Case muss der Speicher im RAM ja auch vorhanden sein. Ob ich das jetzt also dynamisch reserviere, oder statisch ist egal. Ich brauche den Speicher. Basta.
* Wenn ich 123 KOs habe, müssen ja nicht alle 123 KOs die selbe GA haben. Man könnte die Größe weiter einschränken, wenn man beim Sketch-Start in der Lib einfach schaut, wie viele KOs maximal die gleiche GA haben und das dann als Maximum für die statische Array-größe hernehmen.
Ich muss zwar immer noch malloc() benutzen um den Speicher zur Laufzeit zu reservieren, aber ich muss den nicht mehr freigeben. Ich brauch ihn ja eh wieder beim nächsten Telegrammempfang, im worst-case.
Andere Ideen?
Kommentar
-
Ist vielleicht etwas blauäugig, aber könntest du das nicht bei programmieren über die Suite schon fertig übertragen? Also quasi die ArrayListe in der Suite bauen und dann als fixes Array übertragen? Weil wenn es mal programmiert ist ändert es sich ja auf dem Device nicht mehr von selbst...Gruß
Michael
Kommentar
-
Das mache ich ja schon so. Aber wenn es darum geht eingehende Telegramme auszuwerten und zu schauen welche KOs nun betroffenen sind, dann ist das situationsabhängig. Bei der einen GA wird kein KO angesprochen, bei der nächsten nur eins, beim nächsten vielleicht drei... Und eben diese Liste mit angesprochenen KOs ist dynamisch. Im Normalfall wird die Liste wohl nicht größer als 5 sein. Aber mir ist kein KNX seitiges Limit bekannt. So könnte man eine GA an 256KOs zuweisen. Dann wäre die Liste 256 Einträge groß. Wird wohl keiner machen, aber [ironie] es hat ja auch noch niemand mehr als 640kbyte Arbeitsspeicher gebraucht, richtig? [/ironie]Zuletzt geändert von tuxedo; 20.09.2018, 05:40.
Kommentar
-
Keep ist simple?!
Fixes Array ist gut.
Auch ein einmalig dynamisch allokiertes ist OK. (D.h aber nach änderungen von Zuweisungen in der Suite und upload muss MC neu gestartet werden?!)
Zusätzlich ein einfaches define einführen das die Speichergröße für das Array (fix) angibt.
Wenn jemand wirklich mehr braucht muss man dann im Sketch das define setzen...
Oder du bist ein Masochist und baust dir eine Defragmentierung.....
Wenns jemand genauer interessiert. Hier ist es wirklich schön beschrieben was Fragmentierung ist.
https://www.mikrocontroller.net/arti...Fragmentierung
Kommentar
Kommentar