Forum: Mikrocontroller und Digitale Elektronik Puffer-Problem mit C8051F320 (8051)


von Mario G. (suicided)


Angehängte Dateien:

Lesenswert?

Hallo Forum!

Ich hänge zur Zeit an einer USB-Programmierung. Es müssen mindestens 250 
kbps übertragen werden. Hostseitig polle ich aller 100 ms. Das heißt, 
pro USB-Paket müssen 3125 Byte übertragen werden. Ich hab zur Sicherheit 
4 kB eingestellt.
Problem dabei ist, das ich im USB-Controller zawr ein so großese 
char-Array anlegen kann, sobald ich dieses jedoch bearbeiten will 
funktioniert nichts mehr. Der Compiler (IAR) findet keine Fehler und das 
Programm wird auch auf den Controller geflasht - danach passiert aber 
nichts mehr. Ich hab im Debugger RunToMain eingestellt, dort kommt er 
aber nie an. Der Debug-Adapter ist die ganze Zeit im Run-Modus, IAR 
reagiert nicht mehr. Die maximal mögliche Größe des Puffers liegt bei 
478 Byte - warum auch immer...

Ich befürchte, dass ich irgendwelche Compilereinstellungen treffen muss, 
mit denen ich mich nicht auskeene. Kann mir da vielleicht jemand helfen?

Vielen Dank
mario

von Ralf (Gast)


Lesenswert?

In 99% der Fälle sind Fehler, wie du sie beschreibst auf folgendes 
zurückzuführen:

- Verwendung von initialisierten Variablen im XDATA-Bereich
- Bedienen des defaultmäßig aktivierten Watchdogs erst ab der Main

Das Initialisieren der Variablen erfolgt bevor MAIN angesprungen wird. 
Da der Watchdog aber nach einem PowerUp aktiv ist, schlägt er während 
der Initialisierung zu, deswegen kommst du nicht zur Main.

Der IAR wird irgendeine STARTUP-Datei haben (so ist es zumindest bei 
Keil), in der du den zusätzlichen Assemblercode für das Deaktivieren des 
WD einstellen kannst. Somit passiert das vor der Initialisierung, und du 
erreichst dann auch die MAIN()-Routine :)

Ralf

PS: Warum legst du die Descriptoren nicht ebenfalls im Code-Speicher ab? 
Erstens verschwenden sie in deinem Fall nur XRAM, und zweitens werden 
sie normalerweise nicht geändert (was aber auch möglich ist, selbst wenn 
sie im Flash liegen).

von Ralf (Gast)


Lesenswert?

PPS: Was ist die von dir verwendete USB-API?

Ralf

von Ralf (Gast)


Lesenswert?

PPPS: Dir ist übrigens sicherlich bewusst, dass der F32x nur 2kB RAM 
hat?

von Mario G. (suicided)


Lesenswert?

Hallo und danke erstmal.
Die USB-API ist die von SiLabs (USBXpress). Der WatchDog ist deaktiviert 
- das wird in der sog. low_level_init gemacht. Die USB-Initialisierung 
hab ich 1:1 von Beispielen von SiLabs kopiert. Das mit den 2kB RAM ist 
mir auch bewusst, leider bin ich an diesen Controller gebunden - der war 
schon auf der Platine.
Gibt es nicht vielleicht doch eine Möglichkeit des Paket am Stück 
abzuarbeiten? Wenn ich das Pollingintervall verkürze, kommt der 
Controller zu nichts anderem mehr, was sich äußerst ungünstig auf seine 
eigentliche Aufgabe auswirkt.

VG
mario

von Ralf (Gast)


Lesenswert?

> Die USB-API ist die von SiLabs (USBXpress).
Ah, okay.

> Der WatchDog ist deaktiviert - das wird in der sog. low_level_init gemacht.
Was ich nicht sehen konnte :)

> Die USB-Initialisierung hab ich 1:1 von Beispielen von SiLabs kopiert.
Oh, da wär ich vorsichtig... Die MCUs sind spitze, aber die 
Beispielsoftware ist bisweilen... optimierungswürdig. Die pfriemeln halt 
meistens auf die Schnelle zusammen, für ne Demo langt das meist, aber 
auf Performance etc. wird da kaum geachtet...

> Das mit den 2kB RAM ist mir auch bewusst, ...
Dann frag ich mich, warum du dich wunderst, dass deinem Buffer nur knapp 
500Byte zugesprochen werden, v.a.dann, wenn du die Strings auch noch im 
XRAM ablegst, was die mögliche Maximalgröße des Puffers auch wiederum 
schmälert... Verwendest du wenigstens den vollen USB FIFO?

> ...leider bin ich an diesen Controller gebunden - der war schon auf der
> Platine.
Das tut ja mal nix zur Sache, entweder er ist geeignet oder nicht - dass 
er schon auf der Platte ist, hilft nix :)

> Gibt es nicht vielleicht doch eine Möglichkeit des Paket am Stück
> abzuarbeiten? Wenn ich das Pollingintervall verkürze, kommt der
> Controller zu nichts anderem mehr, was sich äußerst ungünstig auf seine
> eigentliche Aufgabe auswirkt.
Was wäre denn die "eigentliche" Aufgabe? Je mehr Informationen du gibst, 
desto besser kann dir geholfen werden :)

Ralf

von Mario G. (suicided)


Lesenswert?

Der Controller empfängt per SPI aus einem IEEE802.15.4 Daten mit bis zu 
250 kbps und soll diese an einen PC weiterreichen. Auf den USB-FIFO hab 
ich durch die USBXpress-Bibliothek keinen Zugriff. Die Bibl. ist 
compiliert - ich kann mir also auch nicht die Quellen anschauen. Die 
reine USB-Programmierung wollte ich mir eigentlich ersparen - das kostet 
zu viel Zeit. Meine eigentliche Aufgabe ist das 802.15.4-Netz.

Ich hatte gehofft, dass man die Variablen auch in irgendeinem anderen 
Speicherbereich ablegen kann - das geht aber nur, mit Konstanten. Die 
Struktur beim 8051 ist mir zugegebenermaßen noch nicht wirklich klar. 
Ich dachte das wird so 'ne learning by doing Sache... . . wohl nicht. 
Tja... dann muss ich mir wohl was anderes einfallen lassen. Die 
Descriptoren werde ich gleich mal in den Code-Speicher legen, das wird 
aber sehr wahrscheinlich nicht genügen.

Trotzdem Danke nochmal... hast mir sehr geholfen.
mario

PS: Warum kann man das Array ohne Probleme anlegen? Sollte da nicht 
eigentlich schon der Speicher reserviert werden? A: Der Compiler 
überspringt die Deklaration, weil das Array nie verwendet wird.

PPS: Die USB_Init-Methode will die Descriptoren nur aus dem RAM.

von Peter D. (peda)


Lesenswert?

Mario G. schrieb:
> Ich hab zur Sicherheit
> 4 kB eingestellt.

Weil 4kB mit Sicherheit nicht in einen 1kB FIFO passen werden???
Du mußt schon das Datenblatt mal anfassen.

> Die maximal mögliche Größe des Puffers liegt bei
> 478 Byte - warum auch immer...

Vermutlich sind die 1kB USB FIFO in je 512 fürs Senden und Empfangen 
aufgeteilt + einige Byte Headerkram.


Peter

von Ralf (Gast)


Lesenswert?

> Ich hatte gehofft, dass man die Variablen auch in irgendeinem anderen
> Speicherbereich ablegen kann - das geht aber nur, mit Konstanten.
Nein, das stimmt nicht. Du hast einmal den RAM vom 805x-Kern. Das sind 
bis zu 256 Byte (real mit Hardware- und reentrant-Stack und etc. etwa 
100 Byte).
Zusätzlich hast du bei deinem Controller 2kB RAM, sog.XRAM, da es sich 
im eXternen Speicher_bereich_ befindet. In beiden kannst du Variablen 
anlegen. In deinem Fall wird die Hälfte des verfügbaren XRAM für den 
USB-Hardware-FIFO verwendet. Die API kümmert sich um den Zugriff.

> Die Struktur beim 8051 ist mir zugegebenermaßen noch nicht wirklich klar.
> Ich dachte das wird so 'ne learning by doing Sache... . . wohl nicht.
> Tja... dann muss ich mir wohl was anderes einfallen lassen.
Was genau ist dir nicht klar an der Struktur? Bevor du sie nicht 
verstehst, wird dein Programm nicht effizient sein, also müssen wir 
dafür sorgen, dass du den Käfer verstehst :)

> Die Descriptoren werde ich gleich mal in den Code-Speicher legen, das wird
> aber sehr wahrscheinlich nicht genügen.
Aber es wird dir trotzdem schon mal ein paar Byte bringen. Du könntest 
zusätzlich auch mal das komplette Projekt in ein ZIP packen und hier 
anhängen, dann kann man sich das mal angucken, und Verbesserungen 
vornehmen.

> PS: Warum kann man das Array ohne Probleme anlegen? Sollte da nicht
> eigentlich schon der Speicher reserviert werden?
Du meinst das übergroße Array? Eigentlich sollte der IAR maulen, da hast 
du recht. Entweder eine falsche Einstellung gaukelt ihm mehr RAM vor, 
als er wirklich hat, oder eine Einstellung verhindert, dass eine Warnung 
ausgespuckt wird. Ich kann mir nicht vorstellen, dass sowas einfach 
akzeptiert wird vom IAR, aber genau sagen kann ich's nicht, ich verwende 
den Keil.
Apropo Keil, ich dachte die USBXpress ist nur für den Keil verfügbar? 
Gibts die mittlerweile auch für den IAR? oO

Ralf

von Ralf (Gast)


Lesenswert?

