Bin gerade dabei eine gute Lösung zu finden, um Data Hazards in einer CPU zu vermeiden. Also wenn aufeinanderfolgende Maschinenbefehle das gleiche Register verwenden. Dann muss die 2. Instruktion ja warten, bis das Ergebnis der 1. Instruktion wieder in das Register geschrieben wurde. Alles nicht so einfach...
Heute so gecodet...
- syshack
- Thread is Unresolved
-
-
Alles nicht so einfach...
DB kann alles.
-
Leider war mein HID/Xinput-Drama mit den letzten Änderungen noch nicht vorbei.
Kurz nach den letzten Änderungen habe ich festgestellt, daß der 8BitDo Arcade Stick zwar über das 2.4GHz-Dongle funktioniert, aber nicht mit direkter USB-Verbindung.
Die unter Windows für diese beiden Modi gemeldeten Deskriptoren sind ähnlich, aber nicht vollkommen gleich.
Ich bin relativ schnell darauf gekommen, daß die Länge ("wDescriptorLength") dieses Deskriptors der Kern des Problems ist, aber ich habe zunächst nicht verstanden, was da genau passiert:
Aber ich konnte beim Debuggen sehen, daß im linken Fall (2.5GHz Dongle) mit der Länge von 788 Bytes ein Deskriptor eingelesen und vom Parser analysiert wurde, während die 20 Bytes im rechten Fall zu einem Abbruch des Parsers und fehlenden Informationen geführt haben.
Das Debugging war leider einigermaßen scheußlich und eigentlich debugge ich beruflich oft und gerne. Ich habe in den letzten drei Wochen immer mal wieder kurz in das Thema reingeschaut, aber schnell wieder aufgegeben, weil man das einfach fast gar nicht debuggen kann. Sobald man einen Breakpoint erreicht, gibt es Timeouts und die Zustandsmaschine des USB-Stacks und/oder der USB-Hardware sorgt dafür, daß man dann nicht weiter debuggen kann. Und der ganze USB-Stack ist eine Indirektionswüste und enthält tonnenweise Quellcode, der nicht kompiliert oder nie erreicht wird.
Wie auch immer: letzten Wochenende oder so hatte ich trotz Covid einen Erkenntnisgewinn, der aber nicht sofort zu einem Erfolg geführt hat. Trotzdem war das der Durchbruch.
Ein normaler HID-Descriptor sieht so aus:
CodeAber ein Xinput "XID"-Descriptor hat dieses Format:
Die angeblich 37 Deskriptoren (bNumDescriptors = 0x25) haben also nie existiert. Stattdessen ist die 0x25 ein "bSubtype", der nicht weiter verwendet wird. Und "bDescriptorType = 0x81" des ersten Unter-Deskriptors war in Wirklichkeit die Länge bMaxInputReportSize. Das war eine wichtige Erkenntnis. Die Deskriptoren in den beiden Modi unterscheiden sich also an dieser Stelle gar nicht. Beide melden eine Größe von 129 Bytes.
Ich habe also im "XInput"-Modus den Deskriptor entsprechend anders ausgewertet und als Größe der Daten für den Deskriptor den Wert 129 aus bMaxInputReportSize benutzt. Das hat allerdings zunächst keine Verbesserung gebracht. Extrem langwieriges Debugging hat gezeigt, daß es im kabelgebundenen USB-Modus beim anschließenden Auslesen des Deskriptors zu einem "USB Stall" kam. Die Anzahl der übertragenen Daten wurde im kabelgebundenen Fall mit 0 zurückgegeben. Im 2.4GHz-Dongle-Modus wurden dagegen 120 Bytes ohne "Stall" empfangen. Ich bin deshalb zunächst davon ausgegangen, daß die Datenübertragung im kabelgebundenen Modus wirklich gar nicht funktioniert, bis ich irgendwann festgestellt habe, daß im Fall des USB-Stalls der allozierte Speicherbereich doch teilweise überschrieben wird.
Ich hatte dann testweise die Anzahl der empfangenen Bytes auf 120 gepatcht, wenn sie 0 waren und damit und mit andere Hacks (Ignorieren des Stalls usw.) konnte ich den Arcadestick auch im kabelgebundenen Modus erkennen.
Das war mein Status vor dem (sehr späten) heutigen Mittagessen. Vorhin hat es mich dann aber noch einmal gepackt, weil ich verstehen wollte, warum 0 empfangene Bytes gemeldet werden. Ich habe dann irgendwann die Stelle in einem USB-Callback gefunden, in der der Stall detektiert wird. Weil es so aussah, als würde die empfangene Größe nur im Erfolgsfall in die Transferstruktur zurückgeschrieben, habe ich dort eine Zeile nachgerüstet, die das auch im Fall eines Stalls macht. Damit konnte ich endlich sehen, daß tatsächlich auch im kabelgebundenen Modus genau 120 Bytes empfangen wurde. Also genau die gleiche Anzahl wie im 2.4GHz-Modus.
Ich habe also mal versucht, die Anzahl der Daten im 9 Bytes von 129 auf 120 Bytes zu reduzieren und tatsächlich hat das für den kabelgebundenen Modus den Stall verhindert und für den 2.4GHz-Modus nicht verändert. Meine endgültige Lösung für den verbesserten Xinput-Hack ist damit diese hier:
Code- if (ux_host_class_xinput != 1U) {
- _ux_utility_descriptor_parse(descriptor, _ux_system_hid_descriptor_structure, UX_HID_DESCRIPTOR_ENTRIES, (UCHAR *)&hid->ux_host_class_hid_descriptor);
- } else {
- // hack for XID descriptor
- hid->ux_host_class_hid_descriptor.bNumDescriptor = 1;
- hid->ux_host_class_hid_descriptor.bLength = *descriptor;
- hid->ux_host_class_hid_descriptor.bDescriptorType = *(++descriptor);
- hid->ux_host_class_hid_descriptor.bcdHID = *(uint16_t*)(++descriptor);
- descriptor++; // since bcdHID is 16bit
- hid->ux_host_class_hid_descriptor.bCountryCode = *(++descriptor); // actually bType
- descriptor++; // ignore the subtype
- hid->ux_host_class_hid_descriptor.wItemLength = *(++descriptor) - 9; // bMaxInputReportSize
- // ignore bMaxOutputReportSize and the rest for the moment
- }
Die Subtraktion von 9 ist zugegebenermaßen empirisch bestimmt. Allerdings ist 9 auch die Größe eines normalen HID-Deskriptor-Headers. Mangels Dokumentation zum Xinput-Format kann ich das nicht abschließend klären. Für den Augenblick funktioniert es aber.
Was ich allerdings überhaupt nicht erklären kann, ist das völlig unterschiedliche Verhalten des Arcadesticks in den beiden Modi, wenn der gleiche Deskriptor mit der gleichen Länge angefordert wird. Im 2.4GHz-Modus scheint es egal zu sein, wieviele Bytes (>120) man anfordert. Man bekommt immer brav 120 Bytes geliefert. Dagegen gibt es unter völlig identischen Bedingungen im kabelgebundenen Modus einen Stall, wenn man auch nur ein Byte mehr als 120 anfordert.
Das ist schon ziemlich schrullig. Man hat den Eindruck, als ob in dem anderen Modus nicht bloß ein anderer Deskriptor benutzt wird, sondern auf eine komplett andere USB-Implementierung von einem anderen Team umgeschaltet wird.
Aber auch das werde ich wohl nie klären können.Wie auch immer: nach unendlich quälenden drei Wochen, in denen ich das Thema immer wieder vor mir hergeschoben habe, habe ich jetzt zumindest einen erträglichen Workaround, der für die beiden "XInput"-Modi des 8BitDo Arcade Sticks funktioniert. Es würde mich allerdings nicht vollständig überraschen, wenn andere Geräte von 8BitDo o.ä., die sich mit der gleichen PID/VID melden, aber andere Implementierungsmacken haben, immer noch nicht erkannt werden.
Aber das ist mir im für den Augenblick jetzt erst einmal egal. -
Nach dem Motto: "Compilieren ist ein bisschen wie coden" und da es in "Heute so gebastelt..." noch weniger passt.
Gestern kam mein EF3 von felixw an. Da brauche ich natürlich erstmal die PC-seitigen Tools. Also...
OK.. irgendwas fehlt ja immer...
Ach ja USB...
Und weil das README nicht mehr README heisst, sondern README.md konnte der Tar-Ball nicht gepackt werden. OK.
Dann...
Out of the Box! Strike! Danke skoe
-
Nach dem Motto: "Compilieren ist ein bisschen wie coden" und da es in "Heute so gebastelt..." noch weniger passt.
Passt bei Coden aber auch hier https://www.forum64.de/index.p…8-heute-so-compiliert%2F=
-
"O'zapft is!" ... wird ein Solar-Datenlogger für den Raspberry Zero 2 W mit Hilfe von PHP und diesem Script: https://github.com/turbopixel/deye-inverter-status . Auf die Speicherkarte kommen dann Apache, mariaDB, PHPmydAdmin, php8.3 und der restliche Kram aus dem git. Die Verbindung geht direkt an den Access-Point eines Deye-Inverter und per CronJob wird dann in eine mySQL-Tabelle geschrieben. Sehr wahrscheinlich im 10 Minuten-Intervall, weil das sowieso ein eher träges System ist.
Der Datenlogger läuft, habe nur noch keinen Raspberry Zero da. Danach mache ich mir dann Gedanken, wie man die gesammelten Daten visualisiert.
Peak waren es heute 691 Watt. Bin schon auf einen ganzen Tag gespannt.
-
Fehler in der WriteBack Stage meines RiscV64 Prozessors entfernt und nun läuft erstmals das C Programm durch, welches die LEDs meines de0 nano FPGA Boards blinken lässt.
-
Endlich mal (viel zu spät) ein Tool begonnen, welches ein hex File nimmt (mit denen füttere ich meine CPU zum Testen), und das File zeilenweise ausgibt, für jede Zeile den PC anzeigt und auch gleich den Hex-Wert disassembliert. Das sollte mein Debuggen deutlich beschleunigen. Hab alles in ganz einfachem C geschrieben, mit der Intention, das später mal in einem ROM zu packen und mit der CPU selbst auszuführen. Also die CPU quasi mit der CPU debuggen. So sieht das jetzt aus:
-
Neue Rechenspielereien. Diesmal nicht mit verschachtelten For-Schleifen und Prozessen, sondern nur mit einer ParalelFor. CPU ist zu 98% ausgelastet. Interessant dabei ist, das der TaskManager die einzelnen Rechenzeiten zusammenrechnet. Obwohl das Programm gerade 1-2 Minuten läuft, steht da schon eine CPU- Zeit von >1h.
-
Was immer interessant ist, ist die brute-force Variante für die Gleichung
T I E R
+ B A U M
= L E B E N
Auf dem 6510 habe ich es noch nicht laufen lassen, aber auf dem Z80 unter Turbo Pascal. Ich habe nicht alle Schleifen implementiert, weil ich nicht vor hatte, dass der Rechner tagelang läuft
Wenn ich mich recht erinnere, war ab 6 Schleifen schon wahnsinnige Laufzeiten. Ob man da ein parallel.for unter VB irgendwie sinnvoll einsetzen kann, habe ich noch nie probiert.
-
Wenn Du diese Meldung beim Debuggen wegbekommst, dann sollte es funktionieren.
Assistent für verwaltetes Debuggen "ContextSwitchDeadlock"
Die CLR konnte 60 Sekunden lang keinen Übergang vom COM-Kontext 0xb5d92550 zum COM-Kontext 0xb5d92428 durchführen. Der Thread, der Besitzer des Zielkontexts/-apartments ist, wartet entweder, ohne Meldungen zu verschieben, oder verarbeitet eine äußerst lang dauernde Operation, ohne Windows-Meldungen zu verschieben. Eine solche Situation beeinträchtigt in der Regel die Leistung und kann sogar dazu führen, dass die Anwendung nicht mehr reagiert oder die Speicherauslastung immer weiter zunimmt. Zur Vermeidung dieses Problems sollten alle STA-Threads (Singlethread-Apartment) primitive Typen verwenden, die beim Warten Meldungen verschieben (z. B. CoWaitForMultipleHandles), und bei lange dauernden Operationen generell Meldungen verschieben.
Hab danach gegoogelt und diese Seite gefunden: https://mycsharp.de/forum/thre…lock-erkennen-und-umgehen
Zitat "Einfach die Exception in den VS-Einstellungen abschalten und gut ist."
Hab in den Einstellungen geschaut, aber nix dazu gefunden und frage daher schon in einem anderen Forum.
-
Wie man die abschaltet, weiiß ich auch nicht. Ich drück immer F5 und dann läufts weiter...
-
Wie man die abschaltet, weiiß ich auch nicht. Ich drück immer F5 und dann läufts weiter...
-
Einfach nur schlimm, meine alten Giga-Ass-Quältexte ...
Das Portieren ins C64-Studio-Format ist nicht so schwierig. Ich drucke den Text mithilfe von VICE als Textdatei aus, öffne ihn in Notepad++, wandle alles in Kleinschrift um, entferne die Zeilennummern, die EQUATE-Befehle und den Header, und das war's schon. Den Code selbst kann man so übernehmen.
Im Studio ändere ich dann von Hand alle relativen Sprungmarken in +/- um. Alle Labels und Variablen sind aber nur wenige Zeichen lang und stellen irgendwelche Akronyme dar, die ich mir daaamals ausgedacht hatte, aber doch heute nicht mehr weiß, was sie bedeuten sollen. Und das beste: Keine Kommentare, Beschreibungen oder Erklärungen, was das ist und was da passiert, nichts, einfach nur eine endlose Schlange von zunächst nichtssagendem Code.
Das lag aber auch daran, dass seinerzeit der Speicherplatz knapp war. Ironischerweise ist der Giga-Ass-Quellcode nach dem Portieren ins Studio nur noch halb so groß wie vorher.
Ich muss also meinen eigenen Programmcode analysieren und dahinterkommen, was der bewirkt, und kann erst dann sprechende Labels und Variablennamen einsetzen und alles kommentieren.
Ein Auszug:
-
Neue Rechenspielereien. Diesmal nicht mit verschachtelten For-Schleifen und Prozessen, sondern nur mit einer ParallelFor. CPU ist zu 98% ausgelastet. Interessant dabei ist, das der TaskManager die einzelnen Rechenzeiten zusammenrechnet. Obwohl das Programm gerade 1-2 Minuten läuft, steht da schon eine CPU- Zeit von >1h.
ParallelFor ist für die Tonne. Es wird mir wohl für immer ein Rätsel bleiben, wie man damit funktionierende Klassen Threadsicher hinbekommen soll. Mit einem SyncLock hat es nicht funktioniert. Ich probiere es jetzt wieder mit Multithreading. Bisherige Versuche scheinen zu bis auf ein "Ausnahme ausgelöst: "System.Threading.ThreadAbortException" in mscorlib.dll" zu funktionieren.
-
Ich versuche ja ein UI zu modelsim Ausgaben zu bauen, welches mir hilft meine CPU zu debuggen. So bau ich nach und nach Features ein.
Die orangenen Zeilen zeigen an, wo die CPU einen Pipeline Flush durchgeführt hat. Wer genau guckt, sieht dass es immer nach einem Sprung oder Branch ist. Da muss ich also an der Branch Prediction arbeiten.
-
Heute scheint ein guter Tag zu sein...
- Multithreading läuft
- Optimierungen bringen zusätzlichen Speed
- Endlich auch mit funktionierenden Zwischenergebnissen
- Eine höhere Geschwindigkeit, weil innerhalb der For-Schleife ein Counter rückwärts läuft und auch der mit den Zwischenergebnissen arbeiten kann
- Das Multithreading ist nun auch skalierbar. Hab mit 8 Threads angefangen, läuft. 16 auch. Und es ist Luft nach oben, weil ich eine 16-Kern CPU (32 Threads) habe.
Mal schauen wie lange dieser glückliche Moment anhalten wird. Bisher war es bei diesem Projekt in der Regel so das ich nach vielen Einzelschritten mühsam vorwärts, oft viele Schritte auf einmal wieder rückwärts gehen durfte.
Zur Feier des Tages gibts heute ne neue Flasche Nusslikör.
-
[...]
Zur Feier des Tages gibts heute ne neue Flasche Nusslikör.
So oft, wie ich davon bislang hier gelesen habe, werde ich langsam neugierig. Allerdings ist Schnappes nicht so meines und Nüsse erst Recht nicht...
-
So oft, wie ich davon bislang hier gelesen habe, werde ich langsam neugierig.
Ich auch. Und zwar ob klappen wird was ich da zusammenstümpere.
Momentan habe ich das Gefühl das ich besser voran komme, weil ich manch technische Fragen Perplexity.at stelle.
Das funktioniert nicht immer, aber manchmal bietet der dazugehörende Text das eine oder andere was bei mir zu
einer Idee führt.
-
Ich auch. Und zwar ob klappen wird was ich da zusammenstümpere.
Mit genug Nusslikör im Oberstübchen
, wirst Du da bestimmt den Eindruck haben, dass das ganz toll ist