Forum: Projekte & Code USB-Tutorial mit STM32


von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Hallo Forum,

weil mich das schon länger juckte habe ich ein Tutorial für die 
Implementation eigener USB-Devices verfasst, in der Hoffnung dass so 
mehr Hobby-Projekte auf den mittlerweile etwas angestaubten Serial-Port 
verzichten können. Das geschieht ohne die Nutzung fremder Libraries, nur 
durch direkte Register-Ansteuerung auf dem STM32F103 wodurch auf den 
ziemlich komplexen und etwas undurchsichtigen USB-Stack des Herstellers 
verzichtet werden kann. Es wird eine Möglichkeit gezeigt, wie man unter 
Windows ohne Treiber-Installation und sonstige Konfiguration von eigenen 
Programmen auf sein Gerät zugreifen kann.

Der Text ist hier zu finden: USB-Tutorial mit STM32
Der dazugehörige Beispielcode für den Controller hier: 
https://github.com/Erlkoenig90/f1usb
Der Code für den PC hier: https://github.com/Erlkoenig90/usbclient

Der Text ist länger geworden als gedacht, aber dafür sollte auch alles 
nötige drin stehen. Hoffentlich findet ihn jemand hilfreich! Über etwas 
Feedback dazu würde ich mich freuen.

von Stefan F. (Gast)


Lesenswert?

Kannst du deinen Code so umschreiben, dass er mit C++ 11 zufrieden ist?
Ich frage, weil die System Workbench for STM32 noch kein C++ 17
unterstützt.

Ich habe das mal einfach ignoriert und den Dialekt manuell eingestellt, 
da der Compiler die Version 6.3.1 hat. c++1y und c++1z werden zwar 
akzeptiert, aber ich erhalte Fehlermeldungen. Überall, wo asm vorkommt:

> ../startup/sysmem.c:54:27: error: expected '=', ',', ';', 'asm'
> or '__attribute__' before 'asm' register char * stack_ptr asm("sp");

Und danach bricht die Kompilierung wegen folgefehlern ab.

Dazu sollte ich wohl noch erklären, dass ich mit der System Workbench 
ein neues Projekt gestartet habe und dann deine Sourcen dort hinein 
kopiert habe. Weil ich deine Projektdateien nicht importieren konnte.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Überall, wo asm vorkommt

Das aber hat doch mit C++11 ./. C++17 nichts zu tun, oder?

von Stefan F. (Gast)


Lesenswert?

Kann sein, ich weiß es nicht.

von Niklas Gürtler (Gast)


Lesenswert?

Stefan U. schrieb:
> Überall, wo asm vorkommt:

Hm? In meinem Code kommt gar kein asm vor, nur in den Header von ST/ARM. 
Nach c++11 portieren geht  nicht so direkt, dort kann man die 
Deskriptoren nicht so schön zusammenbauen. Du kannst in der usb_desc.cc 
das #include "usb_desc_helper.hh" rausnehmen, und die einzelnen 
Deskriptoren auskommentieren und stattdessen die Versionen mit 
std::array einkommentieren damit es mit C++11 geht, sind dann leider 
deutlich schlechter lesbar. Bin gerade unterwegs, ich kann später mal 
schauen das mit SW4STM32 hin zu bekommen...

von Stefan F. (Gast)


Lesenswert?

Vergiss mein Problem. Ich muss irgendwo einen Tippfehler eingebaut 
haben. ich bin jetzt ein Stück weiter gekommen.

Beitrag #5223302 wurde von einem Moderator gelöscht.
von C. H. (hedie)


Lesenswert?

Schöne sache.

Ich denke jedoch dass für viele Gelegenheitsbastler, der Einsatz eines 
FT230XQ für ein paar Euro oder das billige chinesische Pendant, doch 
viele Stunden an Debugging ersparen werden.

Denn C++ für Mikrocontroller setzen nicht sehr viele Hobbyisten ein und 
das aufsetzen eines eigenen Projekts in Eclipse für den STM32 mit dem 
Plugin, der Konfigurations des Debuggers etc ist nicht ganz trivial. 
Deshalb setzen viele gerne auf IDEs wie CooCox oder AttolicTrueStudio 
Lite, welche halt "nur" C Unterstützung bieten.

Ungeachtet dessen, finde ich deine Arbeit hervorragend! Dein Einsatz ist 
lobenswert. Ich werde bestimmt einmal deine Umsetzung testen.

Danke an dieser Stelle an dich!

von Mitlesa (Gast)


Lesenswert?

Claudio H. schrieb:
> Ich denke jedoch dass für viele Gelegenheitsbastler, der Einsatz eines
> FT230XQ für ein paar Euro oder das billige chinesische Pendant, doch
> viele Stunden an Debugging ersparen werden.

Meine Rede. Keine guten Voraussetzungen für eine schnelle
und einfache Implementierung.

Beitrag "Re: USB CDC mit CUBE und SW STM32"

Nachdem ich mir die Sourcen eine Weile angeschaut habe muss
ich das (leider) nochmals so sagen.

von Hans-Georg L. (h-g-l)


Lesenswert?

@Stefan beim g++ musst du die _weak und _packed Symbole in 
Anführungszeichen setzen und evtl noch die include Pfade von gcc 
kopieren.

von Hans-Georg L. (h-g-l)


Lesenswert?

Claudio H. schrieb:
> Schöne sache.
>
> Ich denke jedoch dass für viele Gelegenheitsbastler, der Einsatz eines
> FT230XQ für ein paar Euro oder das billige chinesische Pendant, doch
> viele Stunden an Debugging ersparen werden.
>

Mit dem chinesischen Pendant bin ich bei meinem AD9854 Modul (ist dort 
aufgelötet) auf max. 38kBd Übertragungsrate gekommen.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe das jetzt mit der System Workbench hin bekommen. Irgendwo muss 
ich versehentlich einen Tippfehler eingebaut haben, das war der 
eigentliche Knackpunkt.

Es hat beim zweiten Anlauf ohne großartige Anpassungen geklappt. Ich 
möchte Dir ein großes Lob für dieses Projekt aussprechen. Endlich kann 
ich die USB Schnittstelle ohne HAL beunutzen, ich bin so happy!

> beim g++ musst du die _weak und _packed Symbole in
> Anführungszeichen setzen

War nicht nötig.

Folgendes habe ich mit der System Workbench for STM32 angestellt:

1) Ein neues C++ Projekt für die Toolchain "AC6 STM32 MCU GCC" anlegen.
   Dabei die Option "No firmware" verwenden!

2) Das CMSIS Verzeichnis von irgendeinem HAL basierten Projekt kopieren.
   In der Datei stm32f1xx.h die Zeile "#define STM32F103xB" aktivieren
   um das richtige Device einzustellen.

3) Die ganzen Quelltexte Dateien von Niklas VCP Branch
   (https://github.com/Erlkoenig90/f1usb/tree/vcp) ins src
   Verzeichnis kopieren.
   Auch die Dateien sys/clockcong.h und sys/clockcong.c ins
   src Verzeichnis kopieren.

4) Im LinkerScript.ld den USBBUF hinzufügen:
1
MEMORY
2
{
3
  RAM (xrw)    : ORIGIN = 0x20000000, LENGTH = 20K
4
  ROM (rx)    : ORIGIN = 0x8000000, LENGTH = 64K
5
  USBBUF (rw)  : ORIGIN = 0x40006000,  LENGTH = 1024
6
}
Und weiter unten:
1
  .UsbBuffer (NOLOAD) : {
2
        UsbBufBegin = .;
3
        *(.usbbuf)
4
        *(.usbbuf*)
5
  } > USBBUF

5) Im startup/startup_stm32.s die fehlenden Interrupthandler ergänzen
   (von Niklas Quelltext sys/Startup.S kopieren)