> PPS: Die USB_Init-Methode will die Descriptoren nur aus dem RAM.
Falsch. Das ist jetzt der Zeitpunkt, an dem ich vermute, dass du den 
ProgrammersGuide nicht aufmerksam gelesen hast. Die USB_INIT(...) will 
einen Pointer auf den String! Im ProgrammersGuide kann ich keinen 
MemorySpecific-Pointer im Prototyp sehen, also gehe ich davon aus, dass 
auch ein Generic-Pointer funktioniert -> Da stimmt also was an deiner 
Übergabe noch nicht ganz...

Ralf

von Mario G. (suicided)


Angehängte Dateien:

Lesenswert?

USB-Init möchte BYTE* und bekommt aber "unsigned char const __code *" 
wenn ich die Descriptoren im Code-Speicher ablege.
1
__code const BYTE USB_ProductStr[] = {0x10, 0x03, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'A', 0, 'P', 0, 'I', 0};
In der zip befindet sich diese Variante. Wenn ich auf BYTE* caste kommt 
am PC murks an - grundsätzlich gehts aber so.

Eine USBXpress Portierung für IAR ist bei der Kaufversion dabei. Durch 
die Portierung wird sich wohl der Datetyp für die Descriptoren geändert 
haben. Wie gesagt... ich habe keine Quellen und IAR hat selbst keine 
Beschreibung beigefügt. (Mich stört schon allein das BYTE! Warum kann 
man da nicht unsigned char hinschreiben statt #define BYTE unsigned 
char?)
Externer RAM war das Stichwort... jetzt wird mir so langsam einiges 
klar. Die Effizienz ist mir im übrigen nicht allzu wichtig. Der 
Controller soll nur Daten mit mind. 250 kbps weiterreichen - mehr nicht. 
Dafür werde ich wohl das Polling-Intervall deutlich verkürzen müssen.

von Mario G. (suicided)


Lesenswert?

Peter Dannegger schrieb:
> Weil 4kB mit Sicherheit nicht in einen 1kB FIFO passen werden???
> Du mußt schon das Datenblatt mal anfassen.

Block_Write kann lauf API-Beschreibung von 1 bis 4096 Byte mit einmal 
"aufnehmen"  - was die Bibliothek damit macht, weiß ich nicht. USB low 
level sind böhmische Dörfer für mich.

von Ralf (Gast)


Lesenswert?

> Block_Write kann lauf API-Beschreibung von 1 bis 4096 Byte mit einmal
> "aufnehmen"
Genau... auf einem F34x Device mit 4kB XRAM tut's das dann auch :)

> Wenn ich auf BYTE* caste kommt am PC murks an - grundsätzlich gehts aber
> so.
Hm, okay, dann müssen wir uns das eben genau angucken. Irgendwie muss es 
korrekt klappen.

> Wie gesagt... ich habe keine Quellen und IAR hat selbst keine
> Beschreibung beigefügt. (Mich stört schon allein das BYTE! Warum kann
> man da nicht unsigned char hinschreiben statt #define BYTE unsigned
> char?)
Gute Frage... Sag mal, beim Keil Compiler ist eine compiler_defs.H (oder 
ähnlich) dabei... Gibts die beim IAR auch? Wenn nicht, guck ich daheim 
mal danach. Vielleicht kann uns die helfen, richtig zu casten :)

> Externer RAM war das Stichwort... jetzt wird mir so langsam einiges
> klar.
Das freut mich :)

> Die Effizienz ist mir im übrigen nicht allzu wichtig. Der Controller
> soll nur Daten mit mind. 250 kbps weiterreichen - mehr nicht.
Sorry, aber für mich gehört Effizienz und "Daten schnell durchreichen" 
irgendwie zusammen zwinker

> Dafür werde ich wohl das Polling-Intervall deutlich verkürzen müssen.
Kann sein, aber lass uns erstmal gucken, was wir alles ausm Controller 
rausknautschen können, okay?

Ralf

von Peter D. (peda)


Lesenswert?

Mario G. schrieb:
> Block_Write kann lauf API-Beschreibung von 1 bis 4096 Byte mit einmal
> "aufnehmen"  - was die Bibliothek damit macht, weiß ich nicht. USB low
> level sind böhmische Dörfer für mich.

Eine Bibliothek kann aber nicht die Hardware austricksen.
Was nicht da ist, kann man auch nicht benutzen.


Ich bin mir auch ziemlich sicher, daß nicht der gesamte 2kB RAM vom USB 
benutzt werden kann, sondern nur die 1kB FIFO.


Peter

von Mario G. (suicided)


Angehängte Dateien:

Lesenswert?

Das hört sich super an! Danke!
Ich lege jetzt die beiden Arrays vor den Descriptoren an; in der 
Annahme, dass der RAM linear belegt wird. Alternativ könnte ich bei 
Konstanten auch eine Speicheradresse angeben. Mal schauen, wie groß ich 
das Sende-Array jetzt machen kann.
Vorher mess ich aber mal die Übertragungszeiten des USB um zu sehen, wie 
weit runter ich mit dem Polling-Intervall gehen kann.
Ich hab noch mal eine kommentierte und von allem Sinnlosen befreite 
Version der main.c angehängt.
Per SPI kommen die Daten übrigens mit knapp 500kbps. Es ist also 
sichergestellt, dass nach einem SPI-Paket nicht gleich wieder eins 
kommt. Diese Übertragungsgeschwindigkeit kann ich auch noch erhöhen 
(1/10 der Taktfrequenz vom USB-Controller - also 1,2 Mbps).

...wäre ja irgendwie paradox, wenn USB da der Flaschenhals wäre.

PS: BYTE ist in der USB_API.h definiert. Ob IAR sowas auch mit sich 
bringt, weiß ich nicht. Mir genügen die normalen c-Datentypen. ...und 
vielleicht mal eine Struktur. Ich bin aber noch nicht auf die Idee 
gekommen, die normalen Datentypen umzubennenen - auch wenn es Hostseitig 
byte gibt (ich verwende C#).

von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

Die schlechte Nachricht: Die von mir erwähnte Headerdatei ist nicht von 
Keil.
Die gute Nachricht: Sie ist von SiLabs :)
Siehe Anhang, vielleicht hilft dir das schon mal.
Bist mittlerweile weitergekommen, was die Strings bzw. die Pointer 
angeht?

Ralf

von Mario G. (suicided)


Lesenswert?

Ich hab mir mal das Speicherabbild im Debugger angeschaut (hätte ich 
auch früher drauf kommen können). Da siehts folgendermaßen aus:

       0x0000     1 Byte 0x08
0x0001-0x01A0   400 Byte 0xCD ?
0x01A1-0x01E0    64 Byte pac (InputBuffer)
0x01E1-0x03A0   448 Byte SPIbuffer
0x03A1-0x03FE   110 Byte Descriptoren, count und letzter freier Platz
0x03FF-0x07FF  1025 Byte 0x1A ?

Viel mehr lässt sich also nicht mehr rausholen. Die beiden großen 
Bereiche werden wohl von der USBXpress-Bibliothek belegt (bzw. halt die 
FIFOs fürs USB).

Die USB-ISR hat übrigens eine Laufzeit von ca. 2,8 ms mit 448 Byte 
Daten. Bei 448 Byte müssten man aber das Intervall auf 14 Sekunden 
setzen um auf 250 kbps zu kommen. Das würde aber bedeuten, dass der 
USB-Controller 20% der Rechenzeit in der blockierenden USB-ISR "hängt". 
Das wird knapp!

Mit den Strings bin ich nicht weiter gekommen. Im Prinzip geht es ja, 
wenn die im Code-Speicher liegen. Das Gerät heißt dann aber am Host 
nicht mehr "fine" sondern 1323&f2"R53 - oder so ähnlich. Trotzdem schon 
mal vielen Dank für "compiler_defs.h" - die werde ich mir zu Hause mal 
"reinziehen".

Das Brainstorming hier hat mir auf jeden Fall sehr geholfen. Ich werde 
dich auf dem Laufenden halten, wenn ich irgendwie weiter gekommen bin.

mario

von Ralf (Gast)


Lesenswert?

> Die beiden großen Bereiche werden wohl von der USBXpress-Bibliothek
> belegt (bzw. halt die FIFOs fürs USB).
Hm... Irgendwie kommt mir die Map komisch vor... Laut der USBXpress API 
Beschreibung holt sich die API 448 Byte im Bereich von 0x0640 - 0x07FF.
Ausserdem macht mich der Speicherbedarf des SPI Buffers etwas stutzig. 
Ist der wirklich so groß? Laut deiner Main.c ist der doch bloß 256 Byte 
groß, wo kommt der Rest her? Arbeitest du mit (unnötigen) globalen 
Variablen?

Würdest du mir mal deinen kompletten Code zukommen lassen? Ich hab zwar 
den IAR nicht, aber es würde helfen zu erkennen wo das Problem liegt 
(liegen könnte). Der Speicherverbrauch kommt mir einfach sehr hoch vor.

> Die USB-ISR hat übrigens eine Laufzeit von ca. 2,8 ms mit 448 Byte
> Daten. Bei 448 Byte müssten man aber das Intervall auf 14 Sekunden
> setzen um auf 250 kbps zu kommen. Das würde aber bedeuten, dass der
> USB-Controller 20% der Rechenzeit in der blockierenden USB-ISR "hängt".
> Das wird knapp!
Ja, moment... Bezüglich dem Hängen, BLOCK_WRITE kehrt zurück, wenn das 
letzte PAKET in den FIFO geschrieben wurde. Du schubst den SPI Buffer 
rein, das heisst, vier Pakete (64 Byte x 4 = 256). Deine 
Rechnung/Messung ist irgendwie falsch. Es müssten mindestens 7ms sein. 
Ein Paket pro Millisekunde, 448 Byte : 64 Byte = 7(ms).
Das heisst, deine 250kbs Daten müssten in etwa 488ms da sein: 64Byte * 
488 = 31232 Byte * 8 = ~250.000 Bit.

Woher kommen denn die 448 Byte? Dein SPI Buffer ist doch nur 256 Byte 
groß (laut der letzten angehängten Main.c).
Und wie kommst du auf die 14 Sekunden?

