 Ja, willkommen bei Raspberry Pi RP2040, dem Pio Emulator. Was ist das? Raspberry Pi hat einen Mikro-Kontrolle rausgebracht, mit zwei ganz spannenden neuen Units drinnen, den Programmel Io-Units. Was tut das? Das wird euch dann alles erklärt werden vom Jürgen. Aber ganz spannend, man kann damit ein kleines Programm schreiben, kann zum Beispiel mit DMA-Daten reinschieben, dann coole Sachen machen, wie VR Bitbanging oder sonstiges. Und es ist ein bisschen ein neuer Ansatz beim Mikro-Kontroller-Programmierung oder ein ziemlich coole jedenfalls. Aber das Debugging ist halt auch umso schwieriger. Und das ist genau das Problem, das der Jürgen lösen wollte. Und das wird uns jetzt erzählen. Der Jürgen selber ist Diplom-Informatiker, Programmierer, Software-Architekt, aber auch Medienkünstler und Musiker. Ja, und immer bemüht, das in all seinen Projekten, all seine Skills einfließen zu lassen und zu verbinden. Und ja, da bin ich jetzt sehr gespannt. Danke, willkommen auf die Bühne. Ja, danke für die Einflugung. Herzlich willkommen. So, ja, war eigentlich schon eine sehr gute Einleitung. Also es geht um den Raspberry Pi Pico, speziell um den PIO und um den Prozessor für die Ein- und Ausgabe. Und weil das noch ein relativ neues Thema ist, der kam ja erst letztes Jahr in Februar raus oder in Januar, wollte ich nochmal ganz kurz zumindest auf die Hintergründe eingehen und dann auch näher drauf, warum das überhaupt ein Problem für die Entwicklung darstellt und wie man dann mithilfe eines Emulators dann auch die Entwicklung dann wieder damit ganz gut hinbekommen kann. Und zum Schluss dann noch eine Demo machen, bevor wir dann zu fragen und Antworten kommen. So, das Teil sieht also so aus. Vielleicht haben Sie die meisten schon gesehen. Es ist also, um es jetzt mal ganz grob einzuordnen, da wo sich auch die Arduino Boards befinden, allerdings deutlich mehr Performance, deutlich mehr Speicher. Natürlich dementsprechend auch ein bisschen mehr Stromaufnahme als ein Arduino, aber immer noch verhältnismäßig wenig. Und von Raspberry Pi Boards, die es bisher gab, die ein großer Erfolg war, kann man dann draus schließen, dass dieser Mikrocontroller sicherlich auch ein großer Erfolg werden wird. Und die Raspberry Pi Foundation ist ja auch dafür bekannt, dafür, dass die Software Unterstützung auch excellent ist. Und das Ganze haben die jetzt nicht, wie jetzt der Arduino, der hat ja dann so ein AT-Mega-Chip drauf. Nein, die haben jetzt, die Raspberry Pi Foundation hat jetzt selber einen eigenen Chip entwickelt und auf dessen Basis diesen aufgebaut. Und das Ganze auch in Raspberry Pi manier sehr billig gehalten, also sehr preisgünstig gehalten. Das ganze Board kostete bei zumindest anfänglich so um die 4 US-Dollar und der Chip ein US-Dollar. Im Moment sind die Preise ein bisschen hochgestiegen aufgrund der weltweiten Lage, aber ich denke, das wird auch langfristig sich wieder auf kostengünstig dann einpendeln. Viele Details zu diesem Pico gibt es dann auch, will ich hier so gar nicht dann ins Detail weiter reinsteigen, findet man dann auch im Netz bei der Raspberry Pi Foundation direkt. So, wie gesagt, da ist jetzt ein selbst entwickelter Controller Chip drauf von der Foundation. Der 2 Arm Cortex-Scan enthält 264 Kilobyte Rahmen, also es sind 256 plus nochmal 8 Kilobyte an separater Stelle. Die MA Controller 30 GPIO Pins eigentlich 32, aber extern sind im Moment nur 30 rausgeführt. Und dann eben diese 2 PIOS, wo ich gleich dann nochmal näher drauf kommen werde, die dazu dienen auch die GPIOs direkt über eine Hardware kontrollieren zu können, ohne dass davon die Haupt-CPU belastet wird. Und vor allem auch Takt wirklich zyklusgenau und Timing hinzubekommen. Systemfrequenz geht bis zu 133 MHz, wie gesagt deutlich schneller als die Adoinus, die älteren Adoinus, die ja meistens nur bis 20 MHz gehen. Und auch hier wieder Details kann man auch wieder in den Datenblättern nachlesen, will ich gar nicht so tief drauf eingehen. Interessant ist jetzt halt der PIO, Programmable Input Output heißt das. Früher in den 70er, 80er Jahren hatte man auch schon den Begriff PIO, das war dann die Abkürzung für Peripheral Input Output, bezeichnete also eigentlich nur auf Chips den Teil der Hardware, der wirklich für die Ansteuerung zuständig ist, aber der große Unterschied ist, dass wir hier jetzt beim Raspberry Pi wirklich einen Prozessor haben, also einen Input Output Prozessor, also nicht einfach nur eine Gatalogik, die einfach von den eigentlichen Chores die Daten weiterreichen, nach außen und wieder rein reicht zu den Chores, sondern wir haben wirklich separate Input Output Prozessoren, die man auch programmieren kann. Es gibt zwei solcher PIOs pro Chip, die auch überlappend arbeiten können, das heißt die 30 GPIO Pins, die ich habe, kann ich dann auch gegebenenfalls auf die zwei PIOs aufteilen, dass die unabhängig voneinander bearbeitet werden, wenn ich das möchte. Und pro PIO habe ich insgesamt vier Input Output Prozessoren, also damit kann ich dann schon eine ganz schöne Menge machen, parallel. Allerdings, Chip-Platz ist knapp, deswegen sind die Prozessoren relativ einfach gehalten. Zu den Einschränkungen gehört auch, dass der gesamte Programmspeicher für die Abarbeitung eines IOProgramms gerade mal 32 Instruktionen maximal enthalten kann. Das heißt die maximal vier Prozessoren teilen sich dann sozusagen dieses Programm, was aus maximal 32 Befehlen besteht. Das ist möglich, weil sehr kompakte Opcodes verwendet werden, sodass man auch wirklich mit kurzen Programmen schon ziemlich viel erreichen kann. Auch hier für die eigentliche Programmierung sei auch wieder verwiesen auf das entsprechende Datenblatt, wo es ungefähr 30, 40 Seiten nur über die Programmierung dieses Chips gibt, beziehungsweise über die Prozessoren im PIO. Trotzdem wollte ich ganz kurz nochmal auf den Instruction-Set eingehen. Also wir haben, falls ein Input Output Prozessor ist, hauptsächlich Daten, Transferinstruktion, wir haben konditionale Sprünge, wir haben Wartbedingungen, wir haben keine arithmetischen Operationen, weil es soll ja ein Input Output Prozessor sein, der möglichst einfach gehalten ist. Wir haben auch keine logischen Operationen wie logisches End, logisches Ohr oder sowas, das haben wir nicht. Und im Wesentlichen war es das schon mit Ausnahme von noch ein paar speziellen Sachen, wo es um Synchronisation und exaktes Timing und die Lays und solche Sachen geht. Jeder Opcode ist wie gesagt ein einzelnes Speicherwort, das heißt nicht wie bei Intel Prozessoren oder sowas, da haben ja verschiedene Opcodes, verschiedene Längen. Es gibt einen Bytecode, zwei Bytecodes, drei Bytecodes. Hier hat jede Instruktion exakt 32 bits. Und wie gerade eben schon erwähnt ist, können Verzückungszyklen erfolgen, weil es geht hier immer um exaktes Timing bei der Generierung von der Belegung der GPIO Opins. Auch hier die Details bzw. eine Liste von links findet man auf dieser Seite und von dort aus dann auch wieder weiteres Technisch-Doku. Hier nochmal der Instruktionssatz im Überblick, also nicht wie bei einem Z80 oder 8086, wo man gleich 30, 40, 50, 60 Befehle hat, sondern wirklich hier gerade mal neuen Befehle, die allerdings sehr viele Parameter dann haben in diesen 32 Bits. Hier ist ein kleines Beispielprogramm, das habe ich entnommen aus dem Datasheet von dem Chip. Das macht nichts anderes als auf dem GPIO Pin 1. In Abwechselnden auf 1 und 0 zu schalten, also im Ergebnis bekommt man dann eine Rechteckschwingung am Ausgang des GPIO als Ausgangssignal. Man sieht hier, also erst mal wird angegeben, okay, der Pin 1 wird als Ausgangspin konfiguriert, dann wird der Pin auf 1 gesetzt, dann haben wir einen Delay von einem Zyklus, dann wird es wieder auf 0 gesetzt und dann springen wir zurück und dieser Jump-Effil selber braucht auch einen Zyklus, sodass also der Delay gerade so lang ist, dass quasi die Phase 1 und die Phase 0 wirklich auch die gleiche Länge haben. Genau, das wäre jetzt zum Beispiel ein einfacher Signalgenerator, solche Sachen wie LEDs zum Blinken bringen und solche Sachen kann man natürlich auch machen. Oder LED, diese LED Stripes ansteuern. Man kann damit einen SPI-Interface bauen. Man kann UART-Schnittstellen bauen, I2C-Interface, VGA-Treiber hat jemand auch schon mal gemacht. Vielleicht kann man auch direkt LCD-Panels ansteuern, das ist tatsächlich ein Projekt, was ich auch mal in Erwägung ziehen wollte, weil die LCD-Panels, die haben ja keinen, die Ronen, die kriegt man ja häufig sehr billig, aber da fehlt dann halt die Ansteuerlogik. Die könnte man dann auch hier implementieren, nehme ich mal an. Und eventuell Custom Interconnects, beispielsweise wollte ich auch mal eine Token Ring Architektur als Cluster von 64 Picos in einem Ring zusammengeschaltet, mal irgendwann bauen, wäre auch noch so ein Future Project und noch viel mehr. Auch hier gibt es Beispiele, kann man auch wieder sich anschauen. So, genau. Entwicklung, warum ist das ein Problem? Normalerweise ist der Zyklus, dass man Programm schreibt auf dem Rechner, lädt das Programm auf den Pico hoch, der hat eine USB-Schnittstelle, dann testet man das Programm, man lässt es laufen, stellt fest, entweder es ist okay, dann ist man fertig oder man ist nicht okay, dann muss man es fixen, das Programm und dann wieder zu Schritt 2 zurück. Und das kann halt ziemlich langwierig werden. Aber wenn man fertig ist, kann man auch Gulasch essen. Warum ist das schwierig? Weil es gibt keine Debugging-Funktion, es gibt keinen Single-Step-Modus, es gibt keinen Logging-Ausgabe, also keine Unterstützung für Logging-Ausgaben. Man kommt auch nicht an die Register direkt dran, um zu schauen, was da passiert. Dann auch solche Sachen wie Instruktionsverzögerung, wie weit man da schon ist und so weiter. Auf die internen FIFOs kommt man nicht drauf. Auf die GPIOs, die müsste man quasi auf die internen Vertratung kommen wir nicht drauf und so weiter und so fort. Und man würde eventuell noch zusätzliche Hardware benötigen, um das Ganze dann auch wirklich zu testen. Deswegen war die Idee, ein Emulator zu schreiben. Fokus ist nicht auf Echtzeit, sondern tatsächlich auf Debugging. Und der hat auch den Vorteil, weil es in Software geschrieben ist, eine komplette Emulation, habe ich auch den vollständigen Zugriff auf den kompletten Zustand. Und Nebeneffekt war auch, dass bei der Implementierung dieses Emulators noch ein paar Fehler in der offiziellen Doku im Datasheet aufgefallen sind. Die habe ich dann auch noch zurückgemeldet an die Foundation, sodass ich auch noch ein bisschen Bylink getragen habe, dazu das Datasheet zu verbessern. Und Fun Fact, als ich das geschrieben hatte, hatte ich den Pico noch gar nicht. Das heißt, dass alles nur trocken passiert. Genau, das Ganze ist als Source Code verfügbar, GPLV2 und volle Dokumentation gibt es auch im Netz. Dann, das ganze Ding besteht aus einem Monitor-Programm, mit dem ich, also einen Server habe ich, dann habe ich mehrere Kleinprogramme, die Kleinprogramme dienen im Wesentlichen zum Steuern, das ganze Ablauf sowie zur Beobachtung. Ich kann hier die GBI Opins beobachten, den Codeablauf kann ich beobachten, ich kann die internen FIFUS beobachten und ich kann mir Diagramme generieren und vielleicht werde ich irgendwann auch noch weitere Utilities einbauen. So, dann kommen wir jetzt zur Live-Demo. Genau, also wie ich gerade eben sagte, wir haben einen Server, das Ganze habe ich über HTTP-Protokoll implementiert. Genau, ich habe im Prinzip fertige Jazz, die ich mir dann selber kompilieren kann und kann hier einen Server starten. So, der Server läuft jetzt auf Baud 2040, ist er dann erreichbar und dann habe ich meine Kleinapplikation, hier die Empfehlung, unter Ubuntu dieses Ubuntu-Specific Terminal zu nutzen, weil das kann Unicode-Zeichen besser als das Standard X-Term und kann hier ein Monitor starten, Monitor-Programm, in dem ich dann das kontrolliere und gleichzeitig kann ich hier auch schon im Hintergrund Observer starten, zum Beispiel den Code-Observer, als ein Beispiel. So, dann, hier habe ich eine eingebaute Hilfe drin, kann mir auch die Befehle anschauen, wenn ich sie vergessen habe, würde ich jetzt hier einen Script laden. Da ich den Namen nicht mehr weiß, kann ich mir die auch anzeigen lassen. Es gibt hier eine Reihe von vordefinierten Scripts, die schon vorbereitet sind, als Demo und kann mir dann zum Beispiel das SquareWraith Script laden. So, das wurde jetzt auch gleich ausgeführt und hier da, jetzt sehen wir hier, vorhin war hier alles Null, oh, Wunder, jetzt sehen wir hier in dem Code-Fewer schon tatsächlich was getan. Wir können auch parallel nochmal vielleicht die GPU On-Opens starten. Da sehen wir dann die 32 Stück, wie gesagt, eigentlich sind nur 30 rausgeführt, aber intern sind es halt 32. Hier gibt es auch verschiedene Ansichten. Es gibt eine interne Ansicht, eine externe Ansicht. Es gibt nochmal ein Remapping zwischendurch. Ich kann mir halt dann auch die Pins anschauen aus verschiedenen Sichtweisen und auch, ich kann hier auch auswählen zwischen dem welchen PIO ich mir anschaue und kann, wenn ich jetzt, wenn ich zum Beispiel beide PIOs parallel sehen will, kann ich hier auch noch eine zweite Instanz starten von dem GPIO Server. Das geht alles, könnte dann hier den hier für den GPIO 1 verwenden und der hier zeigt mir den GPIO 0 an, oder wie auch immer. So, jetzt haben wir hier das Programm. Hausgekraut bedeutet, dass im Moment noch nichts ausgeführt wird. Wir haben jetzt hier, also genau, wir starten auch noch den Diagramm, die Diagrammansicht. Das ist nämlich auch ganz nützlich. Dann kann ich nämlich auch gleich hier sehen, was hier so passiert. So, und gleich werden wir dann auch noch ein Problem sehen und dafür werden wir auch eine Lösung machen, genau. Ich haue jetzt mal nur den Code Observer an und hier das, was hier an den Signal nach außen ankommt und kann jetzt hier im Single Step Modus durchgehen. Ich sehe, okay, jetzt kommt der erste Befehl, wird ausgeführt, St. Pindius. Das können wir vielleicht auch noch mit hier hochziehen. So, und wir können dann hier auch mal auf den Pin 0 achten, was mit dem passiert und wir können hier auch verfolgen, was hier im Programmlauf passiert und ich gehe jetzt einfach Stück für Stück weiter. So, jetzt wurde erstmal die Pin-Richtung hier von dem GPIO Pin gesetzt. Genau, im nächsten Punkt wird es dann auf 1 gesetzt. So, jetzt haben wir hier ein Delay-Zyklus. Eins gibt an, dass jetzt ein Delay-Zyklus von einem Takt noch erfolgt, deswegen ist es jetzt wieder ausgegraut. So, im nächsten Schritt wird dann der Pin genau, der ist jetzt hier auf 1. Der wird jetzt im nächsten Schritt dann, wenn der Befehl ausgeführt wird, auf 0 gesetzt werden, sollte er zumindest genau jetzt. Und dann erfolgt der Jump Befehl. Ich glaube, ich habe hier irgendwo noch Frequenztile, genau. Ich glaube, ich habe hier die, man kann auch die Frequenz noch dividieren, damit dann tatsächlich hier das Kommando in jedem Zweitakt noch ausgeführt wird. Deswegen sehen wir hier immer ein verlangsamter Ausführung, genau. So, man sieht auch hier den GPIO genau und der wechselt dann immer von 0 zu 1, genau. Was sagt die Zeit? 7 Minuten, okay. Genau, hier kann ich auch die Ansicht ändern. Also wir sind jetzt hier auf der State Machine, also wie gesagt, wir haben vier Prozessoren pro PIO, wir sind jetzt auf das State Machine Nummer 0. Wenn ich jetzt auf eine andere State Machine setze, die jetzt gerade im Moment allerdings nicht aktiviert ist, wir haben jetzt nur den Prozessor 0 gerade aktiv, dementsprechend ist das Ganze auch wieder ausgegraut. Aber man sieht hier das Programm immer noch, weil vorhin meinte ich ja, die vier Prozessoren, die teilen sich den gemeinsamen Speicher hier, insgesamt die 32 Speicherwörter. Deswegen sieht man hier tatsächlich auch noch das selbe Programm. Wenn ich jetzt auf einen anderen PIO wechsle, den haben wir noch gar nicht initialisiert, da ist dann wirklich tatsächlich alles noch auf 0 gesetzt. So, dann haben wir noch, weil ich es noch nicht gezeigt habe, genau, nee, das ist der Server, da haben wir die Clients. Ich kann jetzt hier, also wie gesagt, es gibt auch noch VIFUS, das Thema habe ich jetzt gar nicht angerissen, die kann ich auf jeden Fall auch noch mir anschauen, wenn sich da was tut, dann habe ich noch, ja, genau, doch. So, und da gibt es auch noch zwei Schieberregister, also gibt es auch komplexere Programme, wo ich dann hier dann auch Daten in einem Schieberregister aufsammeln kann und zwischen Hauptspeicher und JBLOs hin und her seriell dann ausgeben kann und so weiter und so fort. Okay, das würde jetzt im teiligen Rahmen sprengen das noch zu zeigen, aber ich sage es dann einfach nur, kann man auf jeden Fall hier auch dann einzeln verfolgen, wie es dann so ein einzelnes Schieberregister dann tatsächlich füllt oder auch wieder lehrt in einem Rutsch dann und die VIFUS, die sind auch noch pro Prozess auch vorhanden. Das heißt, man kann ja auch Daten sammeln, die man dann anschließend zum Beispiel in Schieberregister rein schiebt und das Schieberregister dann wieder seriell auf einzelne GPIOs dann ausgibt und so weiter. Okay, gut, dann würde ich sagen, also bis zu hier noch fünf Minuten. Okay, dann gucken wir mal, ob wir vielleicht noch ein komplexeres Beispiel finden. Dann nehmen wir vielleicht so dieses Pull Example 1. So, diese Skripte, die machen auch ein bisschen Initialisierung, zum Beispiel die ganzen VIFUS aufsetzen und so weiter. Das Schöne am RPE am 2040 ist, dass der eine Registerschnittstelle bietet gegenüber den beiden Kors und ich habe diese Registerschnittstelle, also die dann quasi memory mapped IO quasi ist, auch dann genutzt, um die TCPIP-Schnittstelle zu implementieren. Das heißt, die ist 1 zu 1 gemapped in der gleichen Art und Weise, wie auch die Register vom Core aus zugreifbar sind. Dementsprechend kann ich hier auch über das Skripting tatsächlich da direkt quasi auch in die Register der einzelnen Prozessoren reinschreiben, soweit sie zur Verfügung stehen. Und weil die halt nicht ausreichen, wie gesagt, man kommt nur an bestimmte Sachen dran, deswegen habe ich noch zusätzliche andere Register definiert, die dann in der gleichen Art und Weise auch angesprochen werden können. Auch dass die ganzen Register sind auch einzeln in der Doku dokumentiert, das würde jetzt in den Rahmen sprengen. Aber vielleicht gehen wir hier nochmal, wenn man hier nochmal klär. Genau und jetzt haben wir hier halt ein anderes Programm auch mittlerweile hier drin. Jetzt müsste ich hier irgendwo noch meine, habe ich es wieder gekillt. Okay, dann starten wir nochmal neu, dass die FIFO Register. So, genau, hier hat sich schon was getan. Und hier kann man dann auch tatsächlich hier dann an dem Programm dann auch verfolgen, wie dann hier auch einzelne Schieberregister dann sich so langsam füllen und dann auch die Ausgangssignale entsprechend nachverfolgen. Die Signale, die hier gezeigt werden, die sind auch konfigurierbar. Ich habe schon eine Reihe von vordefinierten Signalen, die ich hier ein- und ausblenden kann. Ich kann aber auch hier dann noch ein Signal hinzufügen, kann dann hier auch anzeigen, welches dieser ganzen Register, wie gesagt, es gibt diese voll definierten Register. Da gibt es verschiedene Sektionen und kann hier dann auch wirklich einzelne Bits hier beziehungsweise kombinierte Bits rausgreifen und kann die dann als ein Signal hinzufügen. Was? Ach so, hier oben, keine Ahnung, irgendwas rein. So, und dann habe ich das Signal hier jetzt an der Stelle hinzugenommen und das teilt mir dann halt dann auch den entsprechenden Ports, das entsprechende IO an. Genau. Wow. Danke Jürgen. Ja, ich glaube, den Applaus hast du dir verdient, ganze Arbeit. Du hast wahrscheinlich einigen den zukünftigen Raspribe-Heil-Developern da, die Arbeit um einiges einfacher gemacht. Danke. Ja, wir machen jetzt noch fünf Minuten Q&A, wenn ihr Fragen habt. Ich bringe euch das Mikro. Wir haben leider nur fünf Minuten, vielleicht kommen dann auch noch alle dran. Aufzeigen bitte, wenn ich euch das Mikro bringen soll. Frage Nummer eins. Uuh, alles erklärt, alles sprachlos. Na, ihr dürft alle Fragen stellen. Bitte. Ich habe mich jetzt quasi gar nicht mit dem Ding beschäftigt vorher, aber wie flexibel ist man denn überhaupt mit 32 Worten? Das ist jetzt ja schon nicht so viel, wenn man dabei einen LCD-Treiber bauen möchte. Kannst du da vielleicht ein bisschen erzählen? Also in der Tat ist es nicht viel, aber die Befehle sind schon ziemlich kompakt und halt auch auf IO gedrimmt. Und es gibt über den DMA-Controller auch noch die Schnittstelle natürlich zu den Cores. Das heißt, die Cores können natürlich die Daten schon mal im Voraus bearbeiten als ein ganzen Data-Chunk. Und diese Prozessoren würden sich dann quasi den vorbereiteten Chunk halt selber holen und dann im richtigen Timing dann halt beispielsweise ausgeben oder auch umgekehrt Daten einlesen, sammeln, bis irgendeine FIFO voll ist. Und wenn die FIFO voll ist, dann würde über dem Art Transfer das dann wieder den Cores zur Verfügung gestellt werden. Und dort würde ein Interrupt ausgelöst werden. Also man kann das so dann aufteilen zwischen den IO-Prozessoren, die wirklich nur das einfache IO machen, aber schon eine gewisse Logik haben in Bits hin und her schieben können, auch konditionale Sprünge haben und solche Sachen. Sodass man also im Wesentlichen auf dem Abstraktionsniveau wie von so einem SPI oder U-Art Schnittstelle dann ist und die Idee ist halt wirklich so eine Schnittstelle zu bauen. Aber es gibt tatsächlich auch schon Leute, die eine VGA-Ansteuerung gebaut haben. Hände hoch, Hände hoch, wenn ihr noch Fragen habt. Wir haben noch ein bisschen Zeit. Ja, bitte. Wie sieht es denn aus also zwischen den Controller und der Controller? Wie wird denn da kommuniziert oder wie kann man zum Beispiel das Programm updaten? Wird es auch quasi im RAM geschrieben für den Controller? Ich habe ja von die Register erwähnt. Das heißt, ich kann also so einer von den Cores könnte über einen Schreibzugriff auf eines dieser Register, das AP2040 dann entsprechend in den Programmspeicher der Prozessoren den entsprechenden Programmcode reinschreiben. Dafür gibt es aber schon ein fertige Bibliotheken. Wenn man sich die links mal anschaut, also eigentlich muss man da nicht mehr viel tun, man kann das dann direkt auch beispielsweise von C ausmachen. Das ist übrigens auch noch ein spannender Punkt. Interaktion zwischen C und Java wird jetzt aber hier auch den Rahmen springen. Ja, also ist möglich, gibt es fertig Bibliotheken dazu. Allerdings kommt ja hier schon das erste Problem. Im Programmspeicher reinschreiben, aber ich kann nicht mehr auslesen. Das ist so eine Beschränkung, eine der vielen Beschränkungen. Und da brauche ich dann halt wirklich den Emulator überhaupt drauf zu schauen, was steht denn im Moment im Programmspeicher überhaupt drin. Das kriege ich sonst nicht mehr raus. Eine Frage ging noch. Ja. Hallo, also danke erstmal für den Vortrag. Ich habe mir das Ding da auch vorgenommen. Wenn ich das richtig verstehe, kann ich aber auch die normalen M0-Cores nutzen, um die IOs mit Signalen zu versorgen. Nur halt nicht in dieser Schnelligkeit. Ja, würde ich, nach meinem Verständnis ja. Also ich habe es tatsächlich noch nicht selber gemacht, aber es müsste eigentlich gehen. Super, ja. Und ich nehme an, es gibt auch schon eine Sammlung von fertigen PIO-Programmen. Wenn man zum Beispiel SPI oder so machen will, dann laden wir uns einfach rein. Genau, also in Datasheet beziehungsweise in der PICO-Beschreibung haben die 30 Stück ungefähr als Beispiele drin. Das sind im Wesentlichen die, die ich ja auch in dem Emulator drin habe. Ja, super. Vielen Dank Jürgen und danke euch fürs Spaschen und viel Spaß auf der Gebärm. Danke.