6) In den Projekteinstellungen für den C/C++ Builder, die beiden CMSIS 
Verzeichnisse als "Includes" sowohl für den GCC COmpiler als auch für 
den G++ Compiler hinzufügen. Den Dialekt bei G++ auf "-std=c++1z" 
stellen. Beim Linker unter Miscellaneous die Flags "-specs=nano.specs 
-specs=nosys.specs" eingeben.

Und weil ich ein Blue-Pill Board habe, wo PC12 nicht benutzt wird, habe 
ich die entsprechend kommentierten Zeilen im Code auskommentiert.

Achtung: Beim Blue-Pill Board ist der Pull-Up Widerstand am USB Port 
falsch bestückt (10k statt 1,5k). Lösung: 1,8k Ohm parallel dazu 
schalten (von PA12 nach 3,3V).

Anbei ist mein Projektverzeichnis von der System Workbench.

von Stefan F. (Gast)


Lesenswert?

Da ich nur einen Bruchteil deiner Erklärungen verstehe würde ich mich 
sehr freuen, wenn du uns auch eine Klasse basteln könntest, die ähnlich 
wie die Serial Klasse von Arduino funktioniert.

Ich stelle mir vor, dass "mein" Programm (auf dem µC) über eine send() 
Methode Bytes senden kann und über eine receive() Methode den 
Empfangspuffer des virtuellen COM Ports auslesen kann.

Damit würdest du Anfängern wie mir sicher noch mehr helfen.

von 4444444444444444444444 (Gast)


Lesenswert?

hi

hast du auch etwas mit USB Host und isochonem Datentransfer parat?
Ich hatte damals nen netten bug in der stm usb lib  gefunden.
damit funktionierte der Transfer von der webcam zum µC leider nicht.

von Niklas G. (erlkoenig) Benutzerseite


Angehängte Dateien:

Lesenswert?

Stefan U. schrieb:
> Folgendes habe ich mit der System Workbench for STM32 angestellt:

Sieht mir etwas kompliziert aus... Ich hab mir SW4STM32 jetzt auch mal 
installiert und selber ein Projekt angelegt mit folgenden Optionen:
* No firmware
* Don't generate startupfiles
* Präprozessor-Makro definieren: STM32F103xB, NDEBUG (Release). Die 
Vordefinierten löschen
* Das Linker Script des Projekts dem Linker übergeben
* Startupcode des Projekts wird automatisch übernommen
* Linker-Option -specs=nano.specs einstellen
* Include-Pfad "sys" hinzufügen

Ist im Endeffekt nur minimal einfacher als mit GNU-MCU-Plugin, da muss 
man den GCC selbst entpacken.

Ich hab im Anhang die erstellen Projektdateien hochgeladen. Die kann man 
sich in das Projektverzeichnis extrahieren und das dann in SW4STM32 
importieren. Mangels ST-Link konnte ich aber die Launch-Configurations 
nicht testen - kann jemand bestätigen dass die funktionieren? Dann würde 
ich das so in den Beispielcode übernehmen.

Habe den Code nochmal angepasst, der geht jetzt auch mit C++11, war doch 
kein großes Problem. Mit C++14 (und neuer) wird das Image aber etwas 
kleiner, weil da constexpr Funktionen nicht automatisch const sind und 
so an einer bestimmten Stelle constant initialization ermöglicht wird.

Stefan U. schrieb:
> Da ich nur einen Bruchteil deiner Erklärungen verstehe würde ich mich
> sehr freuen, wenn du uns auch eine Klasse basteln könntest, die ähnlich
> wie die Serial Klasse von Arduino funktioniert.
Oh, ich hatte gehofft dass es verständlicher wäre :-/ So eine direkt 
nutzbare Arduino-Artige Klasse entspricht nicht so ganz dem Konzept des 
Artikels, da ging's mehr um tatsächliches Verständnis der Technologie... 
Wenn man fertig einsetzbaren Code will, kann man auch die Library von ST 
nehmen... oder eben SerialUSB vom Maple bzw. Stm32Duino-Projekt ;-)

Mitlesa schrieb:
> Meine Rede. Keine guten Voraussetzungen für eine schnelle
> und einfache Implementierung.
Darum ging's auch nicht. Das gibts ja wie gesagt schon. Der Beispielcode 
soll das Tutorial vereinfachen, nicht noch eine USB-Bibliothek bieten.

4444444444444444444444 schrieb:
> hast du auch etwas mit USB Host und isochonem Datentransfer parat?
Äh. Das ist ja dann noch ca. 7 Größenordnungen komplizierter. Das hab 
ich nicht zufällig hier rumliegen.

: Bearbeitet durch User
von 32zuterrtzkutehte (Gast)


Lesenswert?

Niklas G. schrieb:
> Äh. Das ist ja dann noch ca. 7 Größenordnungen komplizierter. Das hab
> ich nicht zufällig hier rumliegen.

richtig .-)

ging mir nur darum ob di evtl was hast ...
Ich habe so meine bauchschmerzen mit der STM Lib gehabt.
vlt gibts noch einen eleganteren weg :-)

von Axel S. (a-za-z0-9)


Lesenswert?

Niklas G. schrieb:
> Stefan U. schrieb:
>> Da ich nur einen Bruchteil deiner Erklärungen verstehe würde ich mich
>> sehr freuen, wenn du uns auch eine Klasse basteln könntest, die ähnlich
>> wie die Serial Klasse von Arduino funktioniert.

> Oh, ich hatte gehofft dass es verständlicher wäre :-/ So eine direkt
> nutzbare Arduino-Artige Klasse entspricht nicht so ganz dem Konzept des
> Artikels, da ging's mehr um tatsächliches Verständnis der Technologie...
> Wenn man fertig einsetzbaren Code will, kann man auch die Library von ST
> nehmen... oder eben SerialUSB vom Maple bzw. Stm32Duino-Projekt ;-)

Hier bin ich absolut bei dir. Was wir ganz sicher nicht brauchen, ist 
eine weitere opaque, unterdokumentierte und in der Folge unverstandene 
USBSerial Klasse. Wer so etwas haben will, soll sich aus dem Fundus 
existierender Software bedienen.

Ich habe deinen Artikel noch nicht gelesen, aber von der Zielsetzung 
geht der genau in die Richtung, die ich mir gewünscht hatte. USB steht 
seit langem auf der Liste der Dinge, die ich mal grundlegend 
durchexerzieren will. Und auf den ersten Blick sieht dein Artikel wie 
die perfekte Hilfestellung aus.

von Stefan F. (Gast)


Lesenswert?

> Oh, ich hatte gehofft dass es verständlicher wäre :-/

Das liegt sicher nicht an deinem Text, sondern daran, dass meine C++ 
Kenntnisse begrenzt sind, USB scheiß kompliziert ist und die 16bit 
Hardware im STM es noch komplizierter macht.

von Niklas Gürtler (Gast)


Lesenswert?

Axel S. schrieb:
> Ich habe deinen Artikel noch nicht gelesen,

Dann mach das mal... Die VCP Klasse so umzubauen dass sie nicht mehr auf 
einen USART zugreift sondern print ()-artige Funktionen anbietet ist 
dann nur eine Fingerübung. Interessant wird es wenn der Sendepuffer voll 
läuft... Macht man dann ein Timeout, wartet man per WFI auf Interrupts? 
Solche Fragen lassen sich außerhalb eines vieles festlegenden Frameworks 
wie das von Arduino kaum allgemeingültig beantworten.

Stefan U. schrieb:
> und die 16bit Hardware im STM es noch komplizierter macht.

Eigentlich ist die noch relativ simpel, die hat glaube ich weniger 
Einstell Möglichkeiten wie z.B. der UART. Nur der Zugriff auf den USB 
RAM ist etwas komisch, aber das kann man leicht hinter 2 Funktionen 
verstecken. Und mit meiner super schicken svg Grafik ist das doch total 
übersichtlich erklärt ;-)

von temp (Gast)


Lesenswert?

Ich hab mir das Tutorial mal durchgelesen. Das als solches finde ich 
ziemlich gut. Danke dafür. Auch für den Ansatz ohne die STM32 Libs 
auskommen zu wollen.