> Mit den Strings bin ich nicht weiter gekommen. Im Prinzip geht es ja,
> wenn die im Code-Speicher liegen. Das Gerät heißt dann aber am Host
> nicht mehr "fine" sondern 1323&f2"R53 - oder so ähnlich.
Oi! Was ist mit dem Hersteller- bzw. Produktstring? Ist der korrekt?

> Das Brainstorming hier hat mir auf jeden Fall sehr geholfen. Ich werde
> dich auf dem Laufenden halten, wenn ich irgendwie weiter gekommen bin.
Ich helfe gerne :)

Ralf

von Mario G. (suicided)


Lesenswert?

Die 448 Byte habe ich bei der Messung als Puffergröße festgelegt. Das 
war nachdem ich die main.c hier gepostet habe. ...hätte ich mir auch 
denken können, dass das Verwirrung stiftet. Es gibt sonst nur eine 
globale Variable (count). Die Zeit habe ich mittels PortPin (P2.7 siehe 
USB-ISR) und 'nem Oszi gemessen.
Woher hast du denn die eine Millisekunde pro (USB-) Paket? Das würde die 
gesamte Situation noch verschlechtern, da der USB-Controller dann ja 
knapp 50% mit USB beschäftigt wäre.
Die 14 Sekunden sollen natürlich 14 Millisekunden sein auf die ich 
folgendermaßen gekommen bin:

250.000 bps / 8 = 31.250 Bps
Das macht bei 448 Byte pro Paket ca. 70 Pakete pro Sekunde
31250 Bps / 448 BpP = 69,75 Pps
was wiederum ca. 14 ms pro Paket bedeuted.
1 / 70 Pps = 0,01429 spP

Hersteller- und Produktstring waren übrigens korrekt.

Ich nehme folgende Speicheraufteilung an:

1024 Byte für die FIFOs (am Ende des Speichers - mit 0x1A gefüllt beim 
Start)
 400 Byte für die USBXpress-API (mit 0xCD gefüllt; vielleicht hat der 
abweichende Wert hier etwas mit der IAR-Portierung zu tun)

Es bleiben also noch 624 Byte für die Descriptoren und die Anwendung 
übrig.
Meine Descriptoren sind insgesamt 52 Byte und der InptuBuffer 64 Byte 
lang. Abzülich der zwei Byte für die Zählvariable und dem einen Byte bei 
0x0000 (für was auch immer) bleiben 505 Byte für den SPIbuffer. Die 
nächstkleinere durch 64 Byte teilbare Zahl ist 448 Byte - wenn ich die 
Descriptoren aus dem RAM bekomme oder um mindestens 7 Byte verkleinere, 
vielleicht auch noch 512 Byte.

Sind die Strings funktionsrelevant? Eigentlich genügt doch die VendorID 
und die ProductID - oder?

Jedenfalls muss ich wohl damit leben. Ich könnte evtl. die Pakete auf 
den angeschlossenen µC auslagern und 64 Byte-weise im Intervall) an den 
USB-Controller schicken. So könnte ich den µC für die Übertragungszeit 
sperren (oder was anderes machen lassen) und der USB-Controller reicht 
das einfach nur durch (streamen quasi). Da muss ich aber alles noch mal 
umbauen. :(
Ich werde morgen mal probieren, wie sich das Gesamtsystem mit dem kurzen 
Polling-Intervall verhält.

Bis dahin... Gute Nacht.
mario

PS: Ach so... die main.c ist der komplette Code. es gibt lediglich noch 
die Header-Datei für die USB-API und die low_level_init.c - beide sind 
in der .zip weiter oben enthalten. ...wie auch die Bibliothek.

von Mario G. (suicided)


Lesenswert?

Zitat aus dem Programmers Guide: "It is useful to use the code keyword 
preceding the CustomString definitions, so that the strings are located 
in
code space."

So viel dazu. Dann wird das aller Wahrscheinlichkeit nach an der 
Portierung von/für IAR liegen. Die wollen an dieser Stelle BYTE* und der 
Compiler meckert rum, wenn er __code const BYTE* bekommt. ...zumal 
daraus eh __code const unsigned cahr * wird.

Ist das hier vielleicht noch 'ne Alternative um ein wenig mehr Platz zu 
bekommen? Gibts das bei IAR auch? (Ich hab bis jetzt solche Kommandos 
noch nciht benutzt.)

"Saving XDATA Space
The USB_Init function parameters are passed in direct memory locations 
in user XDATA space determined by the linker. If user firmware needs 
this contiguous space, these 17 bytes can be relocated to unused XDATA 
space within the USBXpress reserved area. To do this, the following 
should be added to the command line while invoking the linker (the value 
for “address” is shown in Table 1):
XDATA(?XD?_USB_INIT?USB_API(<address>))"

Laut Programmers Guide sind in den von dir angesprochenen 448 Bytes, die 
die Bibliothek belegt, die FIFOs bereits enthalten. Also entweder ich 
hab irgendeine notwendige Einstellung nicht getroffen oder der Portierer 
hat gepfuscht. Die main.c ist aber wirklich das ganze Programm.

VG
mario

von Ralf (Gast)


Lesenswert?

> Die 448 Byte habe ich bei der Messung als Puffergröße festgelegt. Das
> war nachdem ich die main.c hier gepostet habe. ...hätte ich mir auch
> denken können, dass das Verwirrung stiftet. Es gibt sonst nur eine
> globale Variable (count). Die Zeit habe ich mittels PortPin (P2.7 siehe
> USB-ISR) und 'nem Oszi gemessen.
Ah, okay, dann passt's ja wieder :)

> Woher hast du denn die eine Millisekunde pro (USB-) Paket?
Aus meinem um diese Uhrzeit leicht geschwächten Gedächtnis... Sorry, ich 
hab Transaktion mit Paket verwechselt. Pro Transaktion können bis zu 19 
Pakete versand werden, eine Transaktion erfolgt jede Millisekunde. So 
müsste das eher was werden :)

> Die 14 Sekunden sollen natürlich 14 Millisekunden sein ...
Okay, dann wär das auch geklärt. Aber das kann ja nicht sein, dass der 
Käfer so langsam ist, da haben wir noch irgendwo n Denkfehler bzw. n Bug 
im Code.

> Das macht bei 448 Byte pro Paket ca. 70 Pakete pro Sekunde
Ha, da ist das Verständnisproblem zwischen uns beiden:
- Ein USB Paket kann nur max.64 Byte haben. Von diesem Wert bin ich 
natürlich auch bei einigen der obigen Aussagen ausgegangen. Erklärt 
warum wir aneinander vorbei geredet haben :)

Wir müssen zusehen, dass du soviel XRAM wie möglich bekommst, damit der 
Buffer ordentlich gefüllt wird, und innerhalb einer USB Transaktion 
soviele Pakete wie möglich abgeschickt werden (Das Problem bei 
BulkTransfers die Priorität am niedrigsten, dafür die Bandbreite am 
höchsten ist).

> Hersteller- und Produktstring waren übrigens korrekt.
??? Oi... Interessant... Gucken wir uns auch noch an... Verwende bitte 
mal Großbuchstaben.

> Ich nehme folgende Speicheraufteilung an:
> 1024 Byte für die FIFOs (am Ende des Speichers - mit 0x1A gefüllt beim
> Start) 400 Byte für die USBXpress-API (mit 0xCD gefüllt; vielleicht hat
> der abweichende Wert hier etwas mit der IAR-Portierung zu tun)
??? Ne, das sind weniger für API + USB-FIFO, zumindest lt. der 
Beschreibung im PG.

> Es bleiben also noch 624 Byte für die Descriptoren und die Anwendung
> übrig.
> Meine Descriptoren sind insgesamt 52 Byte und der InptuBuffer 64 Byte
> lang. Abzülich der zwei Byte für die Zählvariable und dem einen Byte bei
> 0x0000 (für was auch immer) bleiben 505 Byte für den SPIbuffer. Die
> nächstkleinere durch 64 Byte teilbare Zahl ist 448 Byte - wenn ich die
> Descriptoren aus dem RAM bekomme oder um mindestens 7 Byte verkleinere,
> vielleicht auch noch 512 Byte.
Das nächstkleinere Vielfache von 64 ist ja nicht relevant, wenn du das 
Maximum hergibst, ist das letzte Paket halt kleiner, was soll's?
Ja, die Descriptoren stopfen wir in den Code-Speicher und kneten die 
USB_INIT() dass sie die Dinger auch annimmt...

> Sind die Strings funktionsrelevant? Eigentlich genügt doch die VendorID
> und die ProductID - oder?
Würd ich nicht drauf wetten, ich könnt mir vorstellen, dass die Strings 
zumindest bei einigen Sachen relevant sind für die Treiber. Komisch ist, 
dass eben nur der String der Seriennummer falsch übermittelt wird...

> Jedenfalls muss ich wohl damit leben...
Nana, nicht gleich aufgeben... :)

