 Vielen Dank fürs Erscheinen. Dieser Vortrag wird über keine USB kein Problem sein und das ist der einzigste USB-Stack, der auf einem 48 Mhz AM Cortex-Prozesse läuft. Es ist relativ speziell, aber es wird oft eingesetzt. Während dieses Vortrags fertig über drei Sachen reden, warum wollte man so was machen? Warum wollte man so ein USB-Stack auf so einem Cortex-Ting laufen lassen? Der zweite Teil wird darüber sein, wie es gemacht wird. Also wie man die Code-Schnip zu anschauen, der eigentlich nutzen dieses Vortrags. Und dann werde ich noch darüber reden, wie wir weitermachen können. Was kann man mit diesem USB-Stack dann machen? Als erstes will ich über mich reden. Ich habe das erste Mal auf dem Kongress einen Vortrag gehalten über SD-Karten gehalten. Also wirklich eingebettete Chips. Da kann man nicht wirklich viel machen, um die auszulesen. Und ich habe auch auf dem Nuvina Open Source Laptop mitgearbeitet von Bunny. Und das Laptop hat dieses Batterie-Bord. Es hat seinen eigenen CPU. Und es ist auch ein Cortex-M0. Das ist derselbe wie über das wir heute reden werden. Ich möchte euch heute mitgeben, dass ihr low-level USB besser versteht. Bücher reden immer über höhere Ebene. Also was man macht, wenn Chip hat, der USB hat, was man dann machen kann. Und ich möchte heute über die tieferen Protokolle reden. Ich möchte euch noch ein paar Tricks zeigen, wie man Chips programmiert. Also das ist wirklich unterschiedlich zu normalen Programmieren. Und es hat ein paar Tricks, die ich gerne mit euch teilen würde. Und das Wichtigste, denke ich, ist zu wissen, was wichtig ist und was nicht. Also wenn euch das Protokoll hat, was dann versucht zu implementieren, dann gibt es Sachen, die wirklich wichtig sind, die man nicht falsch machen kann. Und dann gibt es eine ganz andere Abteilung, wo man sagt, dass das wichtig ist, aber wo sich dann wirklich herausstellt, dass es nicht ist. Also das sind dann Sachen, die man später lösen kann. Also warum würden wir das so tun? Also ganz einfach, weil USB echt einfach ist. Also für einen Nutzer. Es kann ein bisschen schwierig sein. Also USB ist klasse, man kann es einstecken. Man muss sich über keine Konfigurationen sorgen machen. Es gibt keine Interrupts, es funktioniert einfach. Die andere Motivation ist, dass USB überall ist. Also es gibt diesen USB-Pocketball aus irgendeinem Grund. Also alles hat USB. Also wenn irgendwas für jeden anders funktioniert, sollten wir auf jeden Fall mit USB arbeiten. Also zum Beispiel, das ist ein Fernwell, das ist, was in Handys läuft. Also das ist halt eine White Box. Also es hat einen Serialport, das auf 3,3 Volt läuft. Und es ist recht einfach, und es ist recht einfach, das Ding zu managen für eine Programmierer, da schreibt man einfach eine Variable im Rahmen, und dann schreibt es das ganz raus. Für Nutzer ist das recht schwierig, weil man muss sich ein Serialkabel suchen. Und deswegen ist das Ganze hier fortschuldig, weil man hier einfach nur ein USB-Kabel einstecken muss, und es funktioniert schon. Und dann läuft das Board schon. Es hat mich wirklich überrascht, weil ich habe ein seriales Kabel Setup, aber einfach nur USB-Seriele zu haben, hat sehr viele Leuten geholfen, da reinzukommen, weil man eben nicht diesen Mehraufwand braucht, um loszulegen. Und dann weiter zum nächsten Jahr. Bunny hat einen Board für Burning Man gemacht. In Burning Man gibt es ein paar Spezifikationen, die man erfüllen muss. Also man braucht einen Mesh-Netzwerk, was miteinander redet. Und das Ding war ein richtig cooles Projekt, und wenn man es jetzt umdreht, auf der Rückseite ist ein fetter USB-Port. Und für diesen Batch hat das Ganze als noch Batterielade-Gerät funktioniert. Also so was, wie man an einem Flughafen bekommt. Aber die CPU macht nicht wirklich USB. Es hat keinen USB-Support als Board. Und wir haben das Projekt genommen und mit dem RIT zusammengearbeitet, haben der USB-Port geändert. Und wo wir uns entschieden haben, die D-Minus- und D-Plus-Pins auf den CPU zu legen, falls ich einen mit dem Board spielen möchte. Und ich habe mich gefragt, warum wollte man so was tun. Aber ein paar Monate später. Und die wollten dann einen Spiele-Controller. Und die wollten die Pies mit einem Arcade-Stick verbinden. Und daraus ist Project Palawan entstanden. Die Frage war, ist es möglich, ein Software USB-Stack für diesen Prozesse zu schreiben? Es gibt ein paar USB-Stacks wie USB, was wirklich cool ist. Es hat sehr viele Eigenschaften, sehr beeindruckend. Aber das Problem ist, dass die Prozessearchitekturen unterschiedlich sind. Der andere, einzigste USB-Stack über eine andere USB-Stack, der auf einem läuft, ist der LAMG USB. Die haben ein kleines Problem. Also ein Problem, was ich beheben wollte. Ein Problem ist, mit Hardware ist es immer wie in einem Minenfeld. Die Dokumentation selbst, wenn man die 48 MHz hat, gibt es Sachen, die man nicht sieht, wo man auf eine Sackkasse läuft. Zum Beispiel, dass Port A einen festen Interrupt hat und Port C und D gemeinsam interrupt haben. Wenn man das genau liest, sieht man, dass Port B nicht erwähnt wird. Man merkt, man sagt, Port B hat keinen Interrupt. Aber PdB 3 und PdB 4 sind wirkliche Pull-Down-Pins. In Englisch bedeutet das, dass das praktisch nur Imports sind. Das findet man immer erst raus, wenn man das Ganze aus China, aus der Fabrik, zurückbekommt. Warum merkt man das immer erst später? Das ist das Pin-Out-Diagramm. Aber was man hier sieht, dass diese Pins mehr öfters benutzt werden können. Also zum Beispiel, der eine kann als GPIO benutzt werden oder als Debugpin. Beide der anderen USB-Stacks reservieren diese Pins als D- und D-Plus-Pins. Das macht es sehr einfach damit zu arbeiten. Aber wir wollten es haben, dass wir verschiedene D-Plus- und D-Minus-Anschlüsse haben. Ich habe gedacht, das nennt man S-Bahrer-Computer. USB ist niedriges Geschwindigkeit als 1,5 MHz. Das gibt einem 32-Klock-Cycles pro Bit. Und der CPU ist wieder ein Cortex-MEO, 48 MHz. Das ist eine 3-Stufen-Pipeline. Das ist ein Bildschirm von dem ARM-Referenz Handbuch. Und alles, was man drauf sieht, ist ein Zyklus. Alles, was man macht, ist ein Zeuglich. Und manchmal sind es 2 Zeugel. Alles in den RAM zu laden sind 2 Speicher. Und wenn wir die Nummern laufen, sah es aus, dass es möglich wäre. Und dann designen wir das Board Palawan und wir kamen zurück zur Arbeit. Und es funktioniert. Und lassen wir jetzt weitergehen, wie wir es gemacht haben. Erkranium ist der Name des Projekts. Und es hat grob diese Architektur. Und der Usercode ist HowToGetBuffers und so weiter. Und wenn du in die Code schreibst, das ist den Bereich, wo ihr deinen Code reinschreibt. Und dann gibt es den State, wo USB ein State ist. Und dann PHY. Und es handelt den PHY. Und darunter ist PHLL. Das ist die Hardware-Implementierung. Alles hier, alles mit Ausnahme von PHYLL, ist geschrieben NC. Und es, was ich jetzt mache. Und ich arbeite unter dem Jahr an und arbeite mich hoch. Um anzufangen, wir müssen uns um den Strom kümmern. Um die einfachen Kabel. Um die wirklich coolen Sachen ist, dass die Kabel standardisiert sind, wie man die verkabelt. Man findet diese 4 coolen. Rot ist 4 volts. Ground ist schwarz. Und ich vergesse immer, was was ist, weil es nicht keine Rolle spielt. Und das sind die, das Schema, was ich benutzt habe. Es ist wirklich schwer, um Patches zu machen. Man muss viel extra Zeug reintun. USB auf niedriger Geschwindigkeit, verlangt, dass man auf dem D-Pin hochzieht. Man kann auch die Plus drinnen, falls man ins Rückwärts hinbekommt. Und praktisch, wenn man hergeht und sich diesen Schallplan anguckt und das ist unnötige entfernt, sieht der Schallplan so aus. Es sieht nicht zu schwer aus, das zu funktionieren, zu bekommen. Hier sieht man dann das PCB-Board. Und wenn man jetzt das ganze, das Board, wenn es dann in den Raspberry Pi steckt, dann erkennt das USB. Es schmeißt einen Descriptor-Error. Und das bedeutet, wir haben ein Low-Speed-Device, wir haben den Pull-Up richtig gemacht. Es ist die Hardware, scheint richtig zu sein. Wenn man sich minus 32 anguckt, empfehle, das bedeutet, dass die Konfigurations-Pipeline nicht richtig ist, aber wir haben halt keinen Pipeline geschrieben, von dem macht der Fehler wirklich Sinn. Also, das ist physikalisch das elektrische. Nicht nur die Kabel, jetzt reden wir mal über die Signale. Also, was über die Kabel geschickt wird. USB hat drei Zustände. Die drei unterschiedliche Zustände kann man da sehen. Ich vertausche immer zwei Zustände, aber es ist ziemlich, ziemlich, ziemlich egal. Der Unterschied zwischen langsam und schnellem USB ist, wie schnell man zwischen den Zuständen wechselt. Es gibt keinen SE1-Zustand. Also, wo beide Zustände, wo beide Kabel auf High liegen und das ist dann einfach kurz Schluss. Und dann setzt der Host einfach zurück. Also, das heißt, man verliert die Verbindung und muss von vorne anfangen. Also, die Koding-Zustände, USB hat eigene Zyklen und die Übergänge. Also, dann wartet man immer 32-Klock-Zyklen und schaut nochmal nach. Und wenn das immer noch derselbe Zustand ist, ist es eine Null. Wenn es nach einer anderen Zustand ist, ist es eine Eins. Also, diese No Gates ist das, was es macht, aber wir haben dafür keine Standardisierung. Deswegen benutzt man dafür zwei Getrennte. Das ist nicht allzu schlimm. Und jetzt gehen wir in dem Stack ein bisschen höher. Das ist die Preamble. Das ist, wo wir vom K-Zustand zum ... vom K-Zustand zum Ihr-Zustand gehen und immer wieder hin und her wechseln, immer 32 Samples. Also, wir haben 156 Zyklen, bevor überhaupt Daten übertragen werden. Das ist verdammt viel Zeit, um das Ganze zu synchronisieren. Also, das sollte eigentlich recht einfach sein, das dann zu implementieren. Dann kann man sich die Datasektion angucken. Das sind elf Beiz, die maximal gesendet werden. Und dann gibt es das SEO-Signal, was bedeutet, wir haben das Paketende erreicht. Also, normalerweise sind die gegenüber. Aber am Ende sind sie beide auf Low. Also, es gibt da nur einen Problem, über den noch zu bedanken. Das nennt sich Bitstuffing. Die stellt sich heraus, dass die Drähte meistens nicht mögen, dass man den selben Wert immer schickt. Das bedeutet, dass die Kabel immer in dem selben Zustand sind. Und das hier ist jetzt ein Oscillator-Ausschnitt, wo man die Preamble sieht. Und dann sieht man die Einser. Und man sieht, dass 0 eingebaut worden ist. Also, was ist wichtig? Was kann man ignorieren und was müssen wir hinbekommen? Also, was hinbekommen müssen, ist die Zeit und die Sekundisation. USB hat einen eigenen Zyklus. Wenn wir das Timing falsch machen und das Zyklus hinkriegen, dann sind wir falsch. Wir müssen bei dem Bitstuffing aufpassen, dass wir das Signal nicht verfälschen. Und man muss natürlich noch seine Fehler beachten. Also, zum Beispiel Keep Alive, Pakete müssen richtig erimplimentiert werden und die Framing-Pakete auch. Nach dem, wenn zum Beispiel der Host mehr Daten schickt, müssen wir damit klarkommen. Was nicht wichtig ist, ist, dass wir 6 Bits bekommen zum synchronisieren. Das ist ewig zum synchronisieren. So viel brauchen wir nicht. Und wir müssen nur ein Kabel kontrollieren. Also, wir müssen nicht beide Kabel kontrollieren. Es reicht, wenn wir nur D plus korrigieren. Wir können einfach schauen, was das 32 Zyklin war. Das Einzige, was wir machen müssen, wenn wir beide Kabel brauchen, wenn beide niedrig sind, aber dann können wir sie einfach ratieren. Und wenn wir 3 Pakete verlieren, dann müssen wir schauen, weil der Host schickt die 3 Pakete nochmal. Also, worüber ich noch nicht geredet habe, dass er über Signal integriert hat. Da sieht man hier mal den Trace des Signalpins. Das ist normalerweise ein differenzielles Routing, wo die beiden Linien zu nahe wie möglich aneinander sind. Aber anscheinend ist er erreicht, dass hier schon. Das Mikroskop, was ich hatte, gab mir die Müche, einen Diagramm zu machen. Was einem sagt, wie nah man dran ist. Und es reicht für niedrige Geschwindigkeiten auf dem USB. Man möchte die roten Punkte vermeiden. Und selbst mit dem schlimmen Routing über das Board, funktioniert es noch überhaupt wunderbar. Das ist sogar eine Textnachricht, die ich geschickt habe, wo man sieht, wo ein Sprung ist, der am Anfang ist und der in dem Bild davor nicht war. Weil die Chips, die ich benutze auf dem Board, hatten einen unterschiedlichen Standard. Das bedeutet, wenn sich der Zustand ändert, versucht es so schnell wie möglich, runter oder hoch zu ziehen. Sobald ich es auf niedrige Gezogen habe, hat es nicht das gemacht, was es sollte, sondern das, was wir hier in dem Bild gerade sehen. In Hardware ist es schneller nicht immer besser. In diesem Fall wollen wir langsam sein, weil wenn wir langsam sind, löst es das Problem. Weil wir verschiedene D plus und D minus-Systeme haben, kommen Bits nicht an der gleichen Fälle. Da ist ein Nanosekunden-Delay. Aber das ist in Ordnung. Die Hardware-Specs kümmern sich nicht darum. USB ist ein sehr vergebendes, entschuldigendes Protokoll. Man kann ein 32,768 Kiloherz-Kristall benutzen. Das ist ein sehr häufiger Kristall. Diese Kristalle sind sehr billig. In dieser Kristalle, die wir nimmten, und die 32,768 kiloherz-Kristall multipliziert die 1.464 kiloherz-Kristall. Und man kommt mit 47 Punkten megahertz draußen. Das ist nah genug dran. Und für USB, das ist in Ordnung. Ich möchte einen Moment nehmen. Und das hier ist die Hardware und die niedrigen Levelsignal-Sachen. Und ich möchte ein bisschen über den Entwicklungsprozess reden. Oben ist das Board, wo wir USB entwickelt haben. Und am unten ist ein Raspberry Pi. Raspberry Pies sind sehr billig, wie ihr wisst. Und sie sind überall und jeder scheint einen Raspberry Pi zu haben. In diesem Fall laufen drei Kabel von dem Raspberry Pi zu dem Gerät. Und diese sind die Clock, das Debugging. Und das Board ist, kriegt einen Strom über USB. Und den Raspberry Pi läuft open OCD. Raspberry Pi kriegt man in den JTagbacken. Und das hier sind 45 Dollar. Und das hat Internet. Es arbeitet unabhängig. Und auf dem Internet, wenn man das Projekt mit jemanden teilen möchte und jemand anderes drauf wirkelt haben möchte, dann schickt man ihm einfach das Board und packt einfach den Raspberry Pi mitten das Board in das Paket rein. Und dann bekommt man die gleiche Software laufen. Und dann kann man, wenn man auf Mac OS oder Windows oder Linux installiert, dann muss man diese ganzen Sachen installieren. Und wenn man ein Raspberry Pi entwickelt, dann ist alles schon in der Box. Und dann bekommt man seine Stack Traces. Und dann ist es so einfach und so stark. Und das ist, wie man jetzt in den Wickel macht, das ist wirklich eine Veränderung. Und es funktioniert wirklich fantastisch für diese Kleinen. Und das waren ein paar Oszillatoren zu denen ich zugegen hatte, wo man dann USB damit schliessen konnte. Und hier hatte ich ein normales Board als Logical Analyse Tool, womit man Sachen analysieren kann, wo man sich nicht sich ist, dass es funktioniert. Und dann hatte ich noch ein USB-Biegel, der die Pakete zerlegen kann. Also das ist so die Reihenfolge, in der ich es benutzt habe. Zuerst der Oszillator, dann den Begel zum Entschließen des Protokolls. Und dann habe ich in der Hand noch ein Screenshot, das sieht das aus. Aber ist genug von Hardware. Und jetzt reden wir über die eigentliche RP. Also die low-level RP ist speziell eingestellt für ein 48 Cortex-Prozess eingestellt. Es gibt zwei Funktionen zum Schreiben und Lesen. Und sie halten sich an die Konvention, weil die ein i drin haben, weil die sich an einem Interrupt ausgelöst werden und sehr speziell darauf abhängen. Und man will diese Funktion eigentlich selbst niemals wirklich aufrufen. Außer man will irgendwelche Präsentationen haben. Man will stattdessen eher Granim Capture, eher aufrufen aus dem Grund. Das kümmert sich um das Send von Antworten, wenn man auf irgendwas anbauten muss, was von der Haustmaschine kommt. Dann kommen wir jetzt zum Programmiertricks, weil wir haben noch nicht viel Code geschrieben. Aber eins, was wirklich klar sein sollte, ist man will natürlich aus dem Rahmen starten, damit man diese Zyklen richtig bekommt. Also wenn man von Flash aus das ganze Läufe lässt, Flash ist nicht konsistent. Also bei uns hatten wir das Problem, dass das ganze in einem Cache hatte. Und sobald man mehr starten, lesen und schreiben will, kommt von langsam hinzu, was natürlich nicht cool ist, wenn man assembly Code im Laufen hat. Man will natürlich perfekte Zyklen, also perfekte, möglichst wie ich Zyklen habe. Und deswegen kann man einfach, man kann das ganze so schreiben und dann kann man das in den Rahmen laden. Darüber kommen wir sicherer GCC. Und es ist eigentlich sehr leicht, das ganze zum Laufen zu lassen. Und natürlich, man soll natürlich Registermittel zum Daten zu speichern. Wenn man Sachen schreibt, dann hatten wir das Problem, dass wir nicht genügend Register hatten, man hatte nur 8-14 Register, und man brauchte halt einen Extradzyklus, aber wir haben dann einen Stack-Los, weil wir mehr Daten hatten. Aber das Beste ist natürlich auch ein Register-Los, weil schneller wird es nicht. Wenn die Hardware baut, dann baut man einen Laser und einen Schreiber und dann kann die miteinander verbinden und dann kann man sie gegeneinander testen, bevor man sie überhaupt mit einem Host testet. So kann ein Paket hin und her checken. Für dieses Beispiel haben wir verschiedene Pins benutzt und es hat trotzdem funktioniert. Und jetzt reden wir über die CRP. Es hat zwei Funktionen zu verbinden und zum Trend. Das erkennt den Host und den Disconnect simuliert praktisch das Ganze auszustecken. Dann gibt es das Paket-Impfang. Das ist als Schwachdefiniert, weil man das natürlich überschreiben sollte, weil man die Funktion aufrufen sollte, um die Daten zu verarbeiten, die gerade herkamen. Und dann gibt es diese Capture Pack Funktion. Das ist dazu da, um sich um Antworten zu kümmern und solche Sachen. Und warum wir diese Capture Funktion überhaupt brauchen, ist, dass USB-Pakete 11 Bytes groß sind. Aber was diese Bytes sind, ist eigentlich schon wichtig. Jedes Paket begann mit einem 8-Bit PID. Dann kommt eine 8-Bit Sequenz, was spezifiziert, was dieses Paket ist. Also zum Beispiel ein Acknowledgement und dann folgt ein 16-Bit Abschnitt, der genau ein Datenpaket hat wie ein PD, 0 bis 8 Datenbytes und dann eine Korrektursumme. Und der Nack hat nur eine PD-Nummer. Um diese Tatsache ist, man muss wirklich schnell auf diese Pakete antworten. Man hat 6,5 Bit Zeit, um etwa Daten zu senden. Also wenn der Host nach Daten fragt, wir müssen Daten schicken, egal wie. Oder wir müssen den Nack antworten. Solange wir das nicht tun, fragt der Host nach. Und wenn wir das dreimal verpassen, dann wird die Verbindung resettet. Also wenn der Host jetzt Daten schickt, dann müssen wir natürlich Nack schicken, um zu garantieren, dass wir es bekommen haben. Ein Trick, den er dazu benutzen kann, ist, dass man dieses Ganze nicht gleichmäßig allein ist. Man sieht, dass es passt, bis auf diese eine Byte vorne. Man hängt vorne einfach ein paar Bytes an, damit es passt. Und am Ende kann man dann ein 16-Bit Chunk nehmen, um das Ganze zu verarbeiten. Und dann kann man die ganzen Bytes verarbeiten. Und deswegen ist es leichter, das Ganze als 16-Bit zu verarbeiten, anstatt das Ganze um das Ganze zu haben. Wir haben dafür einen Mikrobuffer, der sich darum kümmert. Also was ist wichtig bei den Frames? Also was wichtig ist, ist die schnelle Antwort. Also wir müssen wirklich, wirklich schnell antworten. Wenn wir nicht antworten, wird die Verbindung zurückgesetzt. Das nächste, was wichtig ist, ist die Frame Sequenz. Also wenn man natürlich Hallo sagt und darauf mit Banona antwortet, weiß man natürlich nicht, was das Nächstes kommen soll. Also man muss immer mit der richtigen Antwort antworten. Das nächste Problem ist, dass die Check Summe richtig sein muss. Wenn die falsch ist, wird die Verbindung zurückgesetzt. Und es gibt einen Data 0 und Data 1-Paket. Und die Spezifikation ist ein bisschen unklar, wenn man dazu kommt. Man muss das richtigen kriegen. Und wenn das nicht stimmt, wird wir die Verbindung zurückgesetzt. Also es gibt ein paar Sachen, die aber nicht so wichtig sind. Wir können nachsenden. Das ist, was zum Beispiel die Tastatur macht. Wenn der Computer zum Beispiel die Tastatur fragt, nach irgendwelchen Daten, dann antwortet die Tastatur einfach mit einem Neck. Dass die In-Out- und Setup-Pakete, die generieren wir nicht. Also müssen wir uns damit auch nicht um die Generation von CRC5-Nummern kommen. Wir nehmen einfach immer an, dass es richtig ist. Also wir haben 6,5 Sekunden Zeit zu antworten. Deswegen schmeißen wir das Ding einfach weg und nehmen an, dass es richtig ist. Und wir können auch die Adresse ignorieren. Wenn das Paket ankommt, nehmen wir an, das ist für uns, weil wir hoffen, dass du das richtig gemacht hast. Wenn nicht, dann halt nicht. Also jetzt, wo wir alles das haben, haben wir eine Zustandsmaschine, was den USB-Zustand bescheid. Es ist ziemlich ässlich, es kommt USB-2-Spezifikation. Das implementiert, also man soll nicht direkt dieses State-Maschine einbauen und nicht direkt implementieren. Es ist wirklich ein Haufen Schrott, aber es gibt Methoden dafür, die sich darum kümmern. Es gibt die heißen SEND-Data. Wenn man also z.B. eine Taste auf die Tastatur drückt und es als Daten auch schicken will, gibt man die Adresse an und dann in Zukunft, wenn der Computer unser Gerät nach Daten fragt, dann antworten wir mit dieser Tastatur. Und wenn wir ein Paket bekommen, geben wir das immer an die Prozessfunktion weiter. Und dann können wir das über die Zustandsmaschine abarbeiten. Von diesem Punkt weiter kommen wir zu dem User Code. Wo ihr wisst, wenn ihr schon mal USB selbst gemacht habt, das ist, was die Konfiguration selber macht. Das ist, wie man die eigentliche Applikation definiert. Das sind verschiedene Funktionen. Natürlich, weil eines meiner Themen ist, was wichtig ist und was nicht. Also noch mal. Was wichtig ist, ist, die get-to-grypte Funktion ist wichtig, weil es das Gerät beschreibt, also was für ein Gerät es ist. Also in dem Nutzercode ist das sehr wichtig. Wenn es nicht implementiert, wird es nicht funktionieren. Get-receive-buffer ist auch wichtig, weil wenn man Daten bekommen muss, dann wissen wir, wie man sie hintun. Und receive-daten ist auch wichtig, weil wenn man Daten bekommt, muss man ja auch irgendwas aufrufen. Was nicht so wichtig ist, die Set-Configuration-Nummer und das kann man im Code benutzen, wenn Fans hier Sachen machen wollen, wenn nicht, dann egal. Also damit kann man get-to-grypte Funktion beschreiben. Dann sieht man, dass es funktioniert. Hier sieht man jetzt den Beagle-Output von einem Keyboard. Es funktioniert einfach. Also an diesem Punkt kann jetzt der Computer mit unserem Gerät reden und der Prozess funktioniert. Und es fragt praktisch einfach nur nach verschiedenen Descriptern. Also nicht wirklich ins Rand an diesem Punkt. Jetzt können wir eine Moose-B-Code arbeiten, die wir als Entwickler haben wollen und die Probleme, die da auftreten. Jedes Mal, wenn man in den Debugger geht, hört der Haus auf, nackstisch schicken. Das sieht man, dass der Computer die Verbindung zurextetzt, weil wir in den Debugger gegangen sind. Also, weil das Gerät kurz tot war, weil wir in den Debugger reingegangen sind. Und der Computer hat das richtig interpretiert. Und wenn man das natürlich weiterlaufen lässt, ist es in einem Zustand, der nicht definiert ist. Wie kommt man damit rum? Global Variables sind wirklich nützlich. Also es gibt einfach eine Funktion, die wir loopen. Und da kann man dann sehen, dass es auch wirklich funktioniert. Was man an globalen Variablen schön sieht, die werden nicht wegoptimiert. Also wenn wir das Startup machen, dann könnte es wegoptimiert werden. Aber das ist nicht, was wir haben wollen bei so was. Wir wollen wissen, was los ist. Also globale Variablen sind wunderbar dafür. Ein weiterer Tipp ist, dass Debugging, dass wir Breakpoints haben, aber die sind eine begrenzte Ressource. Es gibt genau zwei Hardware Breakpoints. Zum Beispiel, wenn wir in dieser Funktion brechen, sehen wir, dass ein Breakpoint an 49 Punkte hat. Und das sieht man dann überall, wo die Funktion aufruft. Was natürlich nicht cool ist, wenn wir das Ganze laufen lassen wollen, weil es dann sagt, wir haben einen Breakpoint schon zu viel. Also wir haben einen Breakpoint gesetzt, und es hat natürlich 49 Breakpoints daraus generiert. Also können wir jetzt aus JavaScript klauen. Da ist diese Funktion, wo ich definieren kann, wie ein Debugger ... Nein, kann man diesen Debugger in deinem Code benutzen, und jedes Mal, wenn er das benutzt, dann geht es in den Debugger. Das wirkt über Optimisierung, das funktioniert in einer Funktion. Und beim Kompellieren, und das ist so ein schneller Prozess, es ist einfacher zu benutzen, denn in den Debugger mit Control C. Das ist großartig, wir haben das alles fertig. Wir haben einen USB-Stack, der funktioniert, den wir debuggen können. Was machen wir jetzt, was kann man damit tatsächlich tun? Können wir vielleicht damit eine Festplatte bauen? Nein, leider nicht. Wir können keine Art. Wir machen USB auf niedrige Geschwindigkeit, das lässt uns nur zwei Endpoints haben. Wir können Interrupt oder Control haben. Wenn man einen Hard Drive macht, mit bulk Endpoints benutzt, wird es nicht funktionieren. Es würde vielleicht funktionieren, basierend auf der peraten Betriebssysteme, aber es würde nicht die Spezifikation. Man kann auch keine Audio-Device machen. Es sind Focus Endpoints und das, was sie nicht haben wollen. Ein MIDI-Device können wir auch nicht machen. Es nutzt auch bulk und Dry Endpunkte, die können wir nicht benutzen. Man kann keine Keyboards machen. Man kann Erder machen. Man kann keine Serial-Geräte machen. Was können wir tun? Was machen wir? Das ist ein Device für Updates. Was die lokalen Leute entwickelt haben. Es ist nützlich nur für Updates. Wir können so etwas wie ein Keyboard, ein Maus oder ein Joystick bauen. Das ist alles innerhalb dieser Spezifikation. Dann gibt es noch eine Wendatefine-Klasse, wie zum Beispiel ein T-Pott. Es hat keine Klasse, aber es kann immer sein, was wir haben wollen, wie ein Zombie. Zurück zum Human- und Menscheninterface. Die kommen mit ihrem eigenen Deskriptor. Viele Buttons auf dem Keyboard sind wie viele auf dem Joystick sind. Man schließt es einfach an und funktioniert. Das andere Vorteil von USB-Hit ist, dass es kein Input ist. Man kann USB-Datenübersenden USB-Hit. Es ist auch sehr einfach in Windows. Man muss keine Treiber installieren. Es funktioniert mit dem USB-Hit Driver. Man schließt es einfach an und funktioniert. Man schließt es einfach an, es funktioniert. Da ist Win-USB, was einem noch extra Features gibt, wo man unter Mac und Linux einen Treiber braucht, wo man annimmt, dass die Applikation all die Anwendungen alles übernimmt. Man packt jetzt den Browser. Aber ich habe es geschafft. Ich habe es geschafft, auf meiner Windows-Maschine zum Laufen zu bringen, aber es läuft nicht anderen Windows-Maschinen, und das zerstört es ein bisschen, das einfach zu machen. Es ist sogar einfach unter Windows. Ein Problem ist, dass ein Windows-Hit ist nicht sehr schnell. Es ist C auf C Milikum, wenn man 8 bytes, das ist 80 bytes pro Sekund, und das ist nicht so schnell, aber wir wollen Update. Wir haben nicht viel, aber das ist in Ordnung. 800 bytes in Ordnung, ich nehme das. Der Start ist aktuell ein Projekt. Wir haben verlässlichen 2-direktionalen Transport. Wir haben eine gemeinsame Codebase, das über mehrere Projekte funktioniert. Wir haben Ports zu verschiedenen Plattformen. Palawan war natürlich das erste Hardware-Projekt, an dem ich gearbeitet habe. Das war das, wo die meisten Arbeitrenge auch aufwacht. Es war arbeitet unter GBUS. Da ist ein Bootloader, der Joy Boot genutzt. Der basiert auf dem Fadecandy Bootloader. Es hat kein richtiges Betriebses, das heißt, wir haben dieses Software in 2 verschiedenen Polen arbeitet. Es ist natürlich auch ein Port zu LovedCode. Da gibt es einen Tokener morgens von Bunny dazu. Es hat 2 USB-Pins und 2 Pins, wo wir in der USB-Stack drauf bekommen. Es schickt unsere Daten über Audio. Es ist wirklich cool, es ist kein Audio. Es ist wirklich fantastisch. Es geht morgen zu dem Vortrag um 4 Uhr. Noch eine andere Sache, was über Modi ist. Das steht sich aus, das funktioniert. Für das LovedCode Produkt haben wir einen USB-Pulling-Thread, der in seinem eigenen Thread läuft. Wo wir das Betriebssystem im Hintergrund laufen haben. Es überspringt ab und zu manchen Paketen, aber das ist in Ordnung. Wir haben 3 Versuche, und dann klappt das auch. Es funktioniert aber relativ gut. Für die Zukunft hätte ich gerne einen funktionieren Updater. Es gibt Updater dafür. Microchip macht zum Beispiel eine für seine Chips. Aber es gibt nicht wirklich gute Open-Source-Tools. Ich hätte gerne einen Updater, der mehr Funktion hat. Es wäre natürlich auch nett, dafür eine Grille zu haben. Und ich hätte das Ganze auch gerne auf mehr Plattform getestet. Ich habe das Ganze auf Windows and Linux getestet. Und ich hätte das Ganze auch gerne auf andere Sachen getestet. Also, ich hätte das auch gerne noch auf anderen Chips getestet. Und natürlich als eigene Sache. Ich würde gerne selbst Palawan Hardware bauen. Ich würde gerne einen funktionierenden Updater haben. Weil, wenn ein Software schreibt, macht man Fehler. Und man möchte es dann wieder Updaten. Und den Updater Updaten ist natürlich schwierig. Deswegen wollen wir, dass der Updater so stabil wie möglich läuft. Und dass ich irgendeinem Binary schicken kann und das Ganze dann aktualisiert wird. Vielen Dank fürs Zuhören. Vielen Dank, Sean. Ich musste wirklich nicht das USB so genutzt werden können. Vielen Dank. Wir haben Zeit für ein paar Fragen. Also, falls ihr irgendwelche Fragen habt, stelle ich an die Mikrofone. Wir haben eine Frage. Hallo, als erstes danke für den Vortrag. Auf der wichtigen, nicht wickelnden wichtigen Folie hast du gezeigt, dass man die Adresse ignorieren kann. Ich kann mir vorstellen, dass es auf Pit-Sachen funktioniert, die richtig connect ist. Aber hast du das auch mit USB-Hubs getestet? Weil ich kann dir vorstellen, dass es total schiefgegungen würde. Ich habe die Adresse ignoriert, weil ich und gesagt habe, das nicht wichtig ist. Es kann sein, dass es funktioniert. Es kann sein, dass wir sie ignorieren können. Vielleicht auch nicht. Ich nehme die Adresse wirklich auf, um das Ganze zu speichern. In meiner Erfahrung war es total in Ordnung. Aber meine Einstellung ist, wenn es nicht funktioniert, dann werde ich das fixen. Frage von Mikrofon Nummer 2. Hallo, ich habe eine Frage. Ich wundere mich, ist es einfach die Geschwindigkeit von dem Cortex, die die Implementierung in der hohen Geschwindigkeit limitiert? Oder ist es deutlich komplizierter Antwort? Ich frage dir, was du meinst, dass es die hohen Geschwindigkeit betrifft. Okay, hohe Geschwindigkeit. Voll Geschwindigkeit ist ein bisschen schwieriger. Ich sage, dass es nicht funktioniert. Ich hoffe, dass mich jemand widerlegt. Aber es ist unmöglich auf diesem Chip. Ich wirklich hoffe, dass es jemand widerlegt. Das Sample dauert einen Zyklus. Der Shift dauert einen Zyklus. Und der Shift dauert einen Zyklus und der Exit dauert einen Zykul und das hinzufügen zu dem Wert braucht einen Zykul und man kommt gar nicht zu diesem Bitstuffing und wenn dann ein DMA-Engine hätte, dann würde man vielleicht diese Tricks tun können, aber diese Chipsen so niedrig, so billig, dass man es gar nicht anders macht. Ich glaube nicht, dass volle Geschwindigkeit möglich wäre. Hohe Geschwindigkeit vielleicht, aber nicht volle. Hohe Geschwindigkeit hat auch das Problem, dass man die Spannung erwachsen werden muss und dass man Level Translator haben muss und das. Fragen aus dem Internet. Ich habe eine Frage aus dem Internet. Hast du versucht, SIGROC zu benutzen, um das Ganze zu debaggen und es funktioniert mit billiger Hardware? SIGROC? Nein, ich habe das jetzt davon nie gehört. Also ich habe noch nie wirklich versucht diese Plattform zu benutzen und ich habe nur den Beagle benutzt, aber ich habe nie davon gehört, aber ich werde es mir mal angucken. Ich wundere mich, du benutzt den Timer interrupt? Nein, du benutzt den Timer interrupt, ob man Edge Detection benutzen kann. Für einen Interrupt Vector, Edge Detection, ja, man kann man und das ist, wie es eigentlich arbeiten sollte. Mal gucken, ob ich das machen kann. Ja. Wenn man auf die, wenn man auf die API lag, ist es so designed und wenn man dann eine Kante haut und dann für die Capture fangst du auf. Die obere Hälfte handelt den Interrupt und schickt den Eier an vor zurück und die untere Hälfte läuft in dieser Polschleife. Man kann es nutzen, wenn man benutzt, macht den ganzen Prozess in der Hauptschleife. Auch eine Frage von dem. Wie hast du den Timer Recovery gemacht? Du hast gesagt, dass man viel Zeit in der Preamble hatte. Also mich würde das interessieren, weil das könnte sich ja wieder sprechen. Ich habe sogar eine Folie gehabt, wo ich erklärt habe, wie das funktioniert. Es ist praktisch synchronisiert zu den Pulsen. Mal gucken, wo es ist. Man kriegt diese Pulse am Anfang. Mal gucken, wo es ist. Also, zählst du in die Zügel? Nein, nein, wenn es a, wenn es hoch und runter beginnt, ist es praktisch in der Vorschleife, wo man es mit sich selbst vergleicht. Und sobald sich das Signal ändert, nimmt man das als die Rk8 und man nimmt an, man verschiebt sich ein bisschen, aber das 11-byte-Zinfektiv ist wunderbar. Frage für Mikrofon Nummer 3. Kann man damit ein USB-Hub bauen? Mit der Software? USB-Hubs definiert in Kapitel 11, was genauso viele Seiten hat, wie Kapitel 1 zu 9. Und das wäre nur eine niedrige Schwindigkeit. Ein USB-Hub erwartet, dass man hohe und niedrige Geschwindigkeiten benutzt. Es würde einfach nur mehr P-Types erweitern. Und noch eine Frage aus dem Internet? Ich habe zwei kurze Fragen. Denkst du, dass schneller das High-Speed-USB möglich wäre und wäre das möglich, das Ganze auf den M3 und M4 Prozesse zu portieren? Was war die erste Frage nochmal? Denkst du, dass High-USB möglich wäre? Mit einem externen Phi? Ich denke, es wäre möglich. Die haben Prozessoren, die es eingebaut haben und mit einem externen, denke ich, wenn das Ding über das Decoding übernimmt, denke ich, wäre das möglich. Die zweite Frage könnte man das portieren. Das Caching macht das ein bisschen problematisch. Ich bin nur nicht sicher, ob die Caches haben, aber du musst einfach aufpassen, ob das möglich ist, sie sind schneller, aber vielleicht kann man mit ihnen sogar Full-Speed machen, weil sie sind schneller. Könntest du ein bisschen erklären über das Human Interface Device, ob man unter Windows einen IF-File installieren müsste? Nein, in der Fall, mit einem Schreiben zu einem Human Interface Device, wie man das Hit als ein Ausgang benutzen kann. Das ist verfügbar für jede Programmiersprache, das genannt Signal 11. Es ist eine Bibliothek, das läuft unter Windows, unter Mac, unter Linux. Es kümmert sich um alles, man braucht den richtigen Diskriptor, dass das Herstellerformat angebt. Du schreibst einfach, dass diese Signal 11 Bibliothek und unter Windows braucht, ist kein Treiber und das ist die ideal Art, das zu tun unter Windows. Ja, du hast über Voraussetzungen geredet, um dieses Software in verschiedenen Betriebssystemen zu benutzen. Kann man das Ganze auch im BIOS benutzen, also kann das Keyboard auch im BIOS involieren. Das wird in dem Header definiert. Es ist ein Teil von einem USB-Hit-Diskriptor, wo man einen Bootprotokoll mitgeben kann. Also man kann sich dann verbinden, wenn man dieses Feld setzt. Es passt nicht wirklich auf, was für eine Testatur dran ist. Es nimmt einfach an, es ist eine Standard-Tastatur. Also wenn das Feld setzt und funktioniert das, drei Fragen noch. Ich habe total vergessen, John einen großen Applaus zu geben.