So wie die Implementierung in C++ aussieht gefällt sie mir aber nicht. 
In meinen Augen verkompliziert die Nutzung aller modernen 
Sprachkonstrukte von C++ die Lesbarkeit deutlich.
Solche Zeilen wie:

usb_always_inline constexpr std::array<Util::EncChar, 
Util::staticSum<size_t> (16, Util::arrSize<T> ()...)> compatId (uint16_t 
bcdVersion, uint16_t wIndex, T&&... functions) {

mögen zwar technisch das absolute Highlight sein, mir ist das zu viel 
des Guten. Insbesondere die gesamten Verrenkungen um einen (simplen) USB 
Descriptor zu definieren. Wenn man nach 5 Jahren auf den Code sieht 
blickt man genauso wenig durch wie bei einer reinen C-Programmierung. 
Ich baue meine Projekte auch mit C++, vielleicht sollte man das besser C 
mit Klassen nennen, ich versuche aber vordergründig das Problem zu 
lösen.
W.S. hatte hier auch immer mal auf einen Code verwiesen der nur C und 
auch keine STM32 lib verwendet:
http://www.mikrocontroller.net/attachment/275250/USB-CDC_NXP_STM.zip

Aber das ist nur meinen persönliche Meinung.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

temp schrieb:
> Insbesondere die gesamten Verrenkungen um einen (simplen) USB
> Descriptor zu definieren.
Es wäre etwas inkonsistent die simplen Deskriptoren direkt als Array zu 
definieren, und die anderen per Metaprogrammierung zu erzeugen. Und eine 
ähnlich komfortable, flexible und effiziente Möglichkeit das z.B. für 
die String-Deskriptoren in C zu tun gibt es m.W. nicht.

temp schrieb:
> vielleicht sollte man das besser C
> mit Klassen nennen, ich versuche aber vordergründig das Problem zu
> lösen.
Finde ich blöd, da entgeht einem doch vieles. Ohne constexpr z.B. wird 
das Programm größer und langsamer.

temp schrieb:
> Wenn man nach 5 Jahren auf den Code sieht
> blickt man genauso wenig durch wie bei einer reinen C-Programmierung.
Deswegen sind da ja auch Kommentare...

temp schrieb:
> W.S. hatte hier auch immer mal auf einen Code verwiesen
Ja ich weiß. Hier ist übrigens der Original-Thread zu dem der Anhang 
gehört: Beitrag "Re: STM32F4 USB CDC" Freu dich 
doch dass nicht alle Codes die gleichen Sprachmittel nutzen, da kannst 
du dir aussuchen was du nimmst.

Ich habe ja auch geschrieben, dass die Dateien mit den Metafunktionen 
nicht für Anfänger geeignet sind. Ich finde es gibt schon genug Threads 
für die Diskussion C vs C++, dieser muss da jetzt nicht auch noch 
ausarten. Es handelt sich um einen Beispiel -Code, den man nicht so 
übernehmen soll, er soll lediglich das Lesen des Tutorials vereinfachen. 
Idealerweise schreibt man sich beim Durchlesen seinen eigenen Code in 
der gewünschten Sprache & Struktur. Wenn man nicht ewig auf den 
Sprachmitteln von 1998 sitzen bleiben möchte, ist das auch eine gute 
Gelgenheit, sich aktuelle C++-Versionen anzuschauen.

Ich habe im GitHub-Projekt jetzt Projektdateien für die IDE's SW4STM32, 
Keil MDK 5, Atollic TrueSTUDIO und für gnu-arm-eclipse hinterlegt, die 
können alle C++14... Das sollte reichen, damit jeder damit anfangen 
kann.

von Stefan F. (Gast)


Lesenswert?

Ich wollte gerade deine Launch Configuration testen, aber ich habe nicht 
herausgefunden, wie man diese Files aktiviert/auswählt. Ich komme mir 
gerade ziemlich gehandicapt vor.

Kann mir da mal jemand auf die Sprüge helfen?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Ich wollte gerade deine Launch Configuration testen, aber ich habe nicht
> herausgefunden, wie man diese Files aktiviert/auswählt.

Neben dem Käfer-Symbol auf das kleine Dreieck klicken, da auf "Debug 
Configurations". Links in der Baumstruktur sollten die Konfigurationen 
auftauchen. Die anwählen, im Reiter "Common", bei "Display in favorites 
menu" bei "Debug" einen Haken machen. Dann müssten die Konfigurationen 
erscheinen, wenn du auf das Dreieck neben dem Käfer klickst.

Manchmal (aber nie auf meinem Computer...) erscheinen die 
Konfigurationen auch im "Debug Configurations" Menu nicht. Dann löscht 
man die Dateien unter "launch" und fügt im genannten Fenster ganz neue 
Konfigurationen hinzu, das ist auch nicht kompliziert... Man muss im 
Wesentlichen nur die richtige ELF-Datei angeben.

von Stefan F. (Gast)


Lesenswert?

Alles klar, hat funktioniert!

von Stefan F. (Gast)


Lesenswert?

Nochmal vielen Dank für deine Mühe. Ich hab einen entsprechende 
Empfehlung auf meiner Homepage platziert.

von temp (Gast)


Lesenswert?

Niklas G. schrieb:
> Ich habe ja auch geschrieben, dass die Dateien mit den Metafunktionen
> nicht für Anfänger geeignet sind. Ich finde es gibt schon genug Threads
> für die Diskussion C vs C++, dieser muss da jetzt nicht auch noch
> ausarten.

Ich will hier auch keine Diskussion C vs C++ los treten, aber du hattest 
um Feedback zum Tutorial gebeten. Und da ist es manchmal besser mit 
einfachen Sprachmitteln zu arbeiten. Ich habe jedenfalls mehr Mühe damit 
deinen Code zu lesen als die USB-Geschichten beim STM32F1 zu verstehen. 
Aber wie gesagt, das trifft nur für mich zu, andere haben damit 
sicherlich weniger Probleme.

Niklas G. schrieb:
>> vielleicht sollte man das besser C
>> mit Klassen nennen, ich versuche aber vordergründig das Problem zu
>> lösen.
> Finde ich blöd, da entgeht einem doch vieles. Ohne constexpr z.B. wird
> das Programm größer und langsamer.

Genau diesen Verallgemeinerungen kann ich überhaupt nichts abgewinnen. 
Wie gut oder schlecht ein Programm im embedded Bereich ist wird von weit 
weit mehr beeinflusst als dem Einsatz von constexpr oder nicht. 
Jedenfalls in dem Teil deines Codes der am Ende für den Transfer 
zuständig ist, konnte ich keine modernen C++ Sprachmittel finden die den 
Code schneller oder kleiner machen.

Niklas G. schrieb:
> Wenn man nicht ewig auf den
> Sprachmitteln von 1998 sitzen bleiben möchte, ist das auch eine gute
> Gelgenheit, sich aktuelle C++-Versionen anzuschauen.

Das ist richtig und ich verschließe mich dem auch nicht komplett. 
Allerdings trennen uns auch 32 Jahre und ich sehe für mich keinen 
Vorteil z.B. beim casten anstelle von "(uint8_t)" "static_cast<uint8_t>" 
schreiben zu müssen. Das ist mehr als das Doppelte an Schreibaufwand und 
die Zeit ist endlich. Die Weiterentwicklung von C++ geht in meinen Augen 
sowieso in die falsche Richtung. Vergleich mal verschiedene C++ 
Quelltexte der letzten Jahre. Es wird immer nur komplexer mit wesentlich 
mehr Formalismen im Quelltext. Zeit dass mal wieder jemand auf die Idee 
kommt, hier was zu vereinfachen. Welcher Entwickler schreibt schon gern 
Romane.

von Stefan F. (Gast)


Lesenswert?

Auch für mich sind die "neuen" Features von C++ hinderlich. Mein 
Fachwissen ist bei Version 99 stecken geblieben, weil ich seit dem fast 
ausschließlich in anderen Sprachen programmieren muss.

Andererseits empfinde ich dieses Beispielprojekt als gute Gelegenheit, 
mein Fachwissen upzudaten.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Nochmal vielen Dank für deine Mühe. Ich hab einen entsprechende
> Empfehlung auf meiner Homepage platziert.
Hey danke auch ;-) Du hast deine Seite ja gar nicht verlinkt...

