Forum: Mikrocontroller und Digitale Elektronik µC gesucht mit Ext.Mem.Int, USB, DMA


von Jörg (Gast)


Lesenswert?

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

von nixwissender (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg (Gast)


Lesenswert?

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

von Karl (Gast)


Lesenswert?

Warum sortierst du nicht schon vorher um?

von Jörg (Gast)


Lesenswert?

hab leider keinen Einfluss was vor diesem µC passiert - sprich dem 
ankommenden USB-Stream.

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg (Gast)


Lesenswert?

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...

von Jörg (Gast)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

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.

von Detlev T. (detlevt)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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?

von Jörg (Gast)


Lesenswert?

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...

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg (Gast)


Lesenswert?

>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... ?

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg (Gast)


Lesenswert?

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.

von Jörg (Gast)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

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.

von Detlev T. (detlevt)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg (Gast)


Lesenswert?

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

von Karl (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

@Jörg: An deiner Stelle würde ich einen nehmen, die man kaufen kann.

von Jörg (Gast)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg (Gast)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

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.

von Karl (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg (Gast)


Lesenswert?

>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?

von (prx) A. K. (prx)


Lesenswert?

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.

von Karl (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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
Noch kein Account? Hier anmelden.