> ... Da muss ich aber alles noch mal umbauen. :(
Ja, aber an der richtigen Stelle, kann doch nicht sein, dass das nicht 
geht. Andere User haben schon weit mehr Daten rausgepustet.

> Ich werde morgen mal probieren, wie sich das Gesamtsystem mit dem kurzen
> Polling-Intervall verhält.
Kannst du probeweise mal machen.

> PS: Ach so... die main.c ist der komplette Code. es gibt lediglich noch
> die Header-Datei für die USB-API und die low_level_init.c - beide sind
> in der .zip weiter oben enthalten. ...wie auch die Bibliothek.
Roger, ich guck mal rein (aber jetzt nimmer).

> So viel dazu. Dann wird das aller Wahrscheinlichkeit nach an der
> Portierung von/für IAR liegen. Die wollen an dieser Stelle BYTE* und der
> Compiler meckert rum, wenn er __code const BYTE* bekommt. ...zumal
> daraus eh __code const unsigned cahr * wird.
> Ist das hier vielleicht noch 'ne Alternative um ein wenig mehr Platz zu
> bekommen? Gibts das bei IAR auch? (Ich hab bis jetzt solche Kommandos
> noch nciht benutzt.)
Hm... Hast du das IAR Handbuch parat? Guck doch bitte mal im Kapitel 
Pointer, wie ein Generic-Pointer definiert ist, leg die Strings in den 
Code-Speicher, und mach einen TypeCast auf den Pointer-Typ, den 
USB_INIT() haben will. Wobei, das ja eigentlich nicht nötig sein sollte, 
wenn wir das mit der Seriennummer hinkriegen, schließlich tun die 
anderen beiden Strings ja...

> Laut Programmers Guide sind in den von dir angesprochenen 448 Bytes, die
> die Bibliothek belegt, die FIFOs bereits enthalten. Also entweder ich
> hab irgendeine notwendige Einstellung nicht getroffen oder der Portierer
> hat gepfuscht.
Das ist ja das was mich kekst, offenbar ist die API fest auf einen 
Endpunkt und Buffergröße beschränkt! argl

> Die main.c ist aber wirklich das ganze Programm.
Okay, ich guck morgen nochmal in aller Ruhe drüber, vielleicht find ich 
was.
Übrigens, auf welchen SiLabs Beispielen genau basiert deine Main.c?

Guäts Nächtle...

Ralf

von Mario G. (suicided)


Angehängte Dateien:

Lesenswert?

Hallo Ralf!


So... ich hab jetzt folgendes gemacht:

Polling-Intervall auf 14 Millisekunden: Führte dazu, das einige der 
stochasisch ankommenden SPI-Pakete verloren gegangen sind. Das könnte 
man sperren, was aber dazu führen wird, dass der angeschlossene µC für 
diese Zeit keine Pakete mehr aus dem Netz empfangen kann. -> 
Verringerung der Datenrate!

Descriptoren auf einen Buchstaben verkürzt: Die Dinger sind tatsächlich 
völlig irrelevant. Durch diese Verkleinerung konnte ich die Größe des 
Puffers auf 512 Byte erhöhen. Das ergibt aber immer noch ein 
Polling-Intervall von 16 Millisekunden um auf 250 kbps zu kommen.

Testweise die Bibliothek aus dem Projekt entfernt: Die Puffergröße war 
trotzdem auf einen Wert zwischen 786 und 1024 Byte beschränkt (hab ich 
nicht weiter ausprobiert).

Im Datenblatt des USB-Controllers steht auch - wie Peter schon gesagt 
hat, dass die USB-FIFOs 1 kB RAM verbrauchen. Vom Rest gehen nochmal 400 
Byte für die Bibliothek weg. Das, was dann noch übrig ist, ist das, 
womit man leben muss.
Die Beispiele waren übrigens nicht von SiLabs, sondern von IAR. In dem 
Ordner hab ich auch noch ein Beispiel für eine Dateiübertragung 
gefunden. Die benutzen den Flash als Zwischenspeicher (hab ich mal 
angehängt). Damit werde ich mich jetzt mal ein wenig beschäftigen. Wenn 
das auch nicht geht, dann werde ich das gesamte Kommunikationskonzept 
noch mal überarbeiten - die Logik einfach komplett auf den PC auslagern 
(momentan filtert der angeschlossene µC irrelevante Daten aus).

Vielen Dank nochmal
mario

von Ralf (Gast)


Lesenswert?

> Polling-Intervall auf 14 Millisekunden: ...
> Verringerung der Datenrate!
Muss aber möglich sein, ohne Datenverlust die gewünschte Menge zu 
übertragen (eigentlich sogar noch mehr Daten).

> Descriptoren auf einen Buchstaben verkürzt: ...
Ja, versuchsweise okay, aber wenn ich ein Gerät kaufe, welches sich nur 
mit einem Buchstaben anmeldet, würd ich nicht mal den Treiber 
installieren :)
Aber das gleiche sollte doch ohne Stringkürzung möglich sein, wenn die 
Descriptoren im Flash abgelegt sind. Hast du es auch mal nur mit Ziffern 
probiert?

> Testweise die Bibliothek aus dem Projekt entfernt: Die Puffergröße war
> trotzdem auf einen Wert zwischen 786 und 1024 Byte beschränkt (hab ich
> nicht weiter ausprobiert).
Irgendwie stimmt da was mit den Projekteinstellungen nicht... Wieviele 
Dialoge für die Projekteinstellungen gibts im IAR? Wenn es nicht 
allzuviele sind, kannst du mal ScreenShots posten?

> Im Datenblatt des USB-Controllers steht auch - wie Peter schon gesagt
> hat, dass die USB-FIFOs 1 kB RAM verbrauchen.
Nein, da steht, dass 1kB des XRAMs als FIFO für die Endpunkte dienen 
können, wobei jeder Endpunkt eine bestimmte Teilmenge des FIFOs 
erhält... Würde ich also so interpretieren, dass nicht verwendete 
Endpunkte auch keinen FIFO-Speicher brauchen - was die Sache wieder 
etwas besser machen sollte...

> Vom Rest gehen nochmal 400 Byte für die Bibliothek weg. Das, was dann
> noch übrig ist, ist das, womit man leben muss.
Dann muss das entweder ein wahnsinnig schlechter Port der Keil Lib sein, 
oder IAR hat da was völlig eigenes hochgezogen...

> Die Beispiele waren übrigens nicht von SiLabs, sondern von IAR. In dem
> Ordner hab ich auch noch ein Beispiel für eine Dateiübertragung
> gefunden. Die benutzen den Flash als Zwischenspeicher (hab ich mal
> angehängt).
Die verwenden den Flash halt quasi als Ultra-Mini-Speicherkarte :)

Ganz ehrlich, momentan befürchte ich, dass der F320 nicht das Problem 
ist, sondern der IAR... Bist du an den IAR gebunden?

Ralf

von Bernd N (Gast)


Lesenswert?

Es gibt eine Portierung auf den SDCC, siehe:

http://sdccokr.dl9sec.de/resources.htm

Als Vorlage diente die Keil Version.

von Bernd N (Gast)


Lesenswert?

Noch ein Hinweis, SDCC läßt sich sehr gut in die Silabs IDE einbinden:

http://www.silabs.com/Support%20Documents/TechnicalDocs/an198.pdf

So hat man quasi die Keil Umgebung mit einem freien C Compiler.

von Mario G. (suicided)


Angehängte Dateien:

Lesenswert?

> Muss aber möglich sein, ohne Datenverlust die gewünschte Menge zu
> übertragen (eigentlich sogar noch mehr Daten).
Das ist im momentanen Gesamtsystem problematisch, da nicht vorhergesehen 
werden kann, wann per SPI ein Paket kommt. Duch das kurze 
Polling-Intervall kommt es dadurch weitaus häufiger vor, dass ein Paket 
kommt, während die USB-API den SPI-Interrupt blockiert.

> Ja, versuchsweise okay, aber wenn ich ein Gerät kaufe, welches sich nur
> mit einem Buchstaben anmeldet, würd ich nicht mal den Treiber
> installieren :)
Das soll nicht verkauft werden. Es war ja eigentlich auch recht 
unproblematisch mit den Descriptoren im Flash - wird halt der Name 
falsch angezeigt. Die "paar" Byte helfen aber auch nicht großartig 
weiter.

> Irgendwie stimmt da was mit den Projekteinstellungen nicht... Wieviele
> Dialoge für die Projekteinstellungen gibts im IAR? Wenn es nicht
> allzuviele sind, kannst du mal ScreenShots posten?
Screenshots von allen Einstellungen sind angehängt.

> Dann muss das entweder ein wahnsinnig schlechter Port der Keil Lib sein,
> oder IAR hat da was völlig eigenes hochgezogen...
Im ProgrammersGuide steht aber, das die Bibliothek 448 Byte im RAM 
belegt. Van daher wäre die Portierung ja sogar noch besser.

> Ganz ehrlich, momentan befürchte ich, dass der F320 nicht das Problem
> ist, sondern der IAR... Bist du an den IAR gebunden?
Jein. Mehr ja als nein. IAR wird mir halt zur Verfügung gestellt.

Ich hab mir nochmal den Speicher angeschaut. Ab USB_Clock_Start(); wird 
der Speicher von 0x0400 bis 0x063F und von 0x0740 bis 0x07FF 
vollgeschrieben. Zwischendrin sind nochmal 256 Byte frei bzw. es steht 
0x00 drin. Ich frage mich nur, was die Bibliothek mit den 400 Byte 
macht. Da steht selbst nach einer Zeit in Betrieb ausschließlich 0xCD 
drin. Lediglich die 16 Byte danach ändern sich. (Danach kommt der 
InputBuffer.)

Ich werde das gesamte System einfach nochmal überdenken. Die 
Vorraussetzungen haben sich ja schon gewaltig verändert. Ich war bei USB 
von 12 Mbps bzw. mindestens von 1,5 Mbps ausgegangen. Brutto hat der das 
bestimmt auch. Durch die Bibliothek geht aber zu viel Zeit verloren. Das 
Polling-Intervall kann ich um einiges verkürzen, wenn ich die 
Verarbeitung der Daten komplett auf dem PC dürchführe und den µC quasi 
mit dem USB-Controller synchronisiere - ist halt nur 'n bissl Arbeit.

Nichts desto trotz kannst du ja mal schauen, ob ich vielleicht doch 
irgendwo 'nen Fehler in den Einstellungen habe.

Danke nochmal
mario

von Ralf (Gast)


Lesenswert?

> Das ist im momentanen Gesamtsystem problematisch, da nicht vorhergesehen
> werden kann, wann per SPI ein Paket kommt. Duch das kurze
> Polling-Intervall kommt es dadurch weitaus häufiger vor, dass ein Paket
> kommt, während die USB-API den SPI-Interrupt blockiert.
Wie ist denn die Paketgröße, die in einem Rutsch von deinem SPI 
empfangen wird? Mit welcher Geschwindigkeit wird der SPI-Bus getaktet?