temp schrieb:
> Ich will hier auch keine Diskussion C vs C++ los treten, aber du hattest
> um Feedback zum Tutorial gebeten.
Ja okay. Letztendlich kann man's eh nicht jedem Recht machen.

von Stefan F. (Gast)


Lesenswert?

> Du hast deine Seite ja gar nicht verlinkt...

Ja, weil ich dachte, wer deinen Code durchschaut, der braucht meine 
Anfängertips nicht.
http://stefanfrings.de/stm32/index.html

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Ja, weil ich dachte, wer deinen Code durchschaut, der braucht meine
> Anfängertips nicht.
Achwas. Es ist immer was dabei was man noch nicht kennt. Und du listest 
ja noch viel mehr als nur STM32-Sachen auf...

> Auf der Webseite von STM gibt es den "STM32 Virtual COM Port Driver" zum
> Herunterladen, aber den braucht man gar nicht, da alle aktuellen
> Betriebssysteme den CDC Standardtreiber bereits enthalten.
Fun Fact: Der Treiber-Installer enthält überhaupt keinen Treiber, nur 
eine .inf-Datei, welche Windows anweist, den mitgelieferten Treiber 
(usbser.sys) zu laden. Das ist bis Windows 8 nötig, denn bis dahin war 
Windows nicht dazu in der Lage, Standard-Klassen zu erkennen...
Das kann man so herausfinden: Treiber-Installer starten, nach %TEMP% 
gehen, nach *.msi suchen und eine "Virtual Com port driver V1.4.0.msi" 
finden. Die öffnet man mit 7-Zip, die darin enthaltene Data1.cab ebenso, 
und darin ist nur die .inf Datei, die zugehörige .cat (Signatur), und 
das MS Programm dpinst zur Installation derselben, aber kein 
eigentlicher Treiber...

Eigentlich fehlt im Tutorial noch eine Anleitung wie man so eine 
.inf+.cat Datei für den VCP anlegt; habe aber gar kein altes Windows 
mehr und hoffentlich ist Windows 10 schon verbreitet genug dass es nicht 
mehr nötig ist. Unter Windows 10 ist es ja nicht nur unnötig sondern 
auch noch fast unmöglich weil die Prüfung der Treiber-Signatur kaum zu 
umgehen ist.

von Stefan F. (Gast)


Lesenswert?

> Fun Fact: Der Treiber-Installer enthält überhaupt keinen Treiber

Ich weiß. Da habe ich auch gestaunt, als ich dahinter gekommen bin.

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Niklas G. schrieb:
>> W.S. hatte hier auch immer mal auf einen Code verwiesen
> Ja ich weiß.

Das ist allerdings ne ältere Version. Ich hänge hier mal was 
ausführlicheres dran.

Bei deinem Projekt fehlt mit übrigens was, nämlich eine klare 
Systemschnittstelle.

Wie stellst du dir eigentlich vor, daß dein USB-Teiber von jemandem 
genutzt werden kann? Immerhin reden wir ja über einen virtuellen 
COM-Port als Ersatz für den "mittlerweile etwas angestaubten 
Serial-Port", oder etwa nicht?

Sowas sollte sich aus Sicht des anwendenden Programmes eben genau so 
benutzen lassen wie ein gewöhnlicher serieller Port. Das sehe ich bei 
deinem Projekt jedoch nicht.

Und in deinen Headerdateien steht zu viel drin. Fast alles sind diverse 
Interna deines Projektes, die für die Anwendung des Ganzen nur 
verwirrend wirken. Wo bleibt da die Kapselung des Codes?

Nochwas: Wo ist die Zwischenspeicherung der zu sendenden und empfangenen 
Zeichen? USB ist im Prinzip blockorientiert und seriell ist im Prinzip 
asynchron, einzeln und zeichenorientiert. Das bedarf der 
Zwischenspeicherung und des Lesens und Schreibens von einzelnen Zeichen 
- und dies auch noch in unregelmäßigen, nicht vorhersehbaren Abständen. 
Das scheint mir bei deinem Projekt alles zu fehlen.

W.S.

von temp (Gast)


Lesenswert?

W.S. schrieb:
> Das ist allerdings ne ältere Version. Ich hänge hier mal was
> ausführlicheres dran.

Nimm's mir nicht für übel, aber deine Nop-Funktion ist noch genauso drin 
dass sie der gcc weg optimiert:
1
void Nop (dword count)
2
{ while (count) --count; }

Hatten wir schon mal hier im Forum. Sonst äußerst du dich auch zu allem 
Mist, warum hierzu nicht?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

W.S. schrieb:
> Das ist allerdings ne ältere Version. Ich hänge hier mal was
> ausführlicheres dran.
Ah. Verlink das doch mal hier: UART auf USB: Eigenbau. Da du für 
deinen Code keine Lizenz angegeben hast darf den übrigens keiner nutzen.

W.S. schrieb:
> Bei deinem Projekt fehlt mit übrigens was, nämlich eine klare
> Systemschnittstelle.
Die Klassen USBPhys und EPBuffer kapseln die Hardware schon ziemlich 
gut. Damit kann man sauber auf hoher Ebene programmieren.

W.S. schrieb:
> Wie stellst du dir eigentlich vor, daß dein USB-Teiber von jemandem
> genutzt werden kann?
Indem er das Tutorial durcharbeitet und sich seinen eigenen so 
implementiert, wie er ihn braucht. Wie gesagt handelt es sich um einen 
Beispiel -Code, der nicht 1:1 übernommen werden soll, wie das bei 
einer Bibliothek der Fall wäre, sondern lediglich die Lektüre des Texts 
vereinfachen soll.

W.S. schrieb:
> Das sehe ich bei
> deinem Projekt jedoch nicht.
Nachdem man die USB-Deskriptoren für CDC-ACM angepasst hat, wird ein 
Endpoint jeweils zu einem "Kanal" für eine serielle Schnittstelle, wie 
du sicher weißt. Die EPBuffer-Klasse bietet ein gutes API zum Zugriff 
darauf, somit kann man direkt darüber den VCP ansprechen. Über mein API 
kann man auch beliebig eigene Endpoints definieren.

W.S. schrieb:
> Und in deinen Headerdateien steht zu viel drin.
Wo soll das denn sonst hin? Immerhin hab ich nicht alles in einer 
riesigen Datei wie bei dir.

W.S. schrieb:
> Wo bleibt da die Kapselung des Codes?
Die Kapselung erfolgt über einzelne Klassen (OOP) statt über einzelne 
Header (prozedurale Programmierung). Daher sieht man schon an den 
Klassen-Namen, welche Funktionen zusammen gehören und auf einer Ebene 
arbeiten - bei dir hat man nur eine lose Sammlung an Funktionen, bei 
denen man vermutlich nur mit grafischem Call-Graph durchblickt. Meine 
usb.hh ist API-technisch schon gut aufgebaut, wenn man es unbedingt 
wollte könnte man die einzelnen Klassen noch in eigene Dateien 
schreiben. Da mein API im Gegensatz zu deinem asynchron über Callbacks 
arbeitet, braucht es etwas mehr Definitionen als deine Hand voll 
Funktionen.

W.S. schrieb:
> Das scheint mir bei deinem Projekt alles zu fehlen.
Das ist in der DoubleBuffer-Klasse angelegt, die dann von der VCP-Klasse 
genutzt wird. Damit können sehr wohl auch einzelne Zeichen bei langsamer 
Datenrate übertragen werden. Das ist auch alles hier im Abschnitt 
"Implementierung der Datenübertragung" erläutert.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Hallo W.S., gibt es irgendeinen Ort, auf den ich verlinken kann, wo man 
stets die aktuelle Version deiner Library vorfindet?

