Hallo, ich bin dabei die Baudraten für PiPIco in C++ zu programmieren. Die Verbindung läuft über die USB-Buchse mit den stdio-funktionen. Da gibt es aber keine Möglichkeit die Baudrate zu programmieren. Man kann nur dazu eine #def machen:
1
#define PICO_DEFAULT_UART_BAUD_RATE 9600
Der Compiler sagt nichts dazu. Aber leider bemerke ich keine Veränderungen der Übertragungsdauern. Mit den Oszi messe ich immer nur ca.150ns für die kürzesten Impulse, egal was ich definiere.
Es gibt ja auch noch die UARTs 0 und 1 beim Pico. Die laufen aber nicht über die USB-Buchse, oder?
Zur Not würden mir auch die 115200 reichen, lieber wäre mir aber schneller.
Es gibt ja auch noch die UARTs 0 und 1 beim Pico. Die laufen aber nicht
über die USB-Buchse, oder?
Zur Not würden mir auch die 115200 reichen, lieber wäre mir aber
schneller.
Fangen wir hinten an, die UARTs unterstützen knapp 8 MBaud bei den Standard-genutzten 125MHz (genau: CPU_FREQ/16)
Kann man auch schön mit einem UART-USB Kabel testen. (mein PL2303 schafft 4MBaud in den PC hinein) Zwei Picos kann man aber bequem mit maximaler Geschwindigkeit quatschen lassen. Bei der Geschwindigkeit empfiehlt es sich DMA zu nutzen.
Die ACM hat im Grunde genommen gar keine Baud Rate, die Geschwindigkeit wird durch die USB-Geschwindigkeit bestimmt. Hast du da D+ und D- gemessen?
Bin jetzt nicht 100% sicher, aber ich meine mich zu erinnern, dass entweder pro Millisekunde oder alle 125µs je 64 Bytes übertragen werden können. Da sind die PiPicos übrigens deutlich langsamer als zB. die STM32F4.
Bin jetzt nicht 100% sicher, aber ich meine mich zu erinnern, dass
entweder pro Millisekunde oder alle 125µs je 64 Bytes übertragen werden
können.
Pro Millisekunde, der RP2040 etc. ist nur ein Full-Speed-Device (12 MBit/sec). Microframes alle 125 µsec gibt es erst ab High-Speed (480 MBit/sec).
Die 64 Byte beziehen sich aber auf den Inhalt eines Pakets ("Transfer").
Pro Frame können mehere Pakete ("Transfers") übertragen werden.
Bei 64 Byte Nutzdaten pro Paket sind das maximal 13 Pakete pro Frame, d.h. 832 Byte.
Und damit liegt die maximale Nutzdatenrate bei etwa 832 kByte/sec.
Die 64 Byte beziehen sich aber auf den Inhalt eines Pakets ("Transfer").
Pro Frame können mehere Pakete ("Transfers") übertragen werden.
Bei 64 Byte Nutzdaten pro Paket sind das maximal 13 Pakete pro Frame,
d.h. 832 Byte.
Und damit liegt die maximale Nutzdatenrate bei etwa 832 kByte/sec.
Hmmm, habe ich noch nie durch das Ding bekommen. Noch nicht einmal ansatzweise. Vielleicht eine Limitierung des tinyUSB im SDK. Muss gelegentlich mal einen Blick hinein werfen.
Hmmm, habe ich noch nie durch das Ding bekommen. Noch nicht einmal
ansatzweise.
Setzt "bulk" transfer voraus. Früher(tm) gab es USB-IDE-Adapter, die nur Fullspeed konnten (weil es damals Highspeed noch gar nicht gab), mit denen lag' man bei eben jenen 800 kByte/sec.
Einer der wenigen USB-SCSI-Adapter (Adaptec USBConnect 2000) stammt auch aus der Vor-2.0-Zeit und liefert entsprechende Datenraten. Gemütlich, sehr gemütlich.
Also, über USB weiß ich wohl zuwenig. Was ich hier lese, gibt es einen großen Unterschied zu seriell. Wenn ich nun mit meinen PiPico Daten an einen PC senden will, muß ich praktischer Weise über USB gehen. Da nützten mir die 2 Uarts im PiPico wohl auch nichts.
Also, über USB weiß ich wohl zuwenig. Was ich hier lese, gibt es
einen großen Unterschied zu seriell. Wenn ich nun mit meinen PiPico
Daten an einen PC senden will, muß ich praktischer Weise über USB gehen.
Da nützten mir die 2 Uarts im PiPico wohl auch nichts.
Wenn du richtig heftigen Datendurchsatz brauchst, UART-USB Kabel (hatte ich oben schon geschrieben) damit schaffst du 4MBaud also ca. 400kByte/s.
Mit einem der schnellen FTDI Adapter soll dem Vernehmen nach noch mehr möglich sein.
Wenn es aber so schnell geht, warum kommt der gesendete Text am Teminal
Putty so langsam an, dass man fast mitlesen kann?
Selbst µPy mit tinyUSB schafft > 50KByte/s mit 'nem Dreizeiler.
Hab's mir einfach gemacht und das Arduino-Framework mit earlephilhower Core verwendet.
Müsste Pico-SDK-USB verwenden, was m.W. auch eine TinyUSB-Portierung ist.
Jetzt grüble ich natürlich darüber, wie diese Hausnummer entsteht. Bei einem USB Frame pro Millisekunde wären das jedes mal zwei 64Byte Blocks. Finde ich bis jetzt nirgendwo in den USB specs. Schau'n wir morgen mal…
Ja das schaut interessant aus. Bin gespannt!
Obwohl die Default-Größe ja bereits 256kB/s suggerieren würde (bei 1Frame/ms).
Vielleicht sind's auch nur die nach innen gerichteten App-Buffer.
Vielleicht sind's auch nur die nach innen gerichteten App-Buffer.
Davon geh ich auch aus, in den Buffer laufen die Buchstaben rein, und sollten dann in 64-Byte-Häppchen rausgesendet werden, im Default also bis zu 4 hintereinander bevor der Buffer leer läuft.
Sollte also eigentlich für mehr Bandbreite reichen, wenn der tud_task() oft genug läuft, und der PC genug URBs sendet.
und zumindest der Linux cdc_acm - Treiber sollte eigentlich genug URBs raussenden:
1
for(i=0;i<acm->rx_buflimit;++i){
2
res=acm_submit_read_urb(acm,i,mem_flags);
default für das rx_buflimit sollten 16 sein, "#define ACM_NR" in der cdc-acm.h.
Deswegen wollte ich das mit 1024 in der tusb_config.h versuchen, dann passt die Anzahl der URBs, die der Kernel-Treiber raussendet zur max. Menge an URBs, die TinyUSB direkt hintereinander beantworten kann.
CFG_TUD_CDC_TX_BUFSIZE vergrößern hat nichts gebracht, aber mit der CPU auf 200MHz laufen 170KiB/s über ttyACM.
Und mit dem zweiten Core aktiv, der nur "tud_task()" ausführt, 180-200 KiB/s. Ist so natürlich nicht optimal, weil beide Cores am USB werkeln. Den ganzen USB-Teil auf den zweiten Kern zu schieben wäre vermutlich mit etwas Aufwand möglich...
Eher interessiert mich, warum das hochtakten was bringt. Ist ja nicht so als wäre der vorher CPU-Limitiert gewesen für die 125 KiB/sec..
Super, Danke Ernst.
Ja wenn ›Taktrate erhöhen‹ zu einem höheren Durchsatz führt, dann ist es mMn. ein Problem des USB Stacks. Wäre man Politiker, könnte man auch sagen, da ist noch Optimierungspotential vorhanden.
Vielleicht hat's ja einige Abstraktionsschichten zu viel. Sieht dann zwar schön aus, wie aus dem Lehrbuch, erinnert aber an einen Traktor mit Heckspoiler.
Wenn ich dazu komme, werde ich das mal Taktweise ein wenig hoch peitschen und 'ne Tabelle bauen.
Ad: Die Tabelle ist 'ne flache Linie. Bis 400MHz gleichbleibender Durchsatz. Bei 48MHz geringfügig niedriger. Aber alles mit µPy, da mag die Idle Loop einfach nicht schnell genug sein. Obwohl, bei mehr als dreifacher Frequenz…
Eher interessiert mich, warum das hochtakten was bringt. Ist ja nicht so
als wäre der vorher CPU-Limitiert gewesen für die 125 KiB/sec..
Könnte sein, dass der kooperative Aufruf von "tud_task()" kostspielig ist und man bei höheren Frequenzen eine Art aligning auf die darunter liegende USB req./resp. Struktur bekommt.
Aber alles Spekulatius. Bin mir nicht sicher, ob ich mir das Durchforsten des tinyUSB code antun möchte. Vielleicht im Winter.
alles zurück auf Anfang. Bin bei meinen Messungen zur Geschwindigkeit einem Fehler aufgesessen.
Anscheinend bremst das dazwischen liegende simple Terminal die Datenrate. Ist mir erst aufgefallen, als ich einen ungewöhnlich hohen CPU Wert auf einem Kern des PCs gesehen hatte.
Als Erklärung, nicht Entschuldigung, muss ich anführen, dass bei älteren Firmware Revisionen wirklich eine Limitierung vorlag. Deshalb war ich bei den fehlerhaften neuen Messungen auch nicht sonderlich verblüfft.
Mit der aktuellen 1.29 Firmware (auf RP2040) bin ich es nun aber! ;-)
Hier die korrekten Messungen mit µPy bei µC Frequenzen von 48MHz bis 400MHz.