Moin, vielleicht kann mir jmd bei der Suche nach einem passenden Mikrocontroller helfen: er sollte mindestens 32kB internen RAM, 128kB Flash oder mehr (auch intern) besitzen, sowie einen USB 2.0 Full-Speed Device, welcher per DMA die Daten im internen RAM ablegen kann - der Speicher für die DMA sollte größer 8kB sein im RAM; und ein externes Memory-Interface wird benötigt (16Bit breiter Datenbus). Es kommen insgesamt immer 9kB Daten über USB an, und erst dann kann der Prozessor mit den Daten auch was anfangen. Daher wäre es schön, wenn der Prozessor erst danach damit beschäftigt wird. Bezüglich der DMA-Geschichte: ist es richtig, dass man diese nur einmal am Anfang einstellt und dann läuft der Transfer der Daten von alleine ab (die ganze Zeit), oder muss der Transfer immer wieder per Hand aktiviert werden? Das Gehäuse kann alles sein, außer ein BGA, da ich das nicht selbser löten kann (bzw. keine Erfahrungen habe bezüglich Bügeleisen etc...) LG Jörg
bei den lpcs gibt es ein paar mit allerdings nur 8kb ram für dma (für den usb device reserviert) - hab die genaue bezeichnung grad nicht im kopf
Soweit ich erkennen kann lassen sich per Fullspeed USB sowieso nur 64 Byte pro Frame übertragen, isochron 1KB. Insofern dürfte die Grösse des USB-RAMs nicht der entscheidende Aspekt sein und es sollten genug Möglichkeiten bestehen, die Daten rechtzeitig ins normale RAM zu verlagern. Controller mit mindestens 32KB RAM, externem Speicherinterface und USB gibt es jedenfalls einige. In den STM32F103/105 Reihen beispielsweise.
reicht mir ein 70MHz Prozessor wenn über USB eine Datenrate von 8MBit/s zu erwarten ist? Diese Daten müssen anschließend umsortiert werden (ein kompletter Datenblock hat 600Bit und insgesamt gibt es von diesen 16 Stück); Sortierung sieht so aus, dass von jedem dieser 16 Blöcke nacheinander alle ersten Bits, alle zweiten Bits, dritten Bits etc. an das externe Memory Interface übergeben werden müssen... Die Geschwindigkeit mit der diese Daten an das ExtMemInt weitergeben werden müssen beträgt für jedes Bit 1µs; d.h. alle 1µs wird von jedem dieser 16en Blöcke ein Bit weitergeben. Eigentlich nicht soviel, aber ich weiß nicht wieviel Performance-Verlust man durch die Verwendung des USB Interfaces bekommt. LG Jörg
hab leider keinen Einfluss was vor diesem µC passiert - sprich dem ankommenden USB-Stream.
Jörg schrieb: > reicht mir ein 70MHz Prozessor wenn über USB eine Datenrate von 8MBit/s > zu erwarten ist? Nö. Mit diesem ganzen Zirkus drum herum und vermutlich streng synchronem pausenfreiem Bus nicht. Da klingt das für mich eher nach FPGA. Eventuell geht es aber auch mit XMOS.
die Datenpakete über USB kommen im kontinuierlichen Stream an, das ist richtig. Im Prinzip einschalten und nicht mehr aufhören... Dachte mir schon dass es mit einem ARM7 knapp werden würde, aber ein ARM9 mit 180 MHz (100MHz externes Businterface) reicht auch nicht mehr? Auf einem ARM7 mit 70MHz hatte ich es schon mal am laufen allerdings ohne USB-Zeug (in diesem Fall lagen die DAten in einem Dualport RAM, was jetzt nicht mehr möglich ist)... Mit FPGA oder XMOS kenn ich mich gar nicht aus...
noch eine andere Frage, wieviel MBits/s sind mit so einem ARM7 70 MHz möglich - schafft dieser oder einer von Ihnen wirklich die 12MBit/s?
Hab's nicht probiert, aber 12Mb/s = 1,5MB/s = 0,4MW/s traue ich dem Controller schon zu, immerhin muss der Prozessor die normalerweise nicht Bit für Bit einzeln verarbeiten. Erst zusammen mit der Bitpflückerei wird das zum Thema.
Hallo Jörg, über den Daumen könnte da die Leistung der AVR32UC3 von Atmel reichen. Da gibt es Typen mit USB-Hardware und externem Speicherinterface. Gruß, DetlevT
Detlev T. schrieb: > über den Daumen könnte da die Leistung der AVR32UC3 von Atmel reichen. > Da gibt es Typen mit USB-Hardware und externem Speicherinterface. Ob ein 66MHz AVR32 wirklich so viel schneller ist als ein 100MHz Cortex-M3 (LPC1700)? Weder USB noch Bus sind hier m.E. das zentrale Problem, sondern das Bitgepfriemel frisst die Leistung. Die USB-Interrupts und Blocktransfers kommen da nur noch oben drauf.
Was mit weiterhin zu unklar ist um es abschätzen zu können: die externen Buszyklen. Müssen die exakt alle 1µs ablaufen, komplett ohne erlaubtem Jitter? Das schafft ohne externe Synchronisation nicht einmal DMA. Wie hast du das in der bisherigen Lösung gemacht?
das ganze lief damals ohne Betriebssystem (da kein USB) und die
Synchronisation, dass die Signale über das externe MemInterface
rausgingen, war lediglich ein TimerInterrupt (der daraus resultierende
Jitter war zu vernachlässigen).
Der Jitter zwischen den "gleichzeitig" auf den Weg zu bringenden Daten
durfte nicht zu groß sein, und das war mit dem MemInterface gut zu
händeln.
Mit dem Bitgefriemel hat es gerade so geklappt - war aber zeitlich sehr
knap; also irgendwelche kurzen zusätzlichen Interrupts etc. waren nicht
drinnen. Der Dualport RAM (16Bit Datenbus) war allerdings auch sehr
schnell mit; ich glaub ich hatte einen Waitstate (mit USB wird dieser
Vorgang des Datenschaufelns in den internen RAM wahrscheinlich nicht so
schnell gehen)
>Das schafft ohne externe Synchronisation nicht einmal DMA
welche externen Syn-Möglichkeiten würde es hier denn noch geben? Wenn
extern ein Sync-Signal anliegt wie z.B. Midi-Timecode oder ähnliches
muss das von der CPU auch erstmal per Interrupt wahrgenommen werden...
Wenn ein Jitter von ein paar Takten zulässig ist, dann ist ein Bustransfer über Timer-getriggertes DMA wohl auch kein Problem und frisst kaum Zeit. Ist das externe nun wirklich ein Bus, oder sind das bloss 16 Leitungen und du hast bisher einen Bus verendet? DMA direkt auf den Port gibt's ja auch. Interrupts sollten dann auch kein Problem sein, solange die Gesamtlast noch verdaut wird. Das darf natürlich keine Just-in-Time Produktion werden, sondern es müssen genug umgepfriemelte Daten für den DMA auf Halde liegen, um sich auch ab und zu mal um den USB Interrupt kümmern zu können.
>Timer-getriggertes DMA wohl auch kein Problem
rentiert sich hier der Einsatz von DMA, wenn im Interrupt nur insgesamt
16Bits (1Bit pro Leitung des Datenbusses) übertragen wird, und im
nächsten Interrupt dann das zweite Bit... ?
Also nochmal von vorne, so wie ich den Kram verstanden habe: (1) Alle Millisekunde kommen 9KB Daten über USB rein. (2) Zwischen (1) und (3) sitzt jemand, der deine 9KB vom Kopf auf die Füsse stellt, indem er die Bits im Speicher neu sortiert. (3) Alle Mikrosekunde werden 16 Bit parallel irgendwo ausgegeben, egal ob Bus oder Port. Die Daten kommen aus einem 9KB Puffer im RAM. Deinen Interrupt alle Mikrosekunde sehe ich hier nicht. Sondern einen DMA-Kanal, der in für ihn gemächlichem Mikrosekundenraster umgepfriemelte Daten aus dem Speicher rausschaufelt. Rechenzeit entsteht in (1) und (2). In (1) weil das USB per Interrupt bedient werden will um die eingelaufenen Daten abzufischen bevor das USB-RAM überläuft. Hauptschleife macht (2) und sorgt dafür, dass dem DMA die Daten nicht ausgehen. RAM-Bedarf: 3 Puffer zu je 9KB. Einer läuft grad rein, einer wird verwurstet, einer läuft grad raus. Vielleicht geht auch weniger als 9KB pro Puffer.
Den USB-Transfer werd ich Isochron machen, da es ein Stream ist - sprich wenn etwas falsch angeliefert wordern ist, ist es halt so (ähnlich wie bei Audio, Video etc.) >(1) Alle Millisekunde kommen 9KB Daten über USB rein. genau - dieser Stream läuft die ganze Zeit ununterbrochen >(2) Irgendwo zwischen (1) und (3) sitzt jemand, der deine 9KB vom Kopf >auf die Füsse stellt, indem er die Bits im Speicher neu sortiert. richtig, ein Controller (welcher muss noch gefunden werden); dieser ist natürlich auch dafür zuständig die neu sortierten Daten wieder rauszuschicken (16Bit Port). Jede µs werden insgesamt 16bits (1Bit pro Leitung der 16Bit-breiten-Leitung) rausgeschickt. >Deinen Interrupt alle Mikrosekunde sehe ich hier nicht. Sondern einen >DMA-Kanal, der in für ihn gemächlichem Mikrosekundenraster >umgepfriemelte Daten aus dem Speicher rausschaufelt. Muss dieser Transfer immer wieder von mir persönlich losgetreten werden (wahrscheinlich gibt es einen DMA-Timer-Interrupt)? Also ein Interrupt der die DMA veranlässt die 16bit Daten rauszuschieben... Dieser Transfer passiert ja ohne das der Prozessor etwas mitbekommt. Ist es auch möglich der DMA zu sagen, dass sie im Speicher von Position A nach B wandern soll? Sprich zuerst die 16Bit Daten rausschicken, die sich an Position A im Speicher befinden und anschließend die Daten rausschicken die sich an Position A+16Bits befinden?? Kann man hier bei der Init der DMA einen Bereich angeben der nacheinander abgefrühstückt werden soll? Des Weiteren würd ich mal vermuten das ein DMA Transfer für den ankommenden USB Stream sinnvoll sein wird, um Leistung einzusparen vom Prozessor.
Ist es eigentlich ratsam bei USB ein O/S einzusetzen? Oder ist es schneller wenn mann vom jeweiligen Chiphersteller den Source bekommt für die USB-Treiber Implementierung? Hab bei Atmel gesehen, dass die c-Files dafür zur Verfügung stellen - weiß nicht wie das bei den LPCs ist?
Jörg schrieb: > Den USB-Transfer werd ich Isochron machen, Wenn du schon über die Quelle keine Kontrolle hast, dann darüber wohl auch nicht. Zumal du m.W. diese Datenrate mit Fullspeed nur isochron schaffst. > Muss dieser Transfer immer wieder von mir persönlich losgetreten werden > (wahrscheinlich gibt es einen DMA-Timer-Interrupt)? Wie schon angedeutet kann jeder einzelne DMA-Transferzyklus- eines 16-Bit Wortes automatisch per Timer-Event losgetreten werden. DMA-Quelle ist Speicher, inkrementierend, DMA-Ziel kann ein Port sein, kann externer Speicher sein, inkrementierend oder nicht. Wenn das mal eigerichtet ist, dann läuft das die ganzen 9KB autark durch, ohne Beteiligung der CPU. > Also ein Interrupt der die DMA veranlässt die 16bit > Daten rauszuschieben... Begriffsproblem? Der Begriff "Interrupt" steht gemeinhin für eine Unterbrechung des Prozessors. Die gibt's hier nicht. Nur alle Mikrosekunde ein für einen Takt vom DMA blockiertes RAM. > Dieser Transfer > passiert ja ohne das der Prozessor etwas mitbekommt. Ja. > Position A+16Bits befinden?? Kann man hier bei der Init der DMA einen > Bereich angeben der nacheinander abgefrühstückt werden soll? Genau das ist DMA. > Des Weiteren würd ich mal vermuten das ein DMA Transfer für den > ankommenden USB Stream sinnvoll sein wird, um Leistung einzusparen vom > Prozessor. Je nach Implementierung des USB-Moduls. Ich habe mal kurz bei dem vom STM32 reingesehen. Da landen die Daten in einem internen Dual-Port-Memory aus dem der USB-Interrupt sie rausholen muss. Diesen Transfer kriegt die CPU schneller zustande als der DMA-Controller.
A. K. schrieb: > Ob ein 66MHz AVR32 wirklich so viel schneller ist als ein 100MHz > Cortex-M3 (LPC1700)? Weder USB noch Bus sind hier m.E. das zentrale > Problem, sondern das Bitgepfriemel frisst die Leistung. Die > USB-Interrupts und Blocktransfers kommen da nur noch oben drauf. Sehe ich auch so. Ein 16-Bit Päckchen braucht 32 Shift-Befehle, die jeweils einen Takt brauchen. Bei 66MHz wäre der Controller damit also etwa zur Hälfte ausgelastet. Vielleicht noch 20% Rechenleistung für die Schleife. Bleiben 30% für die Reaktion auf den USB-Interrupt und die Programmierung des DMA, der die bereits behandelten Daten rausspeichert. Käme auf einen (Simulations-) Versuch an, ob man mit der Zeit auskommt. Ich halte das aber für möglich.
Jörg schrieb: > Ist es eigentlich ratsam bei USB ein O/S einzusetzen? Nein, das denke ich nicht. > Oder ist es > schneller wenn mann vom jeweiligen Chiphersteller den Source bekommt für > die USB-Treiber Implementierung? Ebendies. ST hat Code für den USB-Support. Inwieweit der hier direkt geeignet ist oder etwas umgebaut werden muss weiss ich nicht. Das wird bei Atmel, NXP und TI nicht anders sein.
PS: Wenn ich hier STM32 erwähne, dann weil ich die besser kenne als die LCP1700. Prinzipielle Unterschiede in der Vorgehensweise dürfte es dabei nicht geben, vielleicht arbeitet NXP beim USB etwas anders, aber das ändert wenig am Arbeitsprinzip insgesamt. Die 100MHz eines LPC1700 könnten jedoch nützlich sein.
Detlev T. schrieb: > Sehe ich auch so. Ein 16-Bit Päckchen braucht 32 Shift-Befehle, die > jeweils einen Takt brauchen. Bischen mehr ist es, denn die Daten kommen aus Speicher und müssen wieder in Speicher zurück. Wahrscheinlich lässt sich das zeitsparend mit dem Transfer der Daten aus dem USB-RAM verbinden, womit auch noch einer der 3 Puffer entfällt. Dann liegt der Hauptteil der CPU-Last im USB-Interrupt. Entscheidend ist also, ob ein Controller diese Last schafft. Die DMA-gesteuerte Ausgabe ist für die Abschätzung dagegen kaum relevant.
Jörg schrieb: >>(2) Irgendwo zwischen (1) und (3) sitzt jemand, der deine 9KB vom Kopf >>auf die Füsse stellt, indem er die Bits im Speicher neu sortiert. > > richtig, ein Controller (welcher muss noch gefunden werden); Ich rieche da ein mögliches Missverständnis. Mit 1-3 waren Abläufe im zu findenden Controller gemeint und mit dem "sitzt jemand" ein Stück Programm.
vielleicht probier ich mal einen LPC2927 mit 125MHz http://www.standardics.nxp.com/products/lpc2000/lpc29xx/ klingen gut, Flash und RAM intern so dass keine weiteren Transaktionen über das ExtMem sein müssen und USB Fullspeed sowie ein ExtMem
Zur Abschätzung der USB-Leistung vielleicht ganz interessant: Mit einem AT91SAM7 (48 MHz) hab ich mit Bulk Transfers ca. 800-900 kiB/s geschafft. Dabei wurden immer 10 kiB Puffer gesendet. Ohne Optimierung waren die Interrupts zu lange, anscheinend war der damit also ganz schön beschäftigt.
@Jörg: An deiner Stelle würde ich einen nehmen, die man kaufen kann.
hast recht - die LPC2917/01 oder LPC2919/01 sind leichter zu bekommen bei der gleichen Frequenz.... bekomm ich auf jeden Fall bei Digikey (das is erstmal in Ordnung, da für eine Platine eh mehr anfällt). >Zur Abschätzung der USB-Leistung vielleicht ganz interessant: Mit einem >AT91SAM7 (48 MHz) hab ich mit Bulk Transfers ca. 800-900 kiB/s >geschafft. Danke für diesen Leistungsvergleich. >Ohne Optimierung waren die Interrupts zu lange, anscheinend war der damit >also ganz schön beschäftigt. welche Optimierung sprichst du hier vor allem an?
Abgesehen von der Frage zur USB-Performance dürfte die Bitschubserei erst mit mindestens 17 freien Registern optimal arbeiten. Was ARMs und AVR32 schlechter stellt als beispielsweise MIPS oder PowerPC.
welche unterschiede sind das die du bezüglich der PowerPCs ansprichst? Könnt ich noch durch das Umschalten auf Thumb-Mode etwas an performance gewinnen was die Bitschubserei angeht?
Jörg schrieb: > welche unterschiede sind das die du bezüglich der PowerPCs ansprichst? Vielleicht habe ich die Bitschubserei auch nicht richtig verstanden. Aber was bei mir rüberkam sind 16 Register als Datenquelle und eines als Ziel. Die 16 werden nacheinander geschoben und nach jeder solchen Aktion wird das rausgeschobene Bit ins Zielregister reingeschoben. Ergibt an Registern 16 für rein, 1 für raus, 2 für Adressen als Minimum. Nun haben AVR32 und ARM aber nur 16 Register, davon 13 frei verwendbar. MIPS und PowerPC haben insgesamt 32 Register. Ich habe nur nicht parat, ob die den dafür nötigen rotate-with-carry/add-with-carry Befehl kennen. Der Thumb-Mode bringt nichts.
Jörg schrieb:
> welche Optimierung sprichst du hier vor allem an?
Compileroptimierung. Zum Debuggen wollte ich eigentlich -O0, aber damit
hat dann kein USB funktioniert. Schlussendlich bin ich bei -O2 gelandet.
Ich weiß jetzt nicht, wieviel das tatsächlich ausmacht, aber der
Controller langweilt sich auf jeden Fall nicht, wenn er mit Daten
zugeballert wird.
Karl schrieb: > Compileroptimierung. Zum Debuggen wollte ich eigentlich -O0, aber damit > hat dann kein USB funktioniert. Schlussendlich bin ich bei -O2 gelandet. Das ist klar, der Unterschied ist gewaltig. Dazu kommt evtl. noch die Platzierung, denn die SAM7 können mangels Flash-Bandbreite nativen ARM Code nicht ungebremst im Flash ausführen, sondern müssen auf RAM ausweichen. Hier könnte zwar nicht Thumb, wohl aber Cortex mit gegenüber ARM7 oder ARM9 erheblich kleinerem Interrupt-Overhead punkten, jedenfalls bei IRQ in C und nicht FIQ in Assembler. Wenn die einzelnen Interrupts eher kurz sind (ist das der Fall gewesen?) und man sowas auf ARM7/9 macht, dann könnte das ein Fall für FIQ in Assembler sein.
>Registern 16 für rein, 1 für raus, 2 für Adressen als Minimum das mit den Registern stimmt, wusste bloß nicht dass die anderen beiden Architekturen mehr Register zur Verfügung haben. > hat dann kein USB funktioniert. Schlussendlich bin ich bei -O2 gelandet. was wird hier alles optimiert gegenüber dem -00?
Jörg schrieb:
> was wird hier alles optimiert gegenüber dem -00?
Bei -O0 liegen beispielsweise alle Parameter und Variablen im RAM statt
in Registern, sie werden bei jeder Verwendung erneut geladen und/oder
gespeichert. Allein dieser Unterschied ist exorbitant.
Es gibt noch jede Menge mehr Optimierungen unterschiedlicher Bedeutung.
Puh, das ist alles schon ein paar Jährchen her. Die Interrupts waren, ähm, mittellang, in C und AFAIR im Ram, aber nicht als FIQ. Und als es dann lief war es auch ok, weil die restliche Anwendung dank DMA wenig Rechenzeit gebraucht hat. Das USB-Monster zu bändigen war schon genug Arbeit ;) Wenn man die häufigen Teile als FIQ und in Assembler macht, könnte das in der Tat deutlich schneller werden. Außerdem haben die Cortex M3 auch noch deutlich höhere Taktfrequenzen.
A. K. schrieb: > MIPS und PowerPC haben insgesamt 32 Register. Ich habe nur nicht parat, > ob die den dafür nötigen rotate-with-carry/add-with-carry Befehl kennen. Hab mal nachgesehen. MIPS hat nicht, PowerPC hat.
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.