Hallo gibt es jemand im Forum der das schon mal für einen Controller auf 32bit Basis oder weniger realisiert hat ? Das Prinzip wie die Geräte im Baum gesucht werden habe ich verstanden nur bei der Umsetzung gibt es Probleme. Beim teilen der Range und das suchen im oben und unteren Teil. Hinzu kommt die Problematik das im Framework keine 64bit Typen unterstützt werden. In der limit.h werden daraus wieder 32bit Typen. Keine Ahnung warum das Atmel so macht. Also muss ich die 48bit UID in mehren schritten dividieren und addieren inkl. Überlauf prüfen etc. Das dumme ist nur das dann kein Schwein mehr durchschaut was da eigentlich passiert. Zumal man ohne dummy Devices das ganze recht schwierig testen kann. Da sich der Baum mit einen Gerät sofort auflöst. -> also das eine wird immer gefunden ;). Jemand hier den man mal zum Erfahrungsaustausch kontaktieren könnte.
Welcher C Compiler auf welcher Plattform? GCC sollte auf dem meisten 32-Bit Plattformen das "unsigned long long" als 64 Bit Typ kennen.
das dachte ich auch. Wenn man long long -> uint64_t benutzen möchte kommt eine Warnung. Probiert man es trotzdem merkt man das sie als 32bit Type behandelt werden. Keine Ahnung ewt. liegt das am SAM3x warum Atmel den Support deaktiviert hat. gcc-arm-none-eabi-4.9.3 benutzt das Atmel Framework. Ich habe es jetzt mit einen struct umschifft ;)
1 | typedef struct my64bit{ |
2 | |
3 | uint8_t word0; |
4 | uint8_t word1; |
5 | uint8_t word2; |
6 | uint8_t word3; |
7 | uint8_t word4; |
8 | uint8_t word5; |
9 | uint8_t word6; |
10 | uint8_t word7; |
11 | |
12 | }my64bit_t; |
Addieren mit der üblichen Art in einen uinit16_t und diesen dann auf Überlauf testen und das bei nächsten word berücksichtigen.
:
Bearbeitet durch User
So es ist vollbracht. Es funktioniert. Wenn man den Teil das Programms manipuliert so das die Discovery Antwort ungültig ist wird der Baum so lange durchsucht bis nur noch das vorhanden Devices übrigbleibt. Also upper=lower -> devices UID. Das sagt mir das der Algorithmus funktioniert. Sonst würde das Unendlich hin und her gehen. Nun muss ich mal ein paar devices Basteln und schauen ob wirklich funktioniert ;) .
Den Beweis damit es funktioniert bin ich noch schuldig. Bitte schön. Ich habe es mit einigen UID aus der range probiert. Sie werden gefunden. Hier hängen 3 Geräte am Bus. Zwei mit meinen rdmSlave Stack. Der noch nun dummen Fehler hatte ;)
Hallo, ich habe das discovery nun vollständig verstanden und bin auf auf einen dummen Fehler gestoßen der auch bei den vorhanden RDM Projekten (außer OLA) so mit eingebaut wurde. Dies führt dazu das die Geräte nicht gefunden werden so bald zwei mit dem selben BUG am Bus hängen und sich die Geräteadresse nur um geringe stellen unterscheiden. Das Problem ist das viele die UID mit solchen Konstrukten auswerten.
1 | for(int i=0;i<6;i++)if(lowerUID[i]<=deviceUID[i]{ |
2 | valid=true; |
3 | break; |
4 | }
|
Das Problem ist das jede 16bit breite manufacturer ID seinen eignen 32bit großen Adressraum besitzt. Die UID setzt sich wie folgt zusammen manufacturer_ID:device_ID. Das plumpe prüfen nach der oberen Art führt dazu das beim Discovery nach der manufacturer IDs Geräte nicht mehr Antworten wenn sie eigentlich sollten. Der Controller durchsucht den Bereich dann nicht mehr, die folge die Geräte werden nicht gefunden. Man muss zuerst die manufacturer ID auf Gleichheit prüfen und dann die device_ID ob die in der Range ist. Ist die manufacturer ID nicht gleich prüft man ob diese in der Range ist. Das betrachten der 48bit breiten UID mit der Gewichtung der Zahl führt zu dem Problem. Nur die Gleichheit lässt sich so prüfen.
So wieder ein Stück weiter. Der Quick Mode funktioniert. Im Quick Mode wird geprüft ob die Geräte aus der UID Liste noch vorhanden sind. Hierzu sendet man ein Mute packet an das Gerät. Antwortet es ist es vorhandene wenn nicht löscht man das aus der Liste. Ist keine Liste vorhanden wird zuerst ein full discovery ausgelöst und danach der Quick mode. Wird die liste gelöscht weil keine Geräte mehr am Bus sind wird somit automatisch wieder ein komplettes discovery ausgelöst. Ab und zu sollte man dann doch wieder ein komplettes discovery auslösen um neue Geräte zu erkennen. Das ganze benötigt relativ viel die Heap mit verketten listen etc. Anfangs habe ich beim löschen nen Bug drin gehabt so das nach ca 4h der speicher zu lief. Eine Range wurde nicht richtig freigegeben.
So wieder ein Stück weiter. Wie man sieht lassen sich jetzt die RDM Geräte im DMX Workshop verwalten. Allerdings bin ich von den Funktionalitäten etwas enttäuscht. Die Grundsätzlichen Parameter lassen sich Verwalten mehr aber auch nicht. Außerdem fragt DMX Workshop Parameter ab die unter Support nicht aufgelistet werden -> nicht Norm gerecht. Die UID wird wie man sieht dezimal angezeigt usw... Das Abfragen der Subdevices funktioniert noch nicht da mir das Paket ArtRdmSub schleierhaft ist. Eigentlich soll es Bandbreite sparen, kurz gedacht. Das funktioniert in Richtung Workshop-> Gerät aus einen ArtRdmSub Paket werden für alle Subdevices RDM Anfragen generiert. Aber was soll ich damit anderes herum ? Wenn ich einen DMX IN habe ? Ich weiß doch nicht was der RDM Controller vor hat und kann doch nicht auf gut Glück warten bis ich alle Anfragen wieder eingesammelt habe um ein ArtRdmSub zu versenden. Zumal ich mich als Proxy neutral verhalten muss. Das ganze ist sowie so nicht unproblematisch da man ja die Antwort vom Bus abwarten muss stapeln sich die Anfragen im Fifo. Außerdem ergeben sich Problematiken beim multiplen Controllern mit einigen PIDs. So das Parameter bei dem anderen Client nicht aktualisiert werden. Wie man merkt ist das ganze nicht so wirklich zu ende gedacht.
Der sich das Paket ArtRdmSub ausgedacht hat zieht sich die Hosen mit der Kneifzange an. Ich werde diesen Blödsinn nicht Implementieren. Da: - Die Adresse fehlt auf welchen Port das ganze soll -> ich müsste die Geräte suchen auf welchen Port sie sich befinden - Die Quell UID fehlt -> ich müsste mit eigenen Anfragen -> verstößt gegen das neutralitäts- Prinzip - Funktioniert nur bei PIDs mit Parameterlänge null -> was anderes sieht man offenbar nicht vor - Das zusammenbasteln der Antworten ist schwierig bzw. aufwändig. Das ganze ist sowie Sinn frei da alle Input Gateway jegliche RDM Messages in ArtRdm Packete umsetzen.
Hmm ich werde nicht herum kommen es doch implementieren zu müssen. Da sonst zumindest mit dmx Workshop keine Subdevices unterstützt würden. Ich habe mir auch einen Weg ausgedacht die Antworten wieder herauszufischen. Das geht relativ einfach wenn man den Umstand nutzt die UID des Controllers als Quelle zu benutzen. Somit kann man die Antworten prüfen und dann nach PIDs sortieren. Allerdings ist offensichtlich im DMX Wortshop ein Bug drin. Bei der GET Anfrage per ArtRdmSub setzt Workshop den SubCount auf 512 also die maximale Anzahl an zulässigen Subdevices für ein RDM Gerät. Dadurch würden dann 512 GET RDM Messages auf dem Bus erzeugt, an Subdevices die nicht vorhanden sind, meine Geräte quittieren das mit einen negativen ACK -> E120_NR_SUB_DEVICE_OUT_OF_RANGE. Der Subcount muss der Tatsächlichen Anzahl der Subdevices aus dem DeviceInfo entsprechen und die Subdevices müssen fortlaufend sein! Sonst funktioniert das ganze nicht. Das die Subdevices fortlaufend adressiert sind ist nicht sichergestellt. Es können auch zwei Subdevice 1 u.6 vorhanden sein. Das hängt mit der Abfrage vom DeviceInfo zusammen. Ewt. setzt man deswegen das Subcount auf 512. Das ist aber ein weiterer ziemlicher Unsinn weil man somit unnötig Bus Trafic erzeugt.
So soweit alles ok. Es gibt nur ein er unlustiges Problem mit dem W5500. Es scheint so zu sein das dass ARP Table pro Socket immer nur eine MAC Speichern kann. Sendet man nun Pakete zu einer anderen IP kommt es zu einer ARP Anfrage die das versenden erheblich verzögert und auch den Socket blockiert. So ein Schei... aber es ist eben Hardware mit begrenzen Speicher, in so weit schon verständlich. Jetzt muss ich die MAC der Anfrage auslesen und beim senden in das Entsprechende Register vom W5500 schreiben. Sonst blockiert mir die Geschichte die Artnet Ausgabe. Man könnte auch einen zweiten Socket aufmachen, Das Problem ist löst es nicht denn wenn einer der beiden Sockets frei ist landen die Daten in einen von diesen. Es sei denn man benutzt einen anderen Port.
Die Sache ist Käse, da sich die MAC nicht so einfach aus einen angekommen Paket extrahieren lässt. Im IP Header ist sie ja nicht mehr enthalten. Irrend wie scheint da jemand etwas vergessen zu haben? Das einzige was geht ist etwas an die IP senden auf irrend einen Port und das setSn_DHAR() auslesen. Alternativ per Broadcast senden, ARP selbst implementieren.
:
Bearbeitet durch User
So ich habe das Thema umschifft, in dem ich beim versenden von UDP Paketen man eigenes ARP Table aufbaue. Um nicht den kompletten ARP Stack zu implementieren habe ich in die Trickkiste gegriffen ;) Also Beim senden von UDP Pakten wird erst in Table geschaut ob die MAC zu der IP vorhanden ist. Ist das nicht der Fall wird das senden wie sonst auch mit "setSn_CR(sn,Sn_CR_SEND);" angestoßen. Das hat zu folge das der Wiznet ein ARP Anfrage generiert um an die MAC zu kommen muss ich noch dem versenden die MAC Adresse auslesen und in mein Table Speichen. Beim zweiten mal ist die MAC vorhanden und das Paket wird mit "setSn_CR(sn,Sn_CR_SEND_MAC);" gesendet -> ohne ARP anfrage durch den Wiznet. Die ARP Trafic hat sich somit minimiert :).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.