Hallo Leute,
ich weiß, das Thema mit dem VCP gibt es schon ein paar mal aber ich
eröffne jetzt nochmal eines weil ich eine Lösung meines Problems in
keinem finden kann.
Ich hab jetzt die letzte Zeit mit dem USB-VCP zeugs rumgemacht.
Jetzt hänge ich an folgendem Problem und komm einfach nicht weiter.
Hier mal mein Code:
Mein Problem ist jetzt, dass wenn ich das so auf den Controller flashe,
dass es Funktioniert und ich an den PC den String senden kann ( das ist
ja eigentlich garkein problem :-D ).
Sobald ich jetzt aber die beiden zeilen:
1
// char ReceiveString[0x100];
2
// unsigned char ReceiveStringLength;
wieder "einkommentiere" lässt sich das Programm anstandslos kompilieren
und flashen. allerding springt mir das programm beim loslaufen in den
hardfaulthandler. oder mal in irgendwelche interruptroutinen die nicht
existieren usw.
Jetzt frage ich mich woher kommt das problem. Ich tippe ganz stark auf
irgendein Speicherproblem. Nur was läuft da schief?
Der untere teil des Programms ist die ganze zeit auskommentiert(wer weiß
was hier noch auf mich zukommt??)
Ich hoffe mir kann jemand meinen Fehler aufzeigen :)
Grüße Tarkan
// char ReceiveString[0x100];
// unsigned char ReceiveStringLength;
Allein von den Variablen, sofern sie nicht verwendet werden, kann Dein
Problem nicht kommen. Musst erstmal es weiter eingrenzen und mehr
Informationen zum Programm geben, wie Routineninhalte, ISR usw.
Dieses GPIO_Initialisation ist lediglich für die Tasten auf meinem
Evalboard(STM3210E-Eval).
Usb funktioniert ja soweit ganz gut. Wie gesagt nur gibt es irgendwie
ein Problem sobald ich irgendwelche Arrays erzeuge.
Als das einfache Hinzufügen von ein paar Variablen und/oder Arrays darf
keinen Hardfault verursachen. Das kann nur dann passieren, wenn der
Linker Mist baut und sich dadurch Speicher-Bereiche in nicht-RAM
Bereiche verschieben oder Variablen-Speicher mit z.B. dem Stack
überlagern.
Letzteres kann man ausschließen, da Du in das Array ja noch nichts
geschrieben hast, bleibt nur ersteres.
Je nach startup.c oder startup.s werden nicht initialisierte Variablen
auf 0x00 gesetzt. Liegt das Array ganz oder teilweise außerhalb eines
schreibbaren Speichers (RAM), geht die CPU in Hardfault.
Es hilft manchmal die Exception-Handler zu aktivieren und wenn es nur
ein while(1); ist. Außerdem muss man den JTAG aktiv lassen und die
entsprechenden Bits im Exception Handler COntrol Register setzen. Dann
gibt es statt eines nichts-sagenden Hardfaults einen passenden Busfault
oder Memfault.
Aber poste doch mal das .map File, dann kann man Dir weiter helfen. Da
stehen nämlich die Adressen drin, wo im Addressbereich die verschiedenen
Dinge liegen.
Gruß, Ulrich
So, jetzt gehst Du mal her und kommentierst alles(!) aus (mit Ausnahme
Deiner ReceiveString-Geschichte). Dann lässt Du in der Hauptschleife
eine LED blinken.
Na, blinkt die LED? Falls ja, dann liegt es nicht an Deinen Variablen,
sondern am Rest vom Code. Also zurück auf Los und den nächsten Schnipsel
hinzufügen.
Gruß Potter
Soo, also ich hab jetzt nochmal rumgespielt.
ich hab wie man mir geraten hat den Quellcode auskommentiert und stück
für stück wieder einkommentiert.
Also sobald ich die funktion "USB_Init();" einkommentiere springt der
Programmpointer irgendwo ins Nirvana und bleibt dort stehen. Das
passiert aber nur wenn das Array ReceiveString[] einkommentiert ist.
sobald ich es auskommentiere funzt wieder alles :-S
Interessant ist auch: Wenn ich das Array etwas kleiner mache (Statt
0x100 0x0F) dann funktioniert das progarmm auch.
Ich hab jetzt mal folgende Theorie aufgestellt:
Der USB-stack definiert für die einzelnen Endpunkte Bestimmte
Speicherbereiche. Diese haben Feste Adressen. Aber vor diesen Adressen
ist noch ein bischen freier Platz. Sobald ich jetzt Variablen Deklariere
kommen diese in diesen freien Platz rein. Nur wenn ich zu viele
Variablen deklariere überschneiden sich die Adressen von meinen Arrays
mit den Adressen der Endpunkte (zugegeben das ist jetzt reine
Spekulation).
Nur blick ich noch nicht so ganz wie ich das Problem beheben oder wo ich
die Theorie untermauern kann.
Für jeden Tip wäre ich dankbar
Grüße Tarkan
Da wird Dir auch keiner helfen können, wenn Du nicht das map File
postest.
Da steht nämlich drin, wer wo im Speicher landet. natürlich das map File
wenn deine Arrays aktiviert sind.
Tarkan D. schrieb:> Aber ich dachte hier stehen nur die Sachen bezüglich des Flash> speichers, nicht des Ram's ?
Name Origin Length Attributes
UNPLACED_SECTIONS 0xffffffff 0x00000000 xw
FLASH 0x08000000 0x00080000 xr
RAM 0x20000000 0x00010000 xw
USB_CAN_RAM 0x40006000 0x00000200 xw
PCCARD 0x90000000 0x00000000 xw
NAND2 0x80000000 0x00000000 xw
NAND1 0x70000000 0x00000000 xw
NOR_PSRAM4 0x6c000000 0x00000000 xw
NOR_PSRAM3 0x68000000 0x00000000 xw
NOR_PSRAM2 0x64000000 0x00000000 xw
NOR_PSRAM1 0x60000000 0x00000000 xw
CM3_System_Control_Space 0xe000e000 0x00001000 xw
default 0x00000000 0xffffffff
Naa, da stehen alle Sections und man kann auch gut sehen, dass sich der
USB einen eigenen Puffer mit dem CAN teilt, an Adresse 0x40006000, der
512 Bytes groß ist.
Außerdem scheint etwas eingetreten zu sein, dass ich befürchtet habe.
Deine ReceiveStringLength und ReceiveString[] werden im map File nicht
aufgeführt. D.h. der Compiler hat festgestellt, dass die Variablen nicht
referenziert werden und sie garnicht mit eincompiliert.
Was ich sehen kann ist, dass nur ein Heap und ein Stack von jeweils 128
bytes vorgesehen ist. Da ich das Demo aber nicht kenne, kann ich dazu
nix sagen. Ich finde es etwas knapp bemessen.
Sonst offeriert das map File erst einmal keine Auffälligkeiten. Ich kann
das aber heute Abend mal genauer nachsehen.
Wirst also doch mal den JTAG auspacken müssen. Der STM32F hat sehr wenig
Bugs, aber leider einen blöden. Er geht ohne angeschlossenen JTAG immer
in Hardfault. JTAG muss also aktiv sein, damit er in die detaillierteren
Levels, Bus-/Mem-Fault spring.
Gruß, Ulrich
Also, JTAG ist an:
Jetzt spingt das Biest die ganze zeit in den HardFault_Handler.
Zwischendurch ist er auch mal in den UsageFault_Handler gesprungen.
Ulrich P. schrieb:> Außerdem scheint etwas eingetreten zu sein, dass ich befürchtet habe.> Deine ReceiveStringLength und ReceiveString[] werden im map File nicht> aufgeführt. D.h. der Compiler hat festgestellt, dass die Variablen nicht> referenziert werden und sie garnicht mit eincompiliert.
Das finde ich echt komisch, weil ich nämlich im DebugMode bin nicht im
Release :-(
Irgendwie ärgert mich das schon. Weil für dieses dumme USB gibt es noch
nichtmal eine anständig dokumentierte AN UM oder sonst was!!
An USB trauen sich irgendwie noch nicht alle ran. Habe das schon recht
exzessiv für AVR gemacht, bin aber beim STM32 noch nicht dazu gekommen
eigene USB Libraries zu schreiben. Erst mal Urlaub und dann EMAC, dann
USB.
Leider nützt es erst mal nix, wenn Du mir das Projekt schickst, denn ich
nutze nicht die Toolchain aus dem STM3210x Kit sondern yagarto bzw.
gcc-4.6.x. Die STM Toolchain kann aber m.E. keinen Makefile generieren
weshalb ich mir alles aus den XML Dateien des Projektes zusammen suchen
müsste.
Mal sehen, was da geht. Habe im Moment recht viel zu tun und nutze nur
die Compiler-Laufzeiten (Nein, nicht STM32 sondern Linux Kernel) um hier
im Forum zu lesen/schreiben.
Gruß, Ulrich
Kann mir vielleicht jemand einen Link geben, wo ich was bezuüglich
USB-CDC, VCP, Endpunkte etc. nachlesen kann?
Mich stresst das ganze thema jetzt dermaßen, dass ich mir überlege mir
einfach selber meinen Stack zusammen zu basteln. Irgendwie kann das doch
echt nicht sein. Ich sitz hier seit 1,5 wochen und hab noch nicht
wirklich was besonderes zusammen bekommen!!
Sollte doch nicht so schwer sein in irgendwelche endpunkte die richtigen
werte zu schreiben. Und ST schreibt in ihren AN etc. dass die ganze
grütze von denen eher ein vorschlag ist als eine Lösung!
Grüße Tarkan
PS: Vielleicht kann mir jeman auch noch nen Ordentlichen Tip für
Literatur bezüglich USB geben.
Das "USB.Handbuch für Entwickler von Jan Axelson" soll ja nicht so
besonders sein.
Sorry, kann ich nicht. Ich habe den ATMEL Stack damals nur anhand der
USB Forums Unterlagen verändert / korrigiert. Also die Unterlagen von
USB.org
Wie dringend brauchst Du denn den Stack? Im August ließe sich was
machen, vorher nicht.
Gruß, Ulrich
Also die wahrheit ist ich brauch das USB für meine jetzige
Projektabwicklung.
Daher MUSS ich das irgendwie hinbekommen. Und wenn es sein muss, muss
ich da einen Auftrag nach außen geben, damit uns jemand dafür eine
"Bibliothek" schreibt ( wir haben da spezialisten die schonmal was
ähliches für und abgewickelt haben ).
Glücklicherweise stehe ich eher unter Zeitdruck als Kostendruck.Wobei
das jetzt auch noch 2 wochen zeit hat oder so. Ich muss halt früh genug
auf den richtigen Zug aufspringen :)
Aber ich schau mir jetzt nochmal ganz in Ruhe den Quellcode und die
lausige Dokumentation an. Vielleicht komm ich ja doch auf einen grünen
Zweig :)
Trotzdem vielen dank Ulrich :)
Gruß Tarkan
Das Buch von J. Axelson ist der beste Einstieg in USB. Schau Dir mal
Ihre Seite an (lvr.com) und Du wirst schnell feststellen, dass Sie weiß
was sie tut - im Gegensatz zu Dir^^.
Aber mach Dich drauf gefasst: wenn Du USB verstehen willst, dann bring
mal 4 - 6 Wochen zum Einarbeiten mit.
Gruß Potter
>Wobei das jetzt auch noch 2 wochen zeit hat oder so. Ich muss halt früh> genug auf den richtigen Zug aufspringen :)
Wenn Du das nach außen geben willst (was eigentlich?) musst Du das auch
erstmal exakt beschreiben, Lastenheft usw., dann alles implementieren
und testen. 2 Wochen Realisierbarkeit halte ich bei USB für ein
Gerücht;-) USB sind keine Einsteigerprojekte, zumal Du auch nicht gerade
ein STM32-Profi bist.
Vollkommen richtig, aber die Firma hat schonmal was mit USB für uns
gemacht. Aber wie auch immer, ich denke ich bekomm es auch so hin. Hab
nochmal mit dem STM_USB zeugs rumgeeiert.
Tarkan D. schrieb:> Also im endeffekt ist es nur das virtual-comport beispielprogramm, und> wenn man so will hab ich nur in der main datei rumgepfuscht :)
Also sind alle USART-Routinen noch drinnen und so.
Ich würde an deiner Stelle erstmal den ganzen Mist mitm USART
rausnehmen.
Ausserdem würde ich eine Funktion schreiben, die von der CALLBACK
Funktion
"EP3_OUT_Callback" aufgerufen wird, sobald Daten empfangen wurden.
So werden die Daten sofort geholt und dein USB-(CAN)-Ram kann nicht
überlaufen.
Tarkan D. schrieb:> Daher MUSS ich das irgendwie hinbekommen. Und wenn es sein muss, muss> ich da einen Auftrag nach außen geben,
Einen Auftrag würde ich natürlich auch annehmen ;-)
GRUß
Hallo Leute,
ich hab mich jetzt nach einigen Tagen pause nochmal intensiv mit der
USB_FW_LIB von ST beschäftigt. Das funktioniert jetzt eigentlich ganz in
ordnung.
Nur habe ich immernoch das Problem mit den Angelegten Variablen:
folgender Quellcode funktioniert optimal:
1
longirgendwas[0x2FF];
2
3
intmain(void)
4
{
5
6
Set_System();
7
Set_USBClock();
8
USB_Interrupts_Config();
9
USB_Init();
10
11
while(1)
12
{
13
}
14
}
und folgender quellcode erzeugt einen hardfault:
1
intmain(void)
2
{
3
longirgendwas[0x2FF];
4
Set_System();
5
Set_USBClock();
6
USB_Interrupts_Config();
7
USB_Init();
8
9
while(1)
10
{
11
}
12
}
ich kann nicht ganz nachvollziehen wieso es funktioniert wenn ich das
array vor dem Programmstart erzeuge, aber wieso es zur laufzeit nicht
funktioniert! ??
Bitte um hilfe oder tip :)
grüße Tarkan
Gebhard Raich schrieb:> Uberleg mal.
Wow, danke. Also das war extrem hilfreich. Ich hab gedacht ich schnorre
mir jetzt in verschiedenen Foren solange Codeschnipsel zusammen bis mein
Programm so funktioniert wie ich es will. Aber dein vorschlag bringt
mich auf eine ganz neue Idee. Ich überlege einfach mal. Respekt !
Für die Anderen sind meine dateien im anhang.
Entwicklungsumgebung ist Rowley Crossworks 2.0.10
Danke für die Hilfe
Gruß Tarkan
Tarkan D. schrieb:> Gebhard Raich schrieb:>> Uberleg mal.>> Wow, danke. Also das war extrem hilfreich. Ich hab gedacht ich schnorre> mir jetzt in verschiedenen Foren solange Codeschnipsel zusammen bis mein> Programm so funktioniert wie ich es will. Aber dein vorschlag bringt> mich auf eine ganz neue Idee. Ich überlege einfach mal. Respekt !
Übrigens, sorry für die Ironie.
Bin nur mittlerweile wieder ziemlich angekotzt von dem USB-VCP Thema :)
Wir wissen überhaupt nicht, was Du in Deinem Projekt alles ein- oder
verstellt hast. Welcher µC genau? Stimmt das Startup, Linkerscript usw.
Du lieferst nachgefragte Infos nur spärlich.
Das VCP Demo läuft jedenfalls, habe es vor kurzen auch in ein Projekt
eingebaut.
Installier mal testweise eine andere IDE (am beste Keil) oder wenn Du
den ST-LINK hast, das Atollic True Studio Lite. Dort ist nach einer
Projektneuanlage und Auswahl des µC alles bereits richtig konfiguriert.
Eine Fehlerquelle ist es dann weniger.
Matthias K. schrieb:> Du lieferst nachgefragte Infos nur spärlich.
Welche wären das? :)
Also:
IDE = Rowley Crossworks 2.0.10
µC = STM32103ZET6
Installiertes Package:
STM32 CPU Support Package v 2.8
Startup Script sollte passen. Linker sollte auch passen, wird ja
Automatisch für mich gemacht (Stm32 project template). Oder?
Sorry aber ich hab auch nicht den Megaplan sonst bräuchte ich ja keine
Hilfe.
Das Beispiel funktioniert auch perfekt bei mir. Nur die Modifikation
nicht.
Aber mir ist noch was aufgefallen.
Mein Stack ist laut .map 0x80 bytes groß. Ist es nicht so, dass lokale
Variablen im Stack abgelegt werden?
Das heißt wenn ich den Stack größer machen kann dass es funktionieren
könnte? Nur wie kann ich das machen?
Grüße Tarkan
Tarkan D. schrieb:> Das heißt wenn ich den Stack größer machen kann dass es funktionieren> könnte? Nur wie kann ich das machen?
oder passiert das auch automatisch??
>>oder passiert das auch automatisch??
wenn du mal überlegen würdest....
Nein,der Stack wird normalerweise im start-up-file
(STM32F10x.s)eingestellt.
Schlüsselwort: Stack_Size EQU xxxx
Grüße
Hi!
Der StackSize wird im Linker-Script eingestellt. Die Startup.S benötigt
lediglich einen Verweis auf stack_end damit im Flash an Offset 0x0 der
Wert eingetragen wird. Beim Reset lädt der Cortex sich diesen als
aktuellen Stackpointer Wert, dann lädt er die nächste Adresse (Offset
0x4) und setzt den PC darauf, springt also in die Reset-Funktion.
Gruß, Ulrich
Ulrich P. schrieb:> Hi!>> Der StackSize wird im Linker-Script eingestellt. Die Startup.S benötigt> lediglich einen Verweis auf stack_end damit im Flash an Offset 0x0 der> Wert eingetragen wird. Beim Reset lädt der Cortex sich diesen als> aktuellen Stackpointer Wert, dann lädt er die nächste Adresse (Offset> 0x4) und setzt den PC darauf, springt also in die Reset-Funktion.>> Gruß, Ulrich
Wie kann ich am Linker-Script rumfummeln? Wo finde ich das File ? Kann
ich das irgendwie über die IDE einstellen? Reicht es dabei einfach nur
einen Wert ab zu ändern? Ist es ratsam dass jemand mit wenig plan wie
ich da rumspielt?
Vielen vielen Dank für die Mithilfe jedes Einzelnen. Das mit der
Stackgröße scheint das Problem gewesen zu sein! :))
Also ich muss jetzt noch bischen rumspielen, aber das scheint es
tatsächlich gewesen zu sein.. ich bin überglücklich.
Grüße Tarkan
PS: Für den Fall das jemand ein ähnliches Problem hat, unter CrossStudio
stellt man das mit einem Rechtsklick auf
Project->Properties->RuntimeMemoryAreaOptions ein.
Vielleicht kann mir noch kurz jemand den Unterschied zwischen "Main
Stack Size" und "Process Stack Size" erklären ??
Der Cortex hat einige Mechanismen um zwischen User- und System-Tasks zu
unterscheiden. Man kann auf ihm so zu sagen ein in sich gekapseltes
System laufen lassen und nebenher Anwender-Software. Um dies zu trennen
verfügt er über eine MMU (nicht immer) und zwei getrennte Stacks. So
kann sich eine Anwender-Software abschießen, das System bleibt aber
weiterhin intakt.
Daher die beiden separaten Stacks.
Gruß, Ulrich