von W.S. (Gast)


Lesenswert?

Stefan U. schrieb:
> gibt es irgendeinen Ort

Nö. Der einzige Ort, wo du sowas findest, ist eben hier im Forum.

Ich unterhalte keine eigene Webseite.

Mir reicht es aus, hier und da jemandem mal helfen zu können, indem ich 
was aus meinem privaten Portfolio als Anhang poste, wenn es grad eben 
von Interesse ist.

Aber du kannst in den zwei weiter oben befindlichen Antworten ja sehen, 
wie sowas gelegentlich aufgenommen wird. Da klagt einer, daß der GCC 
sich daneben benimmt und der andere meint sogar, daß niemand mangels 
Lizenz es benutzen darf. Nun, ich sag mir immer, daß es wohl den einen 
oder anderen stummen Mitleser geben mag, dem mein Zeug zu was nütze 
gewesen ist.

Momentan hab ich den LPC4088 vor den Nase. Der hat zwar den gleichen 
USB-Core wie der LPC2478 oder LPC17xx, aber ne Kleinigkeit beim Senden 
von Daten µC-->Host klemmt noch. Anschließend kommt der LPC11C3x dran, 
denn den brauch ich für ein neues Bastel-Projekt. Nur so am Rande. Die 
übrigen treiber werkeln schon seit Jahren in diversen Projekten, so daß 
ich da keinen Aktualiserunsgbedarf habe.

W.S.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

W.S. schrieb:
> Da klagt einer, daß der GCC
> sich daneben benimmt
Der GCC darf Code der keinen Effekt hat wegoptimieren. Und eine leere 
Schleife hat keinen Effekt. Füg wenigstens ein __NOP() ein, da sieht der 
Compiler nicht mehr dass da nichts passiert. Ein Compiler der leere 
Schleifen nicht wegoptimiert wäre schon ziemlich schlecht.

W.S. schrieb:
> und der andere meint sogar, daß niemand mangels
> Lizenz es benutzen darf.
Nun, so steht es im Urheberrechts-Gesetz (§31, §34 Satz 1). Die 
Nutzungsrechte im Urheberrecht sind eine "White-List" - alles was nicht 
explizit erlaubt ist, ist verboten. Da du niemandem irgendwelche 
Nutzungsrechte erteilst (oder hab ich das nur nicht gesehen), darf man 
deinen Code nur ansehen. Den Code modifizieren, kompilieren, 
weitergeben, als Kompilat weitergeben ist nicht erlaubt. Deswegen ist 
z.B. GitHub auch so dahinter her, dass man immer eine Lizenz angibt, 
denn sonst sind die Inhalte quasi nutzlos, was GitHub dann nichts 
bringt: https://help.github.com/articles/licensing-a-repository/

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Niklas G. schrieb:
> Damit können sehr wohl auch einzelne Zeichen bei langsamer
> Datenrate übertragen werden. Das ist auch alles hier im Abschnitt
> "Implementierung der Datenübertragung" erläutert.

Kann, können.... Im Klartext heißt das "ist nicht, mußt du selber 
machen". Mag ja so sein, hat auch niemand was dagegen, aber sag es bitte 
DEUTLICH - und zwar in der Dokumentation im PDF-Format, die deinem 
Projekt beiliegt bzw. beiliegen sollte. Aus der Lektüre deiner Quellen 
geht das alles nämlich nicht hervor. Ich darf dich in dem Zusamenhang an 
deine eigenen Wort erinnern:

Niklas G. schrieb:
> habe ich ein Tutorial für die
> Implementation eigener USB-Devices verfasst, in der Hoffnung dass so
> mehr Hobby-Projekte auf den mittlerweile etwas angestaubten Serial-Port
> verzichten können.
> ...
> ... auf dem STM32F103 ...

Das Anliegen, für den STM32F103 einen vom Hobby-Projekt-Programmierer 
benützbaren USB-VCP zu schreiben, ist ja was Gutes - aber schau doch 
bloß mal, was du dem Hobbyisten in deinem GIT-ZIP-Clone bietest, den er 
sich herunterladen kann, um seine bisherige Kommunikation per UART gegen 
das Gleiche, jedoch per USB eintauschen zu können.

W.S.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