> Das soll nicht verkauft werden. Es war ja eigentlich auch recht
> unproblematisch mit den Descriptoren im Flash - wird halt der Name
> falsch angezeigt. Die "paar" Byte helfen aber auch nicht großartig
> weiter.
Mag sein, aber es macht halt stutzig, wenn schon sowas "einfaches" nicht 
richtig tut...

> Im ProgrammersGuide steht aber, das die Bibliothek 448 Byte im RAM
> belegt. Van daher wäre die Portierung ja sogar noch besser.
Du hast geschrieben, dass die 1kB weg sind PLUS die 400 der Lib. Halte 
ich für schlechter :)

> Ich hab mir nochmal den Speicher angeschaut. Ab USB_Clock_Start(); wird
> der Speicher von 0x0400 bis 0x063F und von 0x0740 bis 0x07FF
> vollgeschrieben. Zwischendrin sind nochmal 256 Byte frei bzw. es steht
> 0x00 drin.
Ab hier wird es interessant, denn:
- wir gehen zwar immer hübsch von den Angaben der USBXpress Unterlagen 
aus, aber die sind wie gesagt für den Keil Compiler geschrieben. Die 
Unterlagen sagen, dass die Lib den Speicher von 0x640-0x7FF verwendet -> 
die angegebenen 448 Byte, entsprechen vom Adressbereich den FIFOs der 
Endpunkte 0 bis 2 -> Endpunkt 0 ist bei jedem Gerät immer aktiv, laut 
Beschreibung wird aber für die Daten nur Endpunkt 2 verwendet, das 
heisst, der FIFO des Endpunkt 1 ist für die Lib-internen Daten.

- Dein Debugger sagt, der Speicher von 0x400-0x63F sowie 0x740-0x7FF 
wird verwendet -> 576 Byte + 192 Byte = 768 Byte, vom Adressbereich sind 
das die FIFOs der Endpunkte 0, 1 und 3 sowie die 64 freien Byte im FIFO. 
Die 256 Byte dazwischen entsprechen genau dem FIFO des Endpunktes 2.
- Du sagst, die 256 Byte bleiben quasi unberührt. Entweder sagt der 
Debugger was falsches, oder der IAR Port der API verwendet für die Daten 
die Endpunkte 1 und 3 (unwahrscheinlich, denn dann wär's ja absolut 
nicht kompatibel)

> Ich frage mich nur, was die Bibliothek mit den 400 Byte macht. Da steht
> selbst nach einer Zeit in Betrieb ausschließlich 0xCD drin. Lediglich
> die 16 Byte danach ändern sich. (Danach kommt der InputBuffer.)
Absolut keine Änderung? Das hört sich danach an, als ob der Debugger da 
keinen richtigen Zugriff bekommt. Die Lib will den Speicher sicher nicht 
umsonst :)

> Screenshots von allen Einstellungen sind angehängt.
Target.PNG:
- DataModell von LARGE auf SMALL ändern, sonst landen alle nicht 
explizit einem Speichertyp zugewiesenen Variablen in XDATA -> Es bietet 
sich bei allen Projekten an, auf SMALL zu bleiben, da dort auf die 
Variablen am schnellsten zugegriffen werden kann. Große Buffer usw. legt 
man explizit in XDATA ab.
- Location for constants and strings = CODE memory. Guck mal, ob das was 
bringt (trotz der bereits explizit in CODE abgelegten Strings)
- Calling convention kenne ich nicht, müsste ich nachlesen. Ich vermute, 
dass sich die Einstellung automatisch ändert, wenn das DataModell 
angepasst wird.

Optimizations.PNG:
- Level auf High setzen, in der Liste die Größenoptimierung wählen

STACK-HEAP.PNG:
- bin nicht sicher, ob eine Änderung hier was bringt (wenn du das 
DataModell umstellst, sollte das eigentlich reichen), aber mal 
angenommen, das ursprüngliche DataModell = LARGE verwendet XDATA, dann 
würde ja ab 0x1A0 irgendein Stack angelegt werden -> evtl. wird Speicher 
frei, wenn DataModell SMALL ist

OUTPUT2-4.PNG:
- Hm...auch hier bin ich nicht sicher, ob da irgendwelche der 
DEBUG-Infos im Programm landen, oder nur in speziellen Dateien für den 
Debugger

> Ich war bei USB von 12 Mbps bzw. mindestens von 1,5 Mbps ausgegangen.
> Brutto hat der das bestimmt auch. Durch die Bibliothek geht aber zu viel
> Zeit verloren. Das Polling-Intervall kann ich um einiges verkürzen, wenn
> ich die Verarbeitung der Daten komplett auf dem PC dürchführe und den µC
> quasi mit dem USB-Controller synchronisiere - ist halt nur 'n bissl
> Arbeit.
USB basiert auf fest einzuhaltenden Timings, die 12Mbps sind also sicher 
da :) Sicherlich ist da LowLevel-Protokoll-Overhead mit dabei, aber mehr 
als maximal 10% gehen da nicht hops. Deswegen interessiert mich ja dein 
Problem so arg (abgesehen von meiner angeborenen, natürlichen 
Hilfsbereitschaft), denn ich hab hier mehrere SiLabs DevKits rumflöten 
:)

Hm... Ich könnte mal deine Main.C nehmen, und dir ein HEX-File mit dem 
Keil Compiler und der "originalen" Lib generieren. Wäre alles ohne 
Gewähr auf Funktion, und natürlich auf eigenes Risiko deinerseits.

Ralf

von Mario G. (suicided)


Lesenswert?

> Wie ist denn die Paketgröße, die in einem Rutsch von deinem SPI
> empfangen wird? Mit welcher Geschwindigkeit wird der SPI-Bus getaktet?
Der SPI-BUS läuft mit knapp 500 kbps - kann aber noch schneller (ca. 
2x). Die Pakete haben unterschiedliche Größen (momentan 10 bis 25 Byte). 
Sie kommen per Funk am µC an, werden dort vom Overhead befreit und 
gleich per SPI weiter gesendet. Der USB-Controller sammelt die Pakete 
hintereinander im Puffer und schickt den alle 100 Millisekunden an den 
PC (so wars jedenfalls konzipiert).

> Du hast geschrieben, dass die 1kB weg sind PLUS die 400 der Lib. Halte
> ich für schlechter :)
Das sind ja zwei unterschiedliche Dinge. Laut Datenblatt geht 1 kB für 
die (LowLevel-) USB-FIFOs weg. Die Bibliothek bruach extra nochmal 448 
Byte - wenn ich das richtig verstanden habe.

> USB basiert auf fest einzuhaltenden Timings, die 12Mbps sind also sicher
> da :) Sicherlich ist da LowLevel-Protokoll-Overhead mit dabei, aber mehr
> als maximal 10% gehen da nicht hops. Deswegen interessiert mich ja dein
> Problem so arg (abgesehen von meiner angeborenen, natürlichen
> Hilfsbereitschaft), denn ich hab hier mehrere SiLabs DevKits rumflöten
> :)
Nach meiner Rechnung dürfte die Übertragung von 512 Byte mit 12 Mbps ca. 
342 Mikrosekunden dauern. Selbst mit viel Overhead vielleicht so 'ne 
halbe Millisekunde. Gemessen hab ich über zwei Millisekunden (für die 
USBXpress-ISR). Da scheint also noch mal über das dreifache der 
eingentlichen Übertragungszeit für Funktionsaufrufe und Logik allg. 
drauf zu gehen. ...oder durch den Bulk-Transfer. Laut Beschreibung 
werden die Daten da bis zu drei mal wiederholt. USBXpress ist damit von 
Grund auf "suboptimal". Vielleicht sollte ich mal 'ne USB-Leitung 
auftröseln und die Pakete mitm Logikanalysator anschauen...

> Hm... Ich könnte mal deine Main.C nehmen, und dir ein HEX-File mit dem
> Keil Compiler und der "originalen" Lib generieren. Wäre alles ohne
> Gewähr auf Funktion, und natürlich auf eigenes Risiko deinerseits.
Den Service würde ich gern in Anspruch nehmen. ;-) Danke!

mario

von Ralf (Gast)


Lesenswert?

> Der SPI-BUS läuft mit knapp 500 kbps - kann aber noch schneller (ca.
> 2x). Die Pakete haben unterschiedliche Größen (momentan 10 bis 25 Byte).
> Sie kommen per Funk am µC an, werden dort vom Overhead befreit und
> gleich per SPI weiter gesendet. Der USB-Controller sammelt die Pakete
> hintereinander im Puffer und schickt den alle 100 Millisekunden an den
> PC (so wars jedenfalls konzipiert).
Hm... Okay, dann blick ich da schon ein bisschen besser durch was da 
passiert bzw. passieren soll.

> Das sind ja zwei unterschiedliche Dinge. Laut Datenblatt geht 1 kB für
> die (LowLevel-) USB-FIFOs weg. Die Bibliothek bruach extra nochmal 448
> Byte - wenn ich das richtig verstanden habe.
Tja, das ist jetzt die Frage. In der USBXpress Beschreibung auf Seite 24 
in der Tabelle steht:
1
XDATA space reserved by the library:
2
448 bytes XDATA (0x0640 to 0x07FF) *[includes USB FIFO space]*
Ebenfalls steht dort, dass nur Endpunkt 2 verwendet wird, was die 
Aussage, dass der FIFO-Speicher bereits mit verwendet wird, untermauert, 
da der passende Adressbereich belegt wird.

> Nach meiner Rechnung dürfte die Übertragung von 512 Byte mit 12 Mbps ca.
> 342 Mikrosekunden dauern. Selbst mit viel Overhead vielleicht so 'ne
> halbe Millisekunde. Gemessen hab ich über zwei Millisekunden (für die
> USBXpress-ISR). Da scheint also noch mal über das dreifache der
> eingentlichen Übertragungszeit für Funktionsaufrufe und Logik allg.
> drauf zu gehen.
Nachdem ich jetzt ein bisschen besser durchblicke, was da passieren 
soll, glaube ich, dass es auch daran liegen kann, wie du die USB 
Interrupts programmiert hast. Weiter unten schreib ich noch was dazu (*)

> ...oder durch den Bulk-Transfer. Laut Beschreibung werden die Daten da
> bis zu drei mal wiederholt. USBXpress ist damit von Grund auf
> "suboptimal".
Okay, so gesehen schon, denn BULK garantiert zwar Bandbreite, hat aber 
die niedrigste Priorität auf dem Bus. Wobei... Die benötigte Bandbreite 
muss ja in den Descriptoren stehen... Was steht denn im entsprechenden 
Descriptor?

> Vielleicht sollte ich mal 'ne USB-Leitung auftröseln und die Pakete mitm
> Logikanalysator anschauen...
Lass mal sein, ich glaub nicht, dass ein normaler LA ohne passende 
Messstrippen das genau genug erkennen kann bzw. den Bus evtl. kapazitiv 
zu arg belastet. Ausserdem sollte er dann das Protokoll unterstützen, 
sonst suchst du dir ja n Wolf... Nimm für den Anfang lieber mal einen 
Software-USB-Analyzer, die sollten für den Anfang reichen...

> Den Service würde ich gern in Anspruch nehmen. ;-) Danke!
Jo, mach ich. Soll ich die Main.c vom 10.02.2010 17:52 nehmen oder 
willst du mir die aktuelle Version "opfern"?

(*)Bzgl. der USB-Interrupts, ich kann momentan nur von der 
auskommentierten Variante der Main.c ausgehen, bei der du offenbar im 
RX_Interrupt darauf reagierst, bei Datenempfang vom Rechner den 
kompletten SPI-Buffer zu schicken. Hab ich das so richtig erfasst?
Das ist alles irgendwie wachsweich, mit SPI-Interrupt sperren, etc und 
dann aus dem RX-Interrupt raus senden(selbst wenn's in dem Fall ja nur 
für's Messen war). Das hängt wahrscheinlich auch ein bisschen damit 
zusammen, dass du den 805x-Kern noch nicht durchschaut hast :) Ist ja 
nicht schlimm, ich kann versuchen, aus der Main.c eine Version zu 
machen, von der ich glaube, dass sie das besser umsetzt. Falls du das 
willst...
Aber heut wird das nix mehr :( Stehst du da arg unter Zeitdruck bei dem 
Projekt?

Ralf

von Mario G. (suicided)


Lesenswert?

> Okay, so gesehen schon, denn BULK garantiert zwar Bandbreite, hat aber
> die niedrigste Priorität auf dem Bus. Wobei... Die benötigte Bandbreite
> muss ja in den Descriptoren stehen... Was steht denn im entsprechenden
> Descriptor?
Wo muss ich denn da suchen? Ich hab nur die drei Strings und die paar 
anderen Werte für PID und VID...

> Nimm für den Anfang lieber mal einen
> Software-USB-Analyzer, die sollten für den Anfang reichen...
Das mach ich. ...wusste bis eben nicht, dass es sowas für USB gibt.

> Jo, mach ich. Soll ich die Main.c vom 10.02.2010 17:52 nehmen oder
> willst du mir die aktuelle Version "opfern"?
Ich poste morgen nochmal 'ne aktuelle Version. ~hab zwar nicht viel 
geändert, aber sicher ist sicher.

> (*)Bzgl. der USB-Interrupts, ich kann momentan nur von der
> auskommentierten Variante der Main.c ausgehen, bei der du offenbar im
> RX_Interrupt darauf reagierst, bei Datenempfang vom Rechner den
> kompletten SPI-Buffer zu schicken. Hab ich das so richtig erfasst?
Ja. Wenn ich Device-seitig die Paketgröße auf die tatsächliche Größe 
anpasse, bekomme ich Host-seitig Probleme, da ich ja dort die Anzahl der 
zu empfangenden Bytes angeben muss - die der Host ja nicht kennt.

> Das ist alles irgendwie wachsweich, mit SPI-Interrupt sperren, etc und
> dann aus dem RX-Interrupt raus senden(selbst wenn's in dem Fall ja nur
> für's Messen war). Das hängt wahrscheinlich auch ein bisschen damit
> zusammen, dass du den 805x-Kern noch nicht durchschaut hast :) Ist ja
> nicht schlimm, ich kann versuchen, aus der Main.c eine Version zu
> machen, von der ich glaube, dass sie das besser umsetzt. Falls du das
> willst...
> Aber heut wird das nix mehr :( Stehst du da arg unter Zeitdruck bei dem
> Projekt?
Zeitdruck habe ich nicht. Das System funktioniert aufgrund der 
beschränkten Anzahl an Funkteilnehmern problemlos. Ich will aber die 
maximale Datenrate des Netzes auch zum PC garantieren können.
Das Sperren des SPI-Interrupts wollte ich im nächsten Schritt auf den µC 
auslagern. Der sollte quasi die Daten weiter sammeln, bis der 
USB-Controller wieder Zeit hat. Das wäre im Prinzip die Lösung dafür, 
das Polling-Intervall stark zu verkürzen. Durch die schnelle 
SPI-Übertragung könnte man da locker in den Bereich so um zehn 
Millisekunden kommen. Synchronisieren würde ich das über einen PortPin, 
oder indem ich den USB-Controller zum SPI-Master mache. Das Verlagert 
das Problem zwar nur, der µC (übrigens auch ein 8051) ist aber ein klein 
wenig flexibler. ...oder ich nehme einfach einen Transceiver mit 
integriertem USB-Controller (CC2531 von TI z.B.).
 Alles irgendwie "wachsweich". Eigentlich hatte ich mich gefreut, dass 
es diese Bibliothek gibt. Über RS232 wäre alles viel einfacher 
gewesen... aber nicht so schön. :)

Es würde mich auf jeden Fall außerordentlich freuen, wenn du eine 
effektivere Lösung für dieses Problem "erfinden" würdest. So langsam 
bekomme ich aber ein schlechtes Gewissen - bei dem Lebenszeitverlust, 
den du mit mir hast. ;)

mario

von Ralf (Gast)


Lesenswert?

Moin Mario,

> Wo muss ich denn da suchen? Ich hab nur die drei Strings und die paar
> anderen Werte für PID und VID...
Hm... wenn man es in der API-Headerdatei nicht umstellen kann, wird es 
wohl fest in der Lib codiert sein :(

> Das mach ich. ...wusste bis eben nicht, dass es sowas für USB gibt.
Doch doch, wir haben hier auch ein oder zwei im Einsatz.

> Ich poste morgen nochmal 'ne aktuelle Version. ~hab zwar nicht viel
> geändert, aber sicher ist sicher.
Okay. N kompletter Schaltplan wäre vielleicht noch sinnvoll.

> Ja. Wenn ich Device-seitig die Paketgröße auf die tatsächliche Größe
> anpasse, bekomme ich Host-seitig Probleme, da ich ja dort die Anzahl der
> zu empfangenden Bytes angeben muss - die der Host ja nicht kennt.
Das müsste aber wurscht sein. Wenn der Host 128 Byte anfordert, das 
Gerät aber grad nur 100 Byte hat, müssten die 100 abgeholt werden und 
das Gerät dann die Kommunikation abbrechen, wenn ich's richtig im Kopf 
hab. Und es müsste alles vom jeweiligen Treiber abgefangen werden.

Nebenbei: Wie sieht denn eigentlich die Gegenstelle aus? Also welche 
Software aufm PC?

> Zeitdruck habe ich nicht.
Okay, dann können wir über's Wochenende ein bisschen experimentieren :)
Falls das für dich okay ist.

> Alles irgendwie "wachsweich". Eigentlich hatte ich mich gefreut, dass
> es diese Bibliothek gibt.
Sollst du auch :) Genau deswegen behaupte ich auch, dass es möglich sein 
muss. Im SiLabs-Forum sind höhere Datenraten mit XPress realisiert 
worden, also muss es gehen.

> Über RS232 wäre alles viel einfacher gewesen... aber nicht so schön. :)
Nja, schon, aber die stirbt halt langsam aus... andersrum machts ja auch 
Spass mal was neues zu lernen.

> Es würde mich auf jeden Fall außerordentlich freuen, wenn du eine
> effektivere Lösung für dieses Problem "erfinden" würdest. So langsam
> bekomme ich aber ein schlechtes Gewissen - bei dem Lebenszeitverlust,
> den du mit mir hast. ;)
Okay, meine Zeit auf dieser Welt ist (wie bei jedem anderen auch) 
natürlich beschränkt, aber ich hab ja auch n bisschen was davon, wenn 
ich dir helfe :) Ich hoffe im Gegensatz nur, dass es dann auch 
tatsächlich klappt :)

Ralf

von Peter D. (peda)


Lesenswert?

Mario G. schrieb:
> Das ist im momentanen Gesamtsystem problematisch, da nicht vorhergesehen
> werden kann, wann per SPI ein Paket kommt. Duch das kurze
> Polling-Intervall kommt es dadurch weitaus häufiger vor, dass ein Paket
> kommt, während die USB-API den SPI-Interrupt blockiert.

Warum redest Du immer wieder von Polling und Blockieren?

Der MC hat doch ein Hardware-USB.
Und da erwarte ich, daß man die Sendedaten in den FIFO schreibt und 
fertig, d.h. ich kann nun andere Sachen machen.
Und irgendwann kriege ich einen Interrupt, daß der PC die Daten abgeholt 
hat.

Bzw. da das ja ein FIFO ist, muß es auch eine Funktion geben, die mir 
sagt, wieviel im FIFO noch frei ist.
D.h. ich habe z.B. 16 Byte zu senden, frage ab und wenn dann >=16Byte 
frei sind, schreibe ich die in den FIFO, auch wenn der noch nicht leer 
ist.

Die Zeit für die Übertragung zum PC geht Dir also nicht verloren, die 
kannst Du fürs SPI und anderes benutzen.

Außerdem hat der 8051 vier Interruptprioritäten. Wenn der USB-Interrupt 
zu lange dauern sollte, dann mußt Du nur dem SPI-Interrupt eine höhere 
Priorität zuweisen und dann unterbricht er einfach das USB.


Peter

von Ralf (Gast)


Lesenswert?

Genau das wären so ein paar der Ansätze, die ich dann optimiert hätte.

Ralf

von Mario G. (suicided)


Lesenswert?

Hallo!

Entschuldigt bitte mein langes Schweigen - hatte heute keine Zeit für 
das Projekt.

> Das müsste aber wurscht sein. Wenn der Host 128 Byte anfordert, das
> Gerät aber grad nur 100 Byte hat, müssten die 100 abgeholt werden und
> das Gerät dann die Kommunikation abbrechen, wenn ich's richtig im Kopf
> hab. Und es müsste alles vom jeweiligen Treiber abgefangen werden.
Der Treiber fängt das leider nicht ab. Ich lese die Daten am Host mit 
der Bibliotheksfunktion SI_Read aus. Dort muss man die Anzahl der zu 
lesenden Bytes angeben. Kommen weniger als angegeben an, meldet die 
Bibliothek nach einem Timeout einen Fehler.

> Nebenbei: Wie sieht denn eigentlich die Gegenstelle aus? Also welche
> Software aufm PC?
Auf dem PC habe ich den Treiber von SiLabs, die DLL von SiLabs und 'nen 
Wrapper für C# für die DLL.

> Okay, dann können wir über's Wochenende ein bisschen experimentieren :)
> Falls das für dich okay ist.
Im Prinzip ist das vollkommen OK für mich, ich hab aber die Hardware 
nicht zu Hause - wird also leider nichts. Der Treiber läuft nur unter XP 
- selbst, wenn ich wöllte, könnte ich zu Hause nicht.

> ...andersrum machts ja auch Spass mal was neues zu lernen.
Ja! Allerdings!

Peter Dannegger schrieb:
> Warum redest Du immer wieder von Polling und Blockieren?
>
> Der MC hat doch ein Hardware-USB.
> Und da erwarte ich, daß man die Sendedaten in den FIFO schreibt und
> fertig, d.h. ich kann nun andere Sachen machen.
> Und irgendwann kriege ich einen Interrupt, daß der PC die Daten abgeholt
> hat.
Durch die USBXpress-Bibliothek jabe ich keinen direkten Zugriff auf die 
FIFOs - die Hardware wird -wie auch immer- von der LIB gehandhabt und 
die blockiert mein Programm. Ohne die LIB müsste ich mich um 
LowLevel-USB kümmern, wozu ich aber eigentlich keine Zeit habe.

Ich habe mich heute mit meinem ElCommandante darauf geeinigt, dass die 
Datenrate erstmal zweitrangig ist. Die werden wir eh nicht voll 
ausnutzen. Das eigentliche Thema sind energieeffiziente 
Routingprotokolle in drahtlosen AdHoc-Netzwerken, was wir natürlich auch 
testen wollen. Ich werden die beiden Controller daher jetzt noch 
synchonisieren - dass der µC dem USB-Controller nur Daten schickt, wenn 
der grad nicht in der Bibliothek festhängt. Damit komme ich auch auf 250 
kbps mit dem Nachteil, dass der µC ein kleines bisschen weniger Daten 
aus dem Funknetz aufnehmen kann. Das unterstützt aber 
Hardware-Acknowledge, weshalb da keine Daten verloren gehen.
In Zukunft werden wir dann sehr wahrscheinlich den CC2531 einsetzen. Das 
ist ein Transceiver mit integriertem USB-Controller. TI bietet dafür 
eine USB Firmware-Library an, die im Quellcode für IAR vorliegt. 
http://www.ti.com/litv/zip/swrc088c

Deine Vorschläge zu den Projekteinstellungen werde ich am Montag mal 
ausprobieren und die Ergebnisse hier posten. Ich hab ja die Hoffnung, 
dass das Synchonisieren erstmal zu einem Teilerfolg führt.

Vielen Dank nochmal und ein schönes Wochenende.
mario

von Peter D. (peda)


Lesenswert?

Mario G. schrieb:
> Der Treiber fängt das leider nicht ab. Ich lese die Daten am Host mit
> der Bibliotheksfunktion SI_Read aus. Dort muss man die Anzahl der zu
> lesenden Bytes angeben. Kommen weniger als angegeben an, meldet die
> Bibliothek nach einem Timeout einen Fehler.

Dann mußt Du eben ein Protokoll aufsetzen.
Z.B. Du sendest immer 2 Pakete. Das erste Paket hat eine konstante Länge 
und teilt nur die Länge des zweiten Datenpakets mit.


> Durch die USBXpress-Bibliothek jabe ich keinen direkten Zugriff auf die
> FIFOs - die Hardware wird -wie auch immer- von der LIB gehandhabt und
> die blockiert mein Programm.

Das kann ich nicht glauben, daß die Bibliothek so schlampig implemeniert 
sein soll.
Das hieße ja, Du bleibst für immer hängen, wenn der PC die Daten mal 
nicht abholt.

Eine Bibliothek muß verschiedene Funktionen bereitstellen, die auch 
direkt nach Aufruf wiederkehren.
Eine Funktion zur Statusabfrage muß sagen, ob Du was in den Sendepuffer 
schreiben darfst.
Eine Funktion kopiert dann die Daten in den Sendepuffer.
Und dann kann Dir wieder die Statusabfrage mitteilen, ob das Senden 
erfolgt ist.

Es kann natürlich sein, wenn Du ohne Statusabfrage die Sendefunktion 
aufrufst, daß die dann solange wartet, bis das nächste Senden möglich 
ist.
Dann ist das Warten aber Deine Schuld.
Du solltest nochmal genau nachsehen, welche Funktionen Dir die 
Bibliothek zur Verfügung stellt und wie diese funktionieren.


Man könnte notfalls auch das gesamte SPI-Handling als höher 
priorisierten Interrupt ausführen.


Peter

von Ralf (Gast)


Lesenswert?

> Der Treiber fängt das leider nicht ab. Ich lese die Daten am Host mit
> der Bibliotheksfunktion SI_Read aus. Dort muss man die Anzahl der zu
> lesenden Bytes angeben. Kommen weniger als angegeben an, meldet die
> Bibliothek nach einem Timeout einen Fehler.
Aber mit SI_CheckRXQueue(...) bekommst du doch die Anzahl der Bytes, die 
ein Device gerade im Buffer hat. Wenn du das vor dem SI_READ(...) 
ausführst und die Anzahl der Daten übernimmst, müsste das doch ohne 
Fehler gehen?

Ralf

von Mario G. (suicided)


Lesenswert?

> Das kann ich nicht glauben, daß die Bibliothek so schlampig implemeniert
> sein soll.
> Das hieße ja, Du bleibst für immer hängen, wenn der PC die Daten mal
> nicht abholt.
Das hab ich noch nicht probiert. Laut Programmers Guide gibt die 
Block_Write Funktion 0 zurück, wenn ein Fehler aufgetreten ist.

> Eine Bibliothek muß verschiedene Funktionen bereitstellen, die auch
> direkt nach Aufruf wiederkehren.
> Eine Funktion zur Statusabfrage muß sagen, ob Du was in den Sendepuffer
> schreiben darfst.
> Eine Funktion kopiert dann die Daten in den Sendepuffer.
> Und dann kann Dir wieder die Statusabfrage mitteilen, ob das Senden
> erfolgt ist.
Sowas gibt es in der Bibliothek nicht. Die ist für besonders einfache 
Handhabung und schelle Entwicklung geschrieben worden. Für den 
Datentransfer gibt es folgende Funktionen:
1
UINT Block_Write (BYTE *Buffer, UINT NumBytes)
2
BYTE Block_Read (BYTE *Buffer, BYTE NumBytes)
Der Bibliothek wird quasi ein "User"-Puffer übergeben - den Rest macht 
sie von selbst. Weitere Funktionen dienen nur der Initialisierung und 
dem (virtuellen) Interrupt:

  USB_Clock_Start() - Initializes the USB clock
  USB_Init() - Enables the USB interface
  Get_Interrupt_Source() - Indicates the reason for an API interrupt
  USB_Int_Enable() - Enables the API interrupts
  USB_Int_Disable() - Disables API interrupts
  USB_Disable() - Disables the USB interface
  USB_Suspend() - Suspend the USB interrupts
  USB_Get_Library_Version() - Returns the USBXpress firmware library 
version

Die FIFOs müssen vom User unberührt bleiben, sonst kommt die Bibliothek 
durcheinander.

> Es kann natürlich sein, wenn Du ohne Statusabfrage die Sendefunktion
> aufrufst, daß die dann solange wartet, bis das nächste Senden möglich
> ist.
> Dann ist das Warten aber Deine Schuld.
Block_Write braucht mit einem 512 Byte großem Puffer ca. 3 Millisekunden 
- daran lässt sich nichts ändern.

> Du solltest nochmal genau nachsehen, welche Funktionen Dir die
> Bibliothek zur Verfügung stellt und wie diese funktionieren.
Ich denke wir haben da ein unterschiedliches Verständnis von 
"Bibliothek". Die USB-Firmware-Library von TI z.B. bietet solche 
Funktionen an, wie du sie beschreibst. USBXpress von SiLabs ist für 
DumbAss-User wie mich gemacht, die rein gar nichts von den USB-internen 
Abläufen wissen (wollen) - allerdings mit oben angesprochener 
Einschränkung der Übertragungsrate.

> Man könnte notfalls auch das gesamte SPI-Handling als höher
> priorisierten Interrupt ausführen.
Ich hab mich mal im Datenblatt schlau gemacht. Der SPI-Interrupt ist 
standardmäßig höher priorisiert als der USB-Interrupt. Es kann 
allerdings sein, dass die Bibliothek diese Einstellung verändert. Wenn 
ich aber darauf verzichten würde, nur komplette Pakete per USB weiter zu 
senden, könnte ich auch auf das Blockieren des SPI-Interrupts während 
der Laufzeit von Block_Write verzichten. Die von Ralf angesprochene 
Host-Funktion könnte dabei sehr hilfreich sein, die Pakete im Host 
wieder zusammen zu bauen.

> Aber mit SI_CheckRXQueue(...) bekommst du doch die Anzahl der Bytes, die
> ein Device gerade im Buffer hat. Wenn du das vor dem SI_READ(...)
> ausführst und die Anzahl der Daten übernimmst, müsste das doch ohne
> Fehler gehen?
Wer lesen kann ist klar im Vorteil. Würde es am liebsten gleich 
ausprobieren... aber so kann ich mir das am Wochenende nochmal alles 
durch den Kopf gehen lassen.

VG
mario

von Ralf (Gast)


Lesenswert?

> Wer lesen kann ist klar im Vorteil.
Ich hoff bloß, dass ich's richtig gelesen hab :) Bzw. die Funktion von 
SI_CheckRXQueue richtig verstanden hab.

Ralf

von Ralf (Gast)


Lesenswert?

Hi,

na, irgendwelche Neuigkeiten?

Ralf

von Mario G. (suicided)


Lesenswert?

Ja, die Synchronisierung arbeitet wunderbar - manchmal passiert es aber, 
dass am PC Murks ankommt. Ich versuche mal kurz das System zu erklären:

µC:
- empfängt Daten per Funk
- entfernt Overhead und schreibt die Daten in einen Puffer
- kommt an Pin 0.1 ein steigende Flanke wird ein Interrupt ausgelöst und 
der
  Puffer per SPI an den USB-Controller gesendet

Während des Sendens per SPI sind Interrupts global deaktiviert um 
Inkonsistenzen auszuschließen. Es kann dann nichts mehr über Funk 
empfangen werden.

USB-Controller:
- empfängt über USB Daten vom Host und sendet unmittelbar darauf den
  "SPIbuffer" an den PC
- danach wird der entprechende Pin manipuliert um beim µC einen 
Interrupt
  auszulösen, der daraufhin über SPI die Daten sendet

Durch die Quasisynchronisation wird sichergestellt, dass währen 
Block_Read und Block_Write keine Daten per SPI ankommen, die dann 
verloren gehen würden. Aus diesem Grund kann man das Polling-Intervall 
um einiges verkürzen. Ich arbeite jetzt mit 15 Millisekunden und komme 
damit auf rund 270 kbps. Das ganze Funktioniert auch die meiste Zeit. 
Manchmal scheint es aber, als würden Pakete per SPI unvollständig 
ankommen. Ich habe deswegen schon die Übertragungsrate gesenkt und eine 
Pause zwischen den Bytes eingeführt. ~denke aber, dass der 
USB-Controller trotzdem manchmal falsch detektiert - vielleicht weil die 
Bibliothek da irgendetwas anderes macht. Das lässt sich ziemlich 
bescheiden debuggen. Dass die Daten richtig gesendet werden sehe ich am 
Logikanalysator.

Ich werde daher das ganze System nochmal neu aufsetzen - ohne 
Datenaggregation im µC. Die ankommenden Pakete werden dann einfach als 
Rohdaten zum Rechner durchgereicht, der die "Netzlogik" dann komplett 
übernimmt. Das ist zwar mit Aufwand verbunden und ich weiß auch nicht, 
ob die Probleme dadurch weniger werden, ich denke aber, dass ich mich 
momentan in einer Entwicklungssackgasse befinde (was das System angeht 
;). Durch das Auslagern der Logik auf den PC wird das Übertragungssystem 
weitaus weniger komplex - das "Spielen" mit Parametern somit wesentlich 
vereinfacht. Da das ganze ja auch mal bidirektional funktionieren soll, 
ist das wahrscheinlich die beste Lösung.

von Ralf (Gast)


Lesenswert?

Hi Mario,

allgemein gesagt freut es mich a) dass die Übertragung jetzt wohl mit 
der Wunschgeschwindigkeit funktioniert und b) dass du einen Ansatz 
gefunden hast, der auch ein einfacheres Gesamtsystem ermöglicht.

Verwirrend in deiner letzten Antwort ist, dass du einmal zwischen µC und 
USB-Controller unterscheidest, aber weiter unten quasi offen lässt, wer 
denn jetzt welcher ist (weiss ich ja) bzw. welcher Pin bei welchem 
welche Funktion hat :)

Da ich aufgrund dieser leichten Verwirrung meinerseits jetzt nicht ganz 
durchblicke, kann ich bzgl. der erwähnten Buffer-Fehler nur folgenden 
Vorschlag machen (aus Sicht des F320):

Implementiere zwei Buffer im Ping-Pong-Verfahren.
Zusätzlich implementierst du eine (Bit-)Variable, die anzeigt, in 
welchen Buffer geschrieben wird.
Einer der Buffer wird in Abhängigkeit der (Bit-)Variablen mit den Daten 
durch den SPI-Interrupt gefüllt, und zwar nicht-blockierend, wenn nötig 
SPI-Interrupt hochsetzen. Kein Warten auf irgendwelche Pinzustände, 
höchstens abfragen.
Kommt die Anfrage vom Host, wird die (Bit-)Variable geändert und somit 
der andere Buffer weiter beschrieben. Ausserdem wird der ursprüngliche 
Buffer an den Host gesendet.

Wie gesagt, kann es jetzt nicht abschätzen, aber das sollte alles 
Kommunikationsprobleme beseitigen und vor allem verhindern, dass du den 
SPI-Interrupt sperren musst.

Ralf

von Mario G. (suicided)


Lesenswert?

Hallo Ralf!

> Verwirrend in deiner letzten Antwort ist, dass du einmal zwischen µC und
> USB-Controller unterscheidest, aber weiter unten quasi offen lässt, wer
> denn jetzt welcher ist (weiss ich ja) bzw. welcher Pin bei welchem
> welche Funktion hat :)
PortPins mit Funktionen gibt es fünf: Vier fürs SPI (P0.0-P0.3) und 
einen zur Synchronisation (P1.3 am USB Controller = P0.1 am anderen 
Controller). Mit µC habe ich den CC2431 Transceiver bezeichnet, der per 
Funk die Daten sammelt.

PC <---USB---> USB-Controller <---SPI---> CC2431 < Funk > viele andere 
CC243x

> Da ich aufgrund dieser leichten Verwirrung meinerseits jetzt nicht ganz
> durchblicke, kann ich bzgl. der erwähnten Buffer-Fehler nur folgenden
> Vorschlag machen (aus Sicht des F320):
>
> Implementiere zwei Buffer im Ping-Pong-Verfahren.
> Zusätzlich implementierst du eine (Bit-)Variable, die anzeigt, in
> welchen Buffer geschrieben wird.
> Einer der Buffer wird in Abhängigkeit der (Bit-)Variablen mit den Daten
> durch den SPI-Interrupt gefüllt, und zwar nicht-blockierend, wenn nötig
> SPI-Interrupt hochsetzen. Kein Warten auf irgendwelche Pinzustände,
> höchstens abfragen.
> Kommt die Anfrage vom Host, wird die (Bit-)Variable geändert und somit
> der andere Buffer weiter beschrieben. Ausserdem wird der ursprüngliche
> Buffer an den Host gesendet.
> Wie gesagt, kann es jetzt nicht abschätzen, aber das sollte alles
> Kommunikationsprobleme beseitigen und vor allem verhindern, dass du den
> SPI-Interrupt sperren musst.
Das war auch mein ursprünglicher Plan - Doublebuffering. Aufgrund des 
arg beschränkten Arbeitsspeichers des F320 hätte man das 
Polling-Intervall aber noch mehr verkürzen müssen. Den SPI-Interrupt 
lasse ich momentan auch an... die USBXpress-Bibliothek schaltet offenbar 
aber Interrupts global ab. Wenn das nicht wäre, hätte ich keine 
Probleme.
Die Synchronisation der beiden Controller klapp von der Sache her ganz 
gut. Problem ist jetzt nur noch, dass der USB-Controller manchmal etwas 
anderes empfängt, als ihm auf dem SPI-BUS gesendet wurde - aber auch 
erst, seitdem ich synchronisiere - keine Ahnung warum. Vielleicht sollte 
SPI vor der USB-Abarbeitung übertragen statt danach. Das ist aber 'ne 
Sache für sich und hat nichts mit dem eigentlichen Problem zu tun.

Fakt ist jedenfalls, dass bei USBXpress (zumindest bei der 
IAR-Portierung) die Nettodatenrate durch den beschränkten RAM, die 
blockierenden Funktionen und den Bulk-Transfer auf etwa 1,5 Mbps 
beschränkt ist. Hängen noch andere Systeme dran (der USB-Controller 
quasi als Repeater) halbiert sich diese Datenrate schlimmstenfalls 
nochmal.
Durch meine unsaubere Umsetzung (da ich anfangs noch dachte mit 
USB-Datenrete verschwenderisch umgehen zu können), hat sie sich noch 
weiter verringert - zu weit.

Deine Hilfe und die von Peter haben mir die Augen geöffnet. USBXpress 
ist ansich 'ne schöne Sache - für meinen Fall aber grenzwertig. Mit 
einer sauberen Umsetzung wirds aber gehen. Ich schreibs hier rein, wenn 
es einwandfrei läuft.

Vielen Dank nochmal
mario

von Ralf (Gast)


Lesenswert?

Okay, dann werd ich jetzt mal bis auf weiteres mein Hirn zu dem Thema 
abschalten :)
Freut mich, wenn ich helfen konnte.

Ralf

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.