W.S. schrieb:
> Kann, können.... Im Klartext heißt das "ist nicht, mußt du selber
> machen". Mag ja so sein, hat auch niemand was dagegen, aber sag es bitte
> DEUTLICH - und zwar in der Dokumentation im PDF-Format, die deinem
> Projekt beiliegt bzw. beiliegen sollte.
Soll das ein Witz sein? Warum kritisierst du mich aufgrund frei 
erfundener Tatsachen? Mein Code kann, so wie er ist, einzelne 
Bytes/langsame Datenraten direkt übertragen, ohne auf das Auffüllen 
des Puffers (je 1kB) zu warten. Wenn du schon weder meinem Wiki-Text, 
noch dem Code 
(https://github.com/Erlkoenig90/f1usb/blob/vcp/src/vcp.cc#L316 , 
https://github.com/Erlkoenig90/f1usb/blob/vcp/src/vcp.cc#L267 ) nicht 
glaubst, lade dir doch einfach das Flash-Image herunter und probier's 
aus.

Meine Dokumentation ist im Wiki-Format. Du hast auch kein PDF in deinem 
Projekt.

W.S. schrieb:
> Das Anliegen, für den STM32F103 einen vom Hobby-Projekt-Programmierer
> benützbaren USB-VCP zu schreiben,
Du hast es nicht verstanden. Das ist dein Anliegen, nicht meines. 
Meines ist es, dem Hobby-Programmiere ein Tutorial zu bieten, mit dem er 
"richtige" USB-Geräte implementieren kann, ohne auf fertige Bibliotheken 
zurückgreifen zu müssen. Der VCP ist lediglich ein gefälliges Beispiel, 
auf Basis des Tutorials können auch beliebige andere Geräte 
implementiert werden (z.B. MSC). Das hättest du auch gemerkt, wenn du 
den Text und diesen Thread einfach gelesen hättest, statt hier nur zu 
lästern.

von Stefan F. (Gast)


Lesenswert?

Ich habe den Treiber von W.S. für das BluePill Board in ein System 
Workbench Projekt eingefügt und hier veröffentlicht:
http://stefanfrings.de/stm32/index.html#vcpnohal

Eine Frage dazu an W.S.:
Wer ist der Inhaber des Copyrights? Ich möchte ihn gerne persönlich 
kontaktieren.

von temp (Gast)


Lesenswert?

W.S. schrieb:
> Aber du kannst in den zwei weiter oben befindlichen Antworten ja sehen,
> wie sowas gelegentlich aufgenommen wird. Da klagt einer, daß der GCC
> sich daneben benimmt

Nicht der gcc benimmt sich daneben sondern du. Du bietest deinen Code 
hier wie Sauerbier an, nimmst aber Kritiken daran nicht an. Ich denke 
mal heimlich lachst du dir einen in Fäustchen wenn du mitbekommst, dass 
andere darauf reinfallen. Ist da Absicht dahinter?

W.S. schrieb:
> Nur so am Rande. Die
> übrigen treiber werkeln schon seit Jahren in diversen Projekten, so daß
> ich da keinen Aktualiserunsgbedarf habe.

Wenn einer auf Hinweise überhaupt nicht eingeht kann man das nur als 
Arrogant bezeichnen. Das ist so wie bei deiner Lernbetty die du hier 
auch jeden andrehen willst und deine Konzepte dabei als das einzig Wahre 
ansiehst. Mir gefällt die Implementierung von Günther auch nicht so 
richtig, aber das Tutorial ist wirklich gut. Danke nochmal dafür. Er 
erhebt aber auch im Gegensatzt zu dir nicht den Anspruch Unfehlbar zu 
sein.

W.S. schrieb:
> Mag ja so sein, hat auch niemand was dagegen, aber sag es bitte
> DEUTLICH - und zwar in der Dokumentation im PDF-Format, die deinem
> Projekt beiliegt bzw. beiliegen sollte. Aus der Lektüre deiner Quellen
> geht das alles nämlich nicht hervor.

Sorry, aber bitte fordere nichts von anderen ein, wenn du selbst nicht 
was ähnliches lieferst. Ich gehe sogar soweit zu vermuten, dass der Code 
den du hier immer reinstellst überhaupt nicht von dir ist und du ihn 
auch nicht verstehst. Aber Hauptsache immer große Töne spucken.

von Axel S. (a-za-z0-9)


Lesenswert?

W.S. schrieb:

> Niklas G. schrieb:
>> habe ich ein Tutorial für die
>> Implementation eigener USB-Devices verfasst
>
> Das Anliegen, für den STM32F103 einen vom Hobby-Projekt-Programmierer
> benützbaren USB-VCP zu schreiben

Das mit dem Lesen mußt du noch üben. Denn das ist gerade nicht sein 
Anliegen. Auch nicht meins. Und vermutlich auch nicht das irgend eines 
anderen Lesers in diesem Thread. Wer eine schlüsselfertige VCP 
Implementierung sucht, findet sie in der SPL, in der Cube Lib, in 
libopencm3 und an ca. einem Dutzend anderen Stellen.

von W.S. (Gast)


Lesenswert?

temp schrieb:
> Wenn einer auf Hinweise überhaupt nicht eingeht kann man das nur als
> Arrogant bezeichnen. Das ist so wie bei deiner Lernbetty die du hier
> auch jeden andrehen willst

Ach nö. So nicht.

Wer mein Zeugs so verachtet wie du, der soll's halt bleiben lassen.

Und nochwas zur Lernbetty: Das war ein Gemeinschaftsprojekt und wenn du 
es genau wissen willst, dann guck einfach hier in diesem Forum in die 
zugehörigen Beiträge.

W.S.

von W.S. (Gast)


Lesenswert?

Stefan U. schrieb:
> Ich habe den Treiber von W.S. für das BluePill Board in ein System
> Workbench Projekt eingefügt und hier veröffentlicht:

Hmm... hab mir mal deine Inet-Seite angeschaut und verstehe, daß du 
deswegen am liebsten in meinen Quellen ein Impressum hättst. Ja, sie 
sind selbstgeschrieben und zwar strikt außerhalb dienstlicher 
Obliegenheiten. Das sollte an dieser Stelle reichen.

W.S.

von Stefan F. (Gast)


Lesenswert?

> Ja, sie sind selbstgeschrieben und zwar strikt
> außerhalb dienstlicher Obliegenheiten.

Dann sollte dort der Firmenname nicht drin stehen, finde ich.

Dein Statement stellt mich aus einem anderen Grund kaum zufrieden. Du 
hast es nämlich als anonymer Gast gepostet. Das hätte jede beliebige 
Person tun können, kann also eine Fälschung sein.

Kannst du mir das bitte per Email mit deiner Postanschrift und deinem 
echten namen schicken, damit ich notfalls etwas rechtsgültiges in der 
Hand habe? Ich werde deine Mail vertraulich behandeln.

Oder ist es Dir lieber, wenn ich die Firma Nuvoton anschreibe um das 
aufzuklären?

Verstehe mich bitte nicht falsch. Ich will hier niemandem Probleme 
bereiten, auch nicht mir selbst. Als Inhaber meiner Webseite bin ich in 
gewissem Maße verpflichtet, die Rechtmäßigkeit der Sachen zu prüfen, die 
ich dort veröffentliche.

Ich habe großes Interesse an deinem Code, denn ich konnte ihn ohne 
Schwierigkeiten verwenden. Daher möchte ich ihn gerne weiter empfehlen.

von W.S. (Gast)


Lesenswert?

Stefan U. schrieb:
> Verstehe mich bitte nicht falsch.

Nee, ich verstehe dich vollkommen.

Und wenn du dir mal den USB-Treiber von Nuvoton anschaust, der zu 50% 
aus geschachtelten Makros und 50% aus Arrays von void Pointern besteht, 
dann verstehst du gewiß auch, daß ich da lieber meinen eigenen Treiber 
konzipiert und geschrieben habe - das war der erste aus meiner Feder und 
er war für die NUC120 von Nuvoton. Genau deshalb habe ich auch deren vid 
und pid übernommen. 0416 gehört Winbond (Nuvoton ist ein Teil davon) und 
5011 ist VCP, siehe:
0416  Winbond Electronics Corp.
  0035  W89C35 802.11bg WLAN Adapter
  0101  Hub
  0961  AVL Flash Card Reader
  3810  Smart Card Controller
  3811  Generic Controller - Single interface
  3812  Smart Card Controller_2Interface
  3813  Panel Display
  5011  Virtual Com Port
  5518  4-Port Hub
  551a  PC Sync Keypad
  551b  PC Async Keypad
  551c  Sync Tenkey
  551d  Async Tenkey
  551e  Keyboard
  551f  Keyboard w/ Sys and Media
  5521  Keyboard
  6481  16-bit Scanner
  7721  Memory Stick Reader/Writer
  7722  Memory Stick Reader/Writer
  7723  SD Card Reader

Das Zitat der Anleitung von Nuvoton (NuvotonCDC.inf) und die Namen in 
den Descriptoren hab ich bei allen weiteren Versionen unverändert so 
gelassen. Wenn du damit mentale Probleme kriegst, mußt du dann auch 
akzeptieren, daß man für einen eigenen Satz aus vid&pid Geld zahlen muß. 
Wer das nicht kann oder will, muß dann eben vid&pid benutzen, die 
anderen Leuten gehören.

Ich glaube auch nicht, daß 0xdead und 0xbeef frei verfügbar sind. 
Allenfalls sind sie noch nicht vergeben, was aber nicht heißt, daß man 
sie freiweg benutzen darf, ohne womöglich schon morgen mit jemandem zu 
kollidieren. Da ist mir eine eingeführte ID eines chinesischen 
Herstellers wie Winbond lieber.

Verstehe mal bitte, daß dieses Thema grundsätzlich gegen jegliche freie 
Software gerichtet ist. Bei usb.org kannst du nachlesen, daß die in 
jedem Falle Geld sehen wollen und daß es nirgendwo wirklich freie vid's 
gibt.

So. Wenn also jemand hier im Forum für seine Basteleien mit dem BluePill 
aus China eine .inf braucht, um per USB zu Potte zu kommen, dann ist und 
bleibt sowas im Rahmen privater Basteleien.

Wenn aber jemand wie du eine durchaus umfängliche Internet-Seite 
aufzieht, dann vestehe ich durchaus, daß dich fragst, ob und in welchem 
Umfang dir jemand deswegen an die Karre fahren könnte. Die generelle 
Antwort ist klar: egal, was du für eine ID dort angibst, bist du immer 
einer, der sie nicht bezahlt hat. Und mir ist kein einziger 
Chip-Hersteller bekannt, der irgend eine vid/pid-Kombination für umsonst 
an bedürftige Bastler abgibt. Über den Quellcodes eines Treibers aus 
privater Hand regt sich keiner auf, aber mit den ID's kann man durchaus 
Kollisionen erleiden.

Das ist alles ein schwieriges Thema, denn es ist schlichtweg kommerziell 
orientiert - ohne Raum zu lassen für Bastler.

W.S.

von W.S. (Gast)


Lesenswert?

Nochmal was zum Thema:
siehe dort
https://community.nxp.com/thread/383702

W.S.

von Max G. (l0wside) Benutzerseite


Lesenswert?

W.S. schrieb:
> Das ist alles ein schwieriges Thema, denn es ist schlichtweg kommerziell
> orientiert - ohne Raum zu lassen für Bastler.

Wenn man bereit ist, einen PIC zu verwenden, hilft Microchip gerne aus. 
Ich erinnere mich dunkel, dass bei ST auch mal eine Diskussion dazu 
lief, aber Support ist gefühlt nicht die Stärke von ST.

Ob es reicht, einen nicht beschalteten PIC auf die Leiterplatte zu 
setzen, um die Microchip-VID verwenden zu dürfen? Könnte für Kleinserien 
durchaus kommerziell sinvoll sein.

von Stefan F. (Gast)


Lesenswert?

Für meine Hobby-Projekte ist die Problematik mit der vid vollkommen 
egal.

von Jupp (Gast)


Lesenswert?

Ein durchaus interessanter Beitrag zum Thema USB auf einem STM32F1.
Wenn dieser Thread früher erschienen wäre, als mein Hobby Projekt genau 
dieses Stück Hardware auf einem STM32F7 aktivierte, hätte ich bestimmt 
zu einem FTDI gegriffen, statt den CDC zu benutzen.
Auch ich bin kein Befürworter dieser ewigen Debatten um die benutzte 
Porgrammiersprache. Ob nun C oder C++ eingesetzt wird, muss letztenendes 
jeder für sich entscheiden. Tendenziell finde ich ganz wenig Projekte 
die in C++ auf einem STM32Fxx benutzen. Warum dass so ist kann ich nicht 
sagen. Selbst freeRTOS, welches gern mal in kommerziellen Projekten 
Verwendung findet, ist nicht in C++ angelegt.
Hobby-Projekte können sicherlich von den durchaus vorhandenen Vorteilen 
einiger C++ Konstrukte profitieren. Für die meissten Anwender aus dem 
Hobby-Bereich dürften die komplexer gewordene Sprachgewalt von C++ etwas 
zu weit gehen.
Betrachte ich die Quellen einiger MBED-Projekte an, so ist es auch nur 
ein Mix aus C und C++. Die Sprachanwendung gehen selten über die Nutzung 
von Namensräumen hinaus. Ob ein Programm schneller oder langsamer läuft, 
hängt wohl nicht so sehr davon ab in welcher Sprache er geschieben ist, 
sondern wohl mehr, wie gut das Projekt umgesetzt ist - also die Qualität 
der Kodierung und der Programmstruktur. Die Programmgröße ist ist von 
vielen weiteren Faktoren abhänig. Der Compiler und seine Úmgangsweise 
mit den Quellen ist dabei nur ein Faktor. All dies mag dem Kommerziellen 
wichtig sein denn es sind letztendlich Kosten. Dem Hobby-Bastler ist das 
recht egal. Er nutzt einen kostenlosen GCC mit default-Einstellungen und 
programmiert und bastelt einfach drauflos.
Diese Situation wird sich auch nicht maßgeblich ändern denn Unternhemen 
wie ST oder andere, vertreiben ihre freie IDE nur mit "C" Libraries.
Ein schönes Beispiel ist die HAL oder das CMSIS. Da nutzt es wenig wenn 
man C++ Projekte anlegbar sind. Für den Profi kein Hindernis, für den 
Hobby-Bastler einfach zu aufwendig und komplex.

von Niklas Gürtler (Gast)


Lesenswert?

Jupp schrieb:
> Ein durchaus interessanter Beitrag zum Thema USB auf einem STM32F1.
Danke ;-)

Jupp schrieb:
> Wenn dieser Thread früher erschienen wäre, als mein Hobby Projekt genau
> dieses Stück Hardware auf einem STM32F7 aktivierte, hätte ich bestimmt
> zu einem FTDI gegriffen, statt den CDC zu benutzen.

Der F7 hat leider die deutlich kompliziertere "OTG_USB" Hardware, die 
vom Tutorial nicht abgedeckt ist...

Jupp schrieb:
> Auch ich bin kein Befürworter dieser ewigen Debatten um die benutzte
> Porgrammiersprache.

Endlich etwas Vernunft :)

Jupp schrieb:
> Ob ein Programm schneller oder langsamer läuft, hängt wohl nicht so sehr
> davon ab in welcher Sprache er geschieben ist, sondern wohl mehr, wie
> gut das Projekt umgesetzt ist - also die Qualität der Kodierung und der
> Programmstruktur

So ist es... die großzügige Nutzung virtueller Funktionen verschwendet 
ein paar Takte, wenn man die wirklich braucht kann man den Code immer 
noch umbauen. Die ST USB Library konvertiert "on the fly" die USB 
Deskriptoren von ASCII nach UTF-16, während der C++ Code a) nicht auf 
ASCII beschränkt ist und b) alle Konvertierungen beim Kompilieren 
vornimmt, hier also sogar schneller ist. So absolut sind die 
Verhältnisse also nicht...

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Es gibt ein kleines Update: Ich habe ein Beispiel hinzugefügt, welches 
vom PC/Host einen Strom anfordert und bei Freigabe durch den Host einen 
Pin schaltet. Damit können eigene Geräte per USB mit bis 500mA versorgt 
werden, ohne die Spezifikation zu verletzen und im schlimmsten Fall den 
Host zu beschädigen. Der genutzte STM32 ist damit natürlich stark 
unterfordert, dafür kann der zuvor erstellte Code so weiter genutzt 
werden.

Erläuterung:
USB-Tutorial mit STM32: Stromversorgung per USB

Code & fertiges Image zum Flashen:
https://github.com/Erlkoenig90/f1usb/releases/tag/v1.1

: Bearbeitet durch User
von P.Loetmichel (Gast)


Lesenswert?

>Ob nun C oder C++ eingesetzt wird

Es fehlt noch ein Bascomcompiler.
Dann können auch Profis den STM32 benutzen!

von Stefan F. (Gast)


Lesenswert?

P.Loetmichel schrieb:
> Es fehlt noch ein Bascomcompiler.
> Dann können auch Profis den STM32 benutzen!

Das war jetzt ironisch gemein, oder?

Niklas G. schrieb:
> Ich habe ein Beispiel hinzugefügt, welches vom PC/Host einen
> Strom anfordert und bei Freigabe durch den Host einen
> Pin schaltet.

Super, das ist echt nett von Dir.

von Christopher J. (christopher_j23)


Lesenswert?

Vielen Dank erstmal an Niklas für das Tutorial und den Code.

Da hier ja schon über VIDs und PIDs diskutiert wurde, möchte ich an 
dieser Stelle mal auf pid.codes hinweisen, welche die VID 0x1209 
besitzt. Deren Test-PID 0x0001 kann man sicher problemlos verwenden, 
ohne das einem irgendjemand ans Bein pinkelt. Die Erklärung dazu wie es 
dazu kam findet man hier: 
https://hackaday.com/2015/04/03/usb-pids-for-all/

von M.S. (Gast)


Lesenswert?

Auch ich möchte Herrn Gürtler meinen Dank aussprechen für das tolle 
Tutorial und den gelungenen USB-Treiber.
Da ich als mich als Neuling absolut nicht mit dem HAL von STM 
beschäftigen wollte, sondern ein "blue pill" Board als "bare metal" 
programmieren wollte, war dieser Treiber nach längerer Suche der für 
mich am besten geeignete für ein kleines USB-MIDI Projekt.
Er ist recht leicht erweiterbar und funktionierte sofort, einfach 
klasse!
Auch gibt es dank der sehr permissiven Lizenz fast keine 
Einschränkungen.
(Der vom Author W.S. erstellte USB Treiber ist schon allein aus nicht 
vorhandenen Lizenzhinweisen unbenutzbar.)

Beim blue-pill board funktioniert ein USB Reset gut, wenn man den USB 
+Pin (A12) erst als Output konfiguriert, ihn einige ms auf low setzt und 
erst dann als USB Port aktiviert.

Ein kleiner Hinweis zu kommerziell verwendbaren VIDs/PIDs.
Für ein paar Euro kann man bei bei einigen Firmen (z.B. aus den 
Niederlanden) eine freie Kombination erwerben.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Schön dass es jemand sinnvoll nutzt :-)

M.S. schrieb:
> Beim blue-pill board funktioniert ein USB Reset gut

Netter Trick... Hoffentlich beschädigen die 0V den Host nicht.

von M.S. (Gast)


Lesenswert?

Folgendes steht in der USB Spezifikation.
"""
A USB transceiver is required to withstand a continuous short circuit of 
D+ and/or D- to GND, other data line, or the cable shield at the 
connector, for a minimum of 24 hours without degradation. It is 
recommended that transceivers be designed so as to withstand such short
circuits indefinitely. The device must not be damaged under this short 
circuit condition when transmitting 50% of the time and receiving 50% of 
the time (in all supported speeds). The transmit phase consists of a 
symmetrical signal that toggles between drive high and drive low.
"""
Damit sollte ein kurzer 'short circuit' von ein paar ms eigentlich kein 
Problem sein.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Gut zu wissen, danke! Da hatte ich beim Spezifikations-Lesen die 
Informatikerbrille auf und hab den elektrischen Teil übersprungen... ;-)

von Klaus L. (keyel80)


Lesenswert?

Großes Kompliment für die Architektur dieser USB-Bibliothek und die 
dazugehörige Beschreibung! USB verliert damit zumindest zum Teil seinen 
Schrecken ;-)
Ich arbeite ansonsten mit dem STM32F4 und würde gerne diese Bib auch mit 
dieser Chipfamilie einsetzen. Hast jemand bereits eine nutzbare 
Portierung auf den F4 oder muss/darf/soll ich mich selbst ans Werk 
machen?

Vielen Dank!

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Klaus L. schrieb:
> Großes Kompliment für die Architektur dieser USB-Bibliothek

Danke ;-)

Klaus L. schrieb:
> Hast jemand bereits eine nutzbare
> Portierung auf den F4

Von meiner Bibliothek m.W. nicht. Die "OTG"-USB-Peripherie der F4 ist 
leider deutlich komplexer und noch schlechter dokumentiert. Ich hatte 
mal ein Minimalst-Proof-of-Concept dafür gebastelt, was aber weit von 
einer nutzbaren Implementation entfernt ist. Eine solche hätte aber den 
Vorteil, dass sie auch auf ganz anderen Controllern und auch SoC's 
anderer Hersteller funktioniert, weil diese Peripherie ein IP-Block von 
Synopsys ist den verschiedene Hersteller nutzen.
Ein Traum wäre natürlich eine portable Bibliothek mit einheitlichem API 
für verschiedene Controller, aber wer hat da Zeit für :-)

von Max G. (l0wside) Benutzerseite


Lesenswert?

Falls du auch ein Embedded OS in Betracht ziehen würdest, kannst du mal 
hier schauen: 
https://github.com/dismirlian/ChibiOS-Contrib/tree/master/os/hal

Das OS und sein HAL unterstützen den F4, einschließlich USB. Ob der USB 
OTG ebenfalls auf dem F4 unterstützt wird, kann ich dir aber nicht 
sagen.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Max G. schrieb:
> Ob der USB
> OTG ebenfalls auf dem F4 unterstützt wird, kann ich dir aber nicht
> sagen.

Anscheinend ja:

https://github.com/ChibiOS/ChibiOS/blob/master/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c

Die Frage ist dann: Muss man das gekoppelt an ein RTOS nutzen, oder 
geht das auch stand-alone?

von Max G. (l0wside) Benutzerseite


Lesenswert?

Ich steige gerade von bare metal auf ChibiOS um, bin also nicht ganz 
neutral (d.h. ich frage mich, warum ich mir bisher so viel Stress 
angetan habe).

Lies mal hier nach: 
https://www.playembedded.org/blog/chibioshal-design-an-object-oriented-approach/

von Pieter (Gast)


Lesenswert?

moin moin,

also ich arbeite in Pascal, c nur wenn ich dafür bezahlt werde.
Für den F103/F303 habe ich USB-HID am "laufen".
Den USB-Reset mache ich auch mit auf Low-ziehen, bisher an verschiedenen 
PC kein Problem.
Den Treiber habe ich dann für ein Projekt auch auf einem C8051F340 in 
Turbo51 übersetzt. Geht auch.

Der F407 braucht eine andere USB-Software, die geht aber auch.
Da ich ohne HAL arbeite, ist die Übersetzung nach c nur schreibarbeit.

Mit Gruß
Pieter

von MaWin (Gast)


Lesenswert?

@erlkönig
Ein riesiges großes Lob für deine Arbeit. ???

von Phozer (Gast)


Lesenswert?

Hat dies schon jemand mit einem Nucleo und der STM32CubeIDE versucht?
Versuche das ganze zu portieren, aber es gelingt mir nicht, weil der 
generierte Code von Cube sehr stark vom Code von Niklas abweicht.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Von welchem Nucleo genau reden wir? Mein USB-Code sollte mit der 
STM32CubeIDE funktionieren. Im Repository sind auch Projektdateien für 
die STM32CubeIDE im Archiv STM32CubeIDE.zip . Man darf natürlich nicht 
simultan mit der HAL auf die USB-Peripherie zugreifen. Du musst 
letztlich nur meine Dateien in das Projekt kopieren und dafür sorgen 
dass sie mit C++14 kompiliert werden. In STM32CubeMX darfst du den 
USB-Core natürlich nicht konfigurieren und die USB-Device-Library nicht 
hinzufügen.

: Bearbeitet durch User
von Phozer (Gast)


Lesenswert?

Niklas G. schrieb:
> Von welchem Nucleo genau reden wir?

Ein NUCLEO-G431KB. Dieser hat aber so viel ich weiss nur zwei USART. Der 
NUCLEO-F042K6 hätte ich auch noch, dieser sollte 3 USART haben. USB_FS 
haben beide.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Phozer schrieb:
> Ein NUCLEO-G431KB. Dieser hat aber so viel ich weiss nur zwei USART. Der
> NUCLEO-F042K6 hätte ich auch noch, dieser sollte 3 USART haben. USB_FS
> haben beide.

ST nennt diese Peripherie einfach "USB" (im Unterschied zu OTG_FS und 
OTG_HS der größeren Controller). Damit sollte es prinzipiell gehen, aber 
das habe ich nicht getestet. Eventuell sind kleine Anpassungen nötig. 
Insbesondere haben diese neueren Controller einen integrierten Pull-Up, 
sodass man die Ansteuerung des externen nicht mehr braucht. Den steuert 
man über das DPPU Bit im USB_BCDR Register, welches die STM32F1 gar 
nicht haben.

: Bearbeitet durch User
von Pieter (Gast)


Lesenswert?

moin,

>>Phozer mit NUCLEO-G431KB

da würde ich ein USB-core wie im F407 erwarten.
Das USB Core F103/F303  ist ein andere Aufbau als der Core F4xx.

VG
Pieter

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Pieter schrieb:
> da würde ich ein USB-core wie im F407 erwarten.

Stimmt aber nicht, siehe Reference Manual. Der G4 hat wenig mit dem F4 
zu tun.

von Stefan F. (Gast)


Lesenswert?

Phozer schrieb:
> Hat dies schon jemand mit einem Nucleo und der STM32CubeIDE versucht?

Ich habe Niklas Code mal für das Blue-Pill Board und die System 
Workbench angepasst. Ich denke, dass du das Projekt auch mit der Cube 
IDE öffnen kannst und 1:1 auf dem Nucleo Board mit STM32F103 ausführen 
kannst.

http://stefanfrings.de/stm32/3-Fach-USB-UART.zip

Die Vorgehensweise war: Ein "Empty Project" mit der IDE anlegen, dann 
die CMSIS und die Files von Niklas dazu kopieren.

Auf dem STM32G431 wird der Code vermutlich nicht ohne Anpassungen 
laufen.

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.