Forum: Mikrocontroller und Digitale Elektronik Warum ist die USB/CDC Implementierung der Cube HAL so groẞ?


von Nemopuk (nemopuk)


Angehängte Dateien:

Lesenswert?

Eine minimale Hello-World Anwendung belegt auf STM32F3 ca. 20 kB Flash, 
wenn sie mit der Cube-HAL oder Arduino (was ja darauf basiert) erstellt 
wird.

Eine alternative Implementierung, die ich hier im Forum gefunden habe, 
braucht jedoch nur 5 kB. Der Effekt betrifft nicht nur den STM32F3 auf. 
Ich konnte ihn ebenso mit anderen STM32 Familien reproduzieren.

Mir ist durchaus Klar, dass das Framework alleine aufgrund seiner 
Struktur einen gewissen Overhead mit sich bringt. Aber dass es so viel 
ist, überrascht mich dann doch. Enthält die USB/CDC Implementierung der 
HAL vielleicht irgend welche nützlichen Zwangs-Features, die über die 
minimale CDC Implementierung hinaus gehen?

Falls es jemand nachvollziehen will, das ist mein vollständiger Arduino 
Sketch, der die 20 kB ergibt:
1
void setup() {
2
    pinMode(PC13, OUTPUT);
3
}
4
5
void loop() {
6
    digitalWrite(PC13, LOW);
7
    Serial.println("Tick");
8
    delay(500);
9
10
    digitalWrite(PC13, HIGH);
11
    Serial.println("Tack");
12
    delay(500);
13
}

Das andere Projekt (für die STM32 Cube IDE) habe ich angehängt.

Wer das angehängte Projekt compilieren will, muss die Suchpfade zur 
CMSIS Bibliothek einstellen. In meinem Fall:
- 
.arduino15/packages/STMicroelectronics/tools/CMSIS/6.2.0/CMSIS/Core/Incl 
ude
- 
.arduino15/packages/STMicroelectronics/hardware/stm32/2.12.0/system/Driv 
ers/CMSIS/Device/ST/STM32F3xx/Include

Oder aus dem STM32CubeF3 Paket nehmen
- https://www.st.com/en/embedded-software/stm32cubef3.html

Aber bitte hängt euch nicht an kleinen Unterschieden in den Compiler 
Optionen und loop() bzw. main() auf. Mir geht es nicht um 1 kB mehr oder 
weniger, sondern um den krassen Unterschied von 20 kB versus 5 kB.

: Bearbeitet durch User
von Vanye R. (vanye_rijan)


Lesenswert?

Du hast doch den Sourcecode oder? Warum liesst du den dann nicht und 
beantwortest deine Frage selber? Ich meine wofuer ist der wohl sonst da? 
Du kannst auch deinen Compiler bitten ein Mapfile anzulegen wo du fuer 
jedes Byte nachschauen kannst wo es bleibt.

Die allgemeine Antwort ist, die Welt besteht heute aus unfaehigen und 
faulen Programmierern die nur noch ihren Source von sonst wo 
zusammenkopieren, die fuer alles fertige Libs brauchen. Keiner versteht 
mehr im Detail was sein Programm eigentlich macht. Also werden die immer 
fetter.

Achte darauf das du nicht selbst zu so einem Loser wirst. .-)

Vanye

von Nemopuk (nemopuk)


Lesenswert?

Vanye R. schrieb:
> Warum liesst du den (source code) dann nicht und
> beantwortest deine Frage selber?

Hast du dir mal den Code der HAL angeschaut? Wenn ja, dann kennst du die 
Antwort. Ich frage hier lieber, als mich so tief einzuarbeiten, denn für 
mich sind Mikrocontroller nur ein kleiner Bestandteil von Hobby 
Projekten - nicht meine Lebensaufgabe.

Vanye R. schrieb:
> die Welt besteht heute aus unfaehigen und
> faulen Programmierern

Beruflich bin ich Softwareentwickler, aber nicht für Mikrocontroller. 
Ja, ich benutze sehr viele Bibliotheken (oft hunderte in einem Projekt) 
ohne sie im Detail zu kennen. Niemand gibt mir die Zeit, mich so 
intensiv damit zu beschäftigen, weil das wirtschaftlich nicht 
funktioniert. Ich werde nicht dafür bezahlt, jedes Bit dreimal von allen 
Seiten zu bewundern.

Ein Bauarbeiter analysiert auch nicht alle Bauteile, aus denen er ein 
Haus zusammen setzt. Das Haus muss zügig fertig werden, nur das zählt.

> Achte darauf das du nicht selbst zu so einem Loser wirst.

Beim Hobby hat man den Luxus, sich intensiver beschäftigen zu können, 
wenn man will. Mit dem angehängten kleineren Projekt habe ich das getan. 
Dort ist mir der Sinn von fast jeder einzelnen Zeile Code klar.

Die HAL ist mir allerdings eine Nummer zu groß. Dafür reicht meine 
Lebenszeit nicht aus. Und STM32 sind auch nicht die einzigen 
Mikrocontroller, mit denen ich hantiere. Wenn also jemand anderes die 
HAL gut kennt und meine Frage beantworten kann, dann wäre das super. 
Wenn nicht, dreht sich die Welt auch ohne Antwort weiter.

Wenn mir der Speicherplatz aus geht: Größere Speicher sind billiger als 
Arbeitszeit.

: Bearbeitet durch User
von Manuel H. (Firma: Universität Tartu) (xenos1984)


Lesenswert?

Anstatt mit dem (in der Tat umfangreichen und unübersichtlichen, und 
nicht unbedingt als Lektüre für den Anwender gedachten) Quelltext des 
HAL anzufangen, würde ich mir erst einmal die beiden erhaltenen 
Binärdateien (idealerweise im ELF Format) mit objdump vornehmen und 
schauen, welche Funktionen dort überhaupt eingebunden wurden. Die Namen 
der Funktionen findet man ja schon im entsprechender Header. Um zu 
sehen, wann und von wo sie aufgerufen werden, würde ich das ganze auch 
noch disassemblieren. Im Anschluss daran würde ich konkret diese 
Funktionen, die tatsächlich eingebunden und aufgerufen werden, im 
Quelltext des HAL suchen und einen Blick darauf werfen, was sie 
eigentlich tun. Das ist vielleicht zielführender, als in medias res zu 
gehen, wenn man noch gar nicht weiß, wo man die "Übeltäter" suchen soll.

Meine Vermutung: Die Arduino-Umgebung neigt dazu, eine Menge 
Initialisierung vor dem Aufruf von setup() vorzunehmen. Da werden der 
Timer für millis() gestartet, Standardwerte für Taktgeneratoren gesetzt, 
Interrupts eingestellt... Aus der Cube HAL werden daher einige 
Funktionen aufgerufen und somit eingebunden, die man eigentlich nicht 
bräuchte, um nur Hello World auszugeben. Und diese Funktionen sind nicht 
unbedingt klein, weil sie recht allgemein gehalten sind. Also wird eine 
Menge Code eingebunden, selbst wenn nur bestimmte Pfade innerhalb jeder 
Funktion tatsächlich ausgeführt werden, weil die Arduino-Initialisierung 
eben genau diese Funktion mit bestimmten Parameterwerten aufruft.

Wie gesagt, das ist nur meine Vermutung. Vielleicht hilft auch schon ein 
Blick auf den Arduino-Initialisierungscode, um von dort aus die 
aufgerufenen Funktionen zu identifizieren und dann gezielt unter die 
Lupe zu nehmen.

von Nick (b620ys)


Lesenswert?

Ich würde zuallererst die Compiler- und Linker-Optionen ansehen.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Manuel H. schrieb:
> Um zu sehen, wann und von wo sie aufgerufen werden, würde ich das ganze
> auch noch disassembliere

Ganz simpler Ansatz: die ELF Datei disassemblisieren, und 
durchschscrollen. Da sieht man recht schnell, welche Funktionen, oder 
Gruppen von Funktionen (typischerweise am Namen erkennbar, wie eben 
USBD_xxx) groß sind. "nm" kann auch die Größen der Funktionen ausgeben.

von Nemopuk (nemopuk)


Angehängte Dateien:

Lesenswert?

Manuel H. schrieb:
> im Quelltext des HAL suchen und einen Blick darauf werfen, was sie
> eigentlich tun.

Wenn du das schon mal gemacht hättest, würdest du es nicht empfehlen. 
Der USB Code ist extrem komplex verschachtelt. Daraus erschließt sich 
mir nicht, was den 4x so großen Code rechtfertigt.

Manuel H. schrieb:
> Meine Vermutung: Die Arduino-Umgebung neigt dazu, eine Menge
> Initialisierung vor dem Aufruf von setup() vorzunehmen.

Hatte ich vergessen zu schreiben, daß er auch ohne Arduino auf die ca. 
20 kB kommt? Arduinos Overhead ist hier ausnahmsweise mal irrelevant.

Nick schrieb:
> Ich würde zuallererst die Compiler- und Linker-Optionen ansehen.

Damit kann ich das binary nur noch größer machen. Habe ich vergessen zu 
erwähnen, daß diese Settings für meine Frage irrelevant sind?

Nochmal, die Frage war: Was kann die HAL Implementierung, was die andere 
kleinere Implementierung aus diesem Forum nicht kann?

Anbei die elf und map Dateien, sowie die Ausgabe von nm -S. Ich kann 
damit nichts anfangen.

: Bearbeitet durch User
Beitrag #8005681 wurde vom Autor gelöscht.
von Wastl (hartundweichware)


Lesenswert?

Nemopuk schrieb:
> Nochmal, die Frage war: Was kann die HAL Implementierung, was die andere
> kleinere Implementierung aus diesem Forum nicht kann?

Vermutlich alle Versionen "können" die mit einem STM32 an USB-
Implementierungen möglich sind.

Schaue ich mir das in CubeMX an, dann gibt es da eine ganze Menge:

- Communication Device Class
- Audio Device Class
- Download Firware Update Class
- Human Interface Device Class
- Custom Human Interface Device Class
- Mass Storage Class

Da wird nicht alles "von Haus aus" enthalten sein, aber der Kern-
Code muss so strukturiert sein dass alle Implementierungen
möglich sind. Das wird sicherlich einen Code Overhead verursachen.

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Mein Code enthält nur CDC.

> der Kern-Code muss so strukturiert sein dass alle Implementierungen
> möglich sind. Das wird sicherlich einen Code Overhead verursachen.

Sicher, aber kann das schon der Grund für ein 4x so großes Binary sein? 
Ich mag es nicht glauben. Sorry, aber ich bin von 8 Bit Mikrocontrollern 
anderes gewohnt (auch mit USB).

Kann die HAL ein seriöses Framework sein, wenn sie so schluderig mit der 
Code-Größe (und damit auch Performance) umgeht? Noch hoffe ich auf eine 
bessere Erklärung, die nicht so abtörnt.

: Bearbeitet durch User
von Manuel H. (Firma: Universität Tartu) (xenos1984)


Lesenswert?

Nemopuk schrieb:
> Wenn du das schon mal gemacht hättest, würdest du es nicht empfehlen.
> Der USB Code ist extrem komplex verschachtelt. Daraus erschließt sich
> mir nicht, was den 4x so großen Code rechtfertigt.

Tatsächlich habe ich das schon mal gemacht (für den F4 statt für den F3, 
aber die Komplexität dürfte ähnlich sein). Ja, es stimmt, der Code ist 
verschachtelt - aber mit nm oder objdump bekommt man ja immerhin eine 
Liste der Funktionen und kann sich erst einmal die einfachen vornehmen, 
statt der Verschachtelung zu folgen.

> Hatte ich vergessen zu schreiben, daß er auch ohne Arduino auf die ca.
> 20 kB kommt? Arduinos Overhead ist hier ausnahmsweise mal irrelevant.

Stimmt, du hast geschrieben, dass es auch nur mit Cube-HAL 20kB sind. 
Mir war nur entgangen, wie du den kleineren Code bekommst. (Deinen 
angehängten Code hatte ich nicht kompiliert, da ich keine IDE benutze.)

Nach kurzer Durchsicht (falls ich morgen etwas mehr Zeit habe, nehme ich 
mir die Dateien mal im Detail vor - ich bin neugierig) würde ich nach 
wie vor auf ausführlichere Initialisierung bei Cube-HAL vs. deinem 
kleineren Code tippen. Außerdem sehe ich im HAL Code DMA (scheint dein 
Code nicht zu benutzen), die einige generische Funktionen mit sich 
bringt. Außerdem eine Menge Timer-Funktionen (die vermutlich nur einmal 
aufgerufen werden - Initialisierung...). Und der PCD (Peripheral 
Controller Driver) fällt ebenfalls auf. Wie gesagt, mit etwas mehr Zeit, 
schaue ich gerne etwas genauer rein.

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Manuel H. schrieb:
> Tatsächlich habe ich das schon mal gemacht

Mein herzliches Beileid. Die dazu nötige Ausdauer habe ich nicht mehr.

Manuel H. schrieb:
> Außerdem sehe ich im HAL Code DMA (scheint dein
> Code nicht zu benutzen),

ja, das hast du richtig erkannt

> Und der PCD (Peripheral Controller Driver) fällt ebenfalls auf

Der ist mir auch auf aufgefallen. Ehrlich gesagt weiß ich nicht, was das 
ist. Im Reference Manual vom STM32F3 steht dazu nichts.

Laut 
https://deepwiki.com/grblHAL/STM32F3xx/4.2.3-usb-low-level-configuration 
geht es beim PCD offenbar darum, Takt und I/O Pins für USB zu 
konfigurieren. Also das, was die kleinere Implementierung mit nur 
wenigen direkten Registerzugriffen macht.

> mit etwas mehr Zeit, schaue ich gerne etwas genauer rein.

Das wäre echt super. Denn vielleicht verbirgt sich in dem ganzen Code 
irgendein nützliches Neben-Feature, womit man die Codegröße 
rechtfertigen kann (anstatt ihn "aufgeblasen" zu nennen).

Eigentlich will ich ja gar nicht über die HAL ab lästern. So 
programmiert man heute halt, das habe ich akzeptiert. Ich will nur 
verstehen, was zu der enormen Größe führt.

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Niklas G. schrieb:
> Ganz simpler Ansatz: die ELF Datei disassemblisieren, und
> durchschscrollen. Da sieht man recht schnell, welche Funktionen
> ... groß sind.

So richtig groß ist keine, aber es sind sehr viele.

: Bearbeitet durch User
von Jürgen (fiju)


Lesenswert?

Nach dem MAP Fils ist alles mit drin
I2C
ADC
SPI
...
Da sind ein paar Haken zuviel in den Einstellungen

von Nemopuk (nemopuk)


Lesenswert?

Jürgen schrieb:
> Nach dem MAP Fils ist alles mit drin
> I2C, ADC, SPI ...

Kann es sein, dass du dich in die "Discarded input sections" verlaufen 
hast? Ich sehe im Output von nm und objdump nur ungenutzte IRQ Vektoren 
für die von dir genannte Peripherie.

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Nur digitalWrite: 6 kB

digitalWrite + Serial.println (über UART): 12 kB

digitalWrite + Serial.println (über USB/CDC): 22 kB

digitalWrite + Serial.println (über USB/CDC) + analogRead: 27 kB

Es ist also wohl nicht nur der USB-Code, sondern einfach alles in dem 
Framework ist erstaunlich groß.

Beim PC habe ich mich längst daran gewöhnt, aber beim Mikrocontroller 
jucken mir bei dem Gedanken die Fußnägel. Die Vernunft sagt mir "scheiß 
drauf", aber ich kann es nicht ignorieren. Gibt es dafür kein 
funktionierendes De-Sensibilisierungs Programm ? :-)

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nemopuk schrieb:
> Es ist also wohl nicht nur der USB-Code, sondern einfach alles in dem
> Framework ist erstaunlich groß.

Ja so ist es, die ganze CubeHAL ist ziemlich "nicht-smart" 
implementiert. Alles wird sehr umständlich und explizit zur Laufzeit 
berechnet, jeder Datentyp ist ein 32bit-Integer usw. Die einzelnen 
Architekturschichten und Module sind penibel voneinander getrennt, 
obwohl sie in der Praxis nie unabhängig genutzt werden können. Gerade 
auch weil C wenig Möglichkeiten zur Modularisierung bietet wird es 
dadurch ziemlich kompliziert und dann doch nicht mehr so toll 
wiederverwendbar.

Man könnte den Code dennoch als einigermaßen "sauber" oder "gut 
strukturiert" bezeichnen, aber effizient wird er dadurch nicht. Er ist 
eigentlich schon einigermaßen übersichtlich, wenn man sich mal rein 
gearbeitet hat. ST-intern gibt es sicherlich Übersichtsdiagramme die 
vieles klarer machen, die bekommen wir aber nicht zu sehen...

Ich glaube das ist Absicht, damit das Heer an Junior-Entwicklern 
einigermaßen damit klar kommt, was bei cleveren effizienten Strukturen 
nicht mehr der Fall wäre. Das Heer an Entwicklern braucht man, weil es 
sehr viele Zeilen Code sind, weil der Code so stringend strukturiert 
ist, weil das für die Junior-Entwickler nötig ist, weil man so viele 
Entwicklerstellen eben primär mit Juniors besetzen muss, derer man ein 
Heer braucht weil ...

Richtig lustig wird es dann wenn man noch ein RTOS à la Zephyr drüber 
stülpt, dann hat es nochmal mehrere Abstraktionsschichten über der 
STM32CubeHAL.

Das alles ist natürlich nicht nur bei ST so, sondern Industrie-Standard. 
Ach, und LLMs kommen mit dem sehr expliziten Code sicher auch besser 
klar.

Nemopuk schrieb:
> Gibt es dafür kein
> funktionierendes De-Sensibilisierungs Programm ? :-)

Einfach mal die Kosten für Flash-Speicher mit den Kosten von 
Senior-Entwicklern vergleichen...

: Bearbeitet durch User
von Ben S. (bensch123)


Lesenswert?

Vanye R. schrieb:
> Die allgemeine Antwort ist, die Welt besteht heute aus unfaehigen und
> faulen Programmierern die nur noch ihren Source von sonst wo
> zusammenkopieren, die fuer alles fertige Libs brauchen. Keiner versteht
> mehr im Detail was sein Programm eigentlich macht. Also werden die immer
> fetter.

Also ich habe ehrlich gesagt kein Interesse mich groß in USB und fremde 
Bibliotheken einzuarbeiten. Ich habe auch keine Lust selber Monate und 
Jahre zu verbrauchen, um große Frameworks zu entwickeln, die vollends 
durchgeprüft werden müssen.

Wozu soll ich das Rad neu erfinden? Und die paar kB jucken mich nicht, 
da ich die heutigen Mikrocontroller in der Regel eh nur zu einem 
Bruchteil voll bekomme.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Nemopuk schrieb:

> Es ist also wohl nicht nur der USB-Code, sondern einfach alles in dem
> Framework ist erstaunlich groß.

Dafür gibt es zwei Hauptursachen:

1)
Die ganze Initialisierung passiert über Strukturen (und die sind dann 
auch noch standardmäßig zur Laufzeit beschreibbar), was dazu führt, dass 
sie sowohl im Flash als auch zur Laufzeit im RAM Platz verbrauchen.

Dieser Ansatz ist ganz schick, wenn irgendwas zur Laufzeit 
umkonfiguriert werden muss. Bloß unterstützt CubeMX das erstens nicht 
wirklich und zweitens braucht man es bei kleinen µC auch eher selten. 
Was natürlich der tiefere Grund dafür ist, dass CubeMX praktisch keine 
Unterstützung dafür liefert.

2)
Das Interrupthandling ist massiv suboptimal. Es wird immer das gesamte 
Gedöhns mitgeschleppt, welches praktisch alle möglicherweise auftretende 
Situationen abdeckt, auch wenn oft in der konkreten Anwendung der 
Hardware 2/3 bis 3/4 davon unmöglich auftreten können. Und natürlich 
wird auch hier wieder massiv mit Strukturen im RAM gearbeitet, in denen 
die aufgelaufene Weisheit der Interuptroutine (aus der Abfrage der 
ganzen Hardware-Flags) etwas handlicher abgelegt wird, bevor der 
Callback des Frameworks aufgerufen wird.

Der unbestreitbare Vorteil ist hier, dass aus Sicht der Awnendung das 
Handling massiv vereinfacht wird. Es spielt fast keine Rolle mehr, ob 
Polling, Interruptbetrieb oder Interruptbetrieb mit DMA verwendet wird.

> Beim PC habe ich mich längst daran gewöhnt, aber beim Mikrocontroller
> jucken mir bei dem Gedanken die Fußnägel. Gibt es dafür kein
> funktionierendes De-Sensibilisierungs Programm ? :-)

Man kann STM32 auch zu Fuß programmieren. Das macht aber sehr viel mehr 
Arbeit und ist allenfalls für die ganz kleinen STM32 zu empfehlen.

Der Witz ist allerdings: in vielen Fällen kann HAL-freier Code dafür 
sorgen, dass man mit einem deutlich kleineren STM32 auskommt, als man 
ihn bei Verwendung der HAL brauchen würde. Allerdings sind die 
Preisunterscheide der Hardware so gering, dass der erhöhte Aufwand bei 
der Software sich erst bei recht großen Stückzahlen auszahlt.

von Nick (b620ys)


Lesenswert?

Nemopuk schrieb:
> digitalWrite + Serial.println (über USB/CDC): 22 kB
>
> digitalWrite + Serial.println (über USB/CDC) + analogRead: 27 kB

Achso, du wunderst dich, dass Programme größer werden, wenn du 
zusätzliche libraries verwendest?!
Was genau hat analogRead mit USB zu tun? Was Serial.println? Verwendet 
das println auch noch floats? Wunderst du dich dann auch, dass die ganze 
Fließkommaarithmetik mit dazu gelinkt wird? C-Compiler analysieren die 
formatierungsstrings nicht (Rust und OCaml tun das) und haben somit 
absolut Null Chancen den float-Krempel wegzulassen.

von Nemopuk (nemopuk)


Lesenswert?

Nick schrieb:
> Achso, du wunderst dich, dass Programme größer werden, wenn du
> zusätzliche libraries verwendest?!

Nein, ich staune über die Größe. Die USB Implementierung aus diesem 
Forum ist keine 5 kB groß, die HAL legt jedoch 10 kB drauf.

DigitalWrite und Serial.Println habe ich einzeln aufgelistet, damit man 
den Platzbedarf der Framework-Komponenten sehen kann. Damit keiner sagt: 
Dein USB Test ist nur so groß, weil er DigitalWrite und Serial 
beinhaltet.

> Was genau hat analogRead mit USB zu tun?

AnalogRead habe ich zum Schluss aus Neugier hinzugefügt - auch weil ich 
ein Gefühl dafür habe, wie viele Zeilen Code direkte Registerzugriffe 
für diesen Schritt brauchen würden. Nämlich ganz sicher keine 5 kB, 
nicht mal 1/10 davon.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Nemopuk schrieb:
> die HAL legt jedoch 10 kB drauf.

Das ist wohl eher das println. Scheinbar bist du dir nicht darüber 
bewusst was dahinter steckt. Ein putch wäre der einfachste 
Einstiegspunkt. println ist schon garnicht Teil der 
C-Standardbibliothek. Das öffnet schon Tür und Tor für irgendwelche 
Spinnereien.

Nemopuk schrieb:
> Um einen analogen Eingang zu lesen, brauche ich mit klassischen
> Registerzugriffen ganz sicher keine 5 kB

Ganz sicher nicht. Das analogRead bietet aber wohl (ich vermute) floats 
an. Und sonst noch irgend ein Gedöns das du in den header-Files 
rausfindest. Genau darauf zielte meine Frage nach den linker-options ab. 
Ordentliche Compiler/Linker werfen das nicht benötigte Zeug einfach 
wieder raus. Tw. kann man explizit floats ausschließen. Aber wenn man 
(der Hersteller) Spaghetti-code produziert und den dann noch 2 Tage 
eintrocknen lässst, dann kommt auch nur ein riesen Kneuel als ein Teil 
aus dem Topf raus. Das hat übrigens absolut nichts mit HAL zu tun. HAL 
bedeutet Hardware Abstraction Layer. Das ist eine dünne Schicht die 
Zugriffe auf die Hardware vereinfacht und vereinheitlicht. Der Compiler 
kann daraus fast immer direkte Registerzugriffe machen.
Wenn das bei dem Cube nicht geht, wäre das ein Argument für mich die 
Plattformwahl nochmal zu überdenken.

Aber ich glaub, ich rede da gegen eine Wand.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nick schrieb:
> Das ist eine dünne Schicht die Zugriffe auf die Hardware vereinfacht
> und vereinheitlicht

So dünn ist die nicht. Das mit den structs stimmt schon.

von Nemopuk (nemopuk)


Angehängte Dateien:

Lesenswert?

Nick schrieb:
>> die HAL legt (für USB) jedoch 10 kB drauf.
> Das ist wohl eher das println

Eben nicht! Schau dir meine Zahlen an:
1
digitalWrite + Serial.println (über UART): 12 kB
2
digitalWrite + Serial.println (über USB/CDC): 22 kB

Serial.println über USB ist 10 kB größer als Serial.println über UART. 
Ich beiden Fällen habe die jeweils andere Schnittstelle komplett raus 
gelassen.

> Ein putch wäre der einfachste Einstiegspunkt

Ich frage mich gerade, ob du mit dem Arduino Framework vertraut bist.

> println ist schon garnicht Teil der C-Standardbibliothek. Das
> öffnet schon Tür und Tor für irgendwelche Spinnereien.

Ach wirklich? Das ist ja gerade der Punkt! Das Framework ist erstaunlich 
groß. Es geht ums Framework, nicht um die C-Standardbibliothek.

>> Um einen analogen Eingang zu lesen, brauche ich mit klassischen
>> Registerzugriffen ganz sicher keine 5 kB
> Ganz sicher nicht.

Wolltest du damit meine Aussage bestätigen, oder widersprechen? Ist mir 
jetzt nicht klar.

Schau dir meine Zahlen an:
1
digitalWrite + Serial.println (über USB/CDC): 22 kB
2
digitalWrite + Serial.println (über USB/CDC) + analogRead: 27 kB

Nur durch Hinzufügen von einem simplen analogen Lesezugriff ist der Code 
erstaunliche 5 kB größer geworden. Für "eine dünne Schicht" ist das sehr 
viel Code.

> Das analogRead bietet aber wohl (ich vermute) floats an.

Nun ist klar dass du überhaupt keine Ahnung von Arduino hast.

> Genau darauf zielte meine Frage nach den linker-options ab.
> Ordentliche Compiler/Linker werfen das nicht benötigte Zeug einfach
> wieder raus.

Ja sicher, tut Arduino natürlich auch.

> (HAL) ist eine dünne Schicht die Zugriffe auf
> die Hardware vereinfacht und vereinheitlicht.
> Der Compiler kann daraus fast immer direkte Registerzugriffe machen.

Du kennst weder Arduino noch die HAL von ST, hast nicht mal in ihren 
Quellcode geschaut. Also erspare uns bitte solche dumm falschen 
Aussagen.

Tu mir einen Gefallen: Halte dich aus dieser Diskussion heraus.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Nemopuk schrieb:
> Nun ist es klar, du hast keine Ahnung von Arduino.

Stimmt. Will ich auch nicht. Dein Gesülze bestätig es mir nur wieder. 
Arduinoisten wissen nicht was sie tun, jammern aber gerne drüber.

Nemopuk schrieb:
> Du kennst die HAL von ST nicht, hast nicht mal in ihren Quellcode
> geschaut.

Nein, kenn ich nicht mehr (mehr). Vor über 10 Jahren hab ich mal einem 
Freund was damit aus Gefallen programmiert. Das hat mich überzeugt, dass 
der code von Armateuren geschrieben wurde. Aber der Begriff HAL ist mir 
durchaus geläufig. Zu der Zeit als der Begriff geprägt wurde gabs so ein 
Arduino-Betreutes-Denken noch nicht mal.
Übrigens ist Arduino ein Framework und hat rein garnichts mit ST zu tun. 
Aber selbst das zu erkennen bist du nicht fähig.

Nemopuk schrieb:
> Ich frage mich gerade, ob du mit dem Arduino Framework vertraut bist.

Ich weiß, dass du nicht den blassesten Schimmer von C hast. Ich weiß, 
dass dir der Begriff HAL nicht geläufig ist, denn jetzt verwendest du 
ihn synonym mit Framework. Gleichzeitig jammerst du aber, dass der code 
kompakter wird, wenn du auf die Arduino-Blase verzichtest. Da gehört 
schon einiges an Realitätsverweigerung dazu.

Du kannst natürlich gerne weiter in deiner Galaxie weiterarbeiten, 
solltest dich aber nicht darüber beklagen.

von Nemopuk (nemopuk)


Lesenswert?

Nachdem ich 30 Jahre lang auf Registerebene Programmiert habe, darf ich 
mir ja wohl mal die längst etablierten Frameworks anschauen, und über 
Punkte diskutieren, die mir dabei besonders auffallen. Daran ist nichts 
verwerfliches.

Und was kann ich dafür, daß ST sein Produkt "Cube HAL" nennt?

Eine vernünftige Diskussion ist hier mit dir unmöglich. Also nochmal: 
Halte dich bitte aus dieser Diskussion heraus.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nick schrieb:
> Aber der Begriff HAL ist mir durchaus geläufig.

Da versteht aber jeder was anderes drunter. Wenn ich einen Elefanten 
"Maus" nenne, ist es immer noch kein Nagetier, trotz langer Zähne.

Ein wichtiger Punkt bei einer HAL ist die Abstraktion, d.h. dass das API 
"nach oben" Hardware unabhängig ist. Genau diese Funktion erfüllen die 
HALs vom Linux-Kernel, Windows, Android. Aber nicht die STM32CubeHAL - 
da ist das API je nach Hardware unterschiedlich. Teilweise sogar bei 
identischer Hardware: Das was beim STM32F4 das "SDIO" ist, heißt beim 
STM32F7 "SDMMC". Die Hardware ist sehr ähnlich, die Register 
größtenteils kompatibel. Aber die APIs der HAL heißen einmal SDIO und 
einmal SDMMC. Man muss also im gesamten Code die HAL-Aufrufe ändern, um 
vom F4 auf den F7 umzusteigen, obwohl die Hardware nahezu gleich ist. 
Ist zwar hauptsächlich suchen & ersetzen, aber trotzdem blöde dass man 
nicht die selbe Codebase für beides nutzen kann.

Nicht alles wo "HAL" dran steht ist auch "HAL".

von Nemopuk (nemopuk)


Lesenswert?

Nick schrieb:
> Übrigens ist Arduino ein Framework

deswegen habe ich es bereits im Eröffnungsbeitrag so genannt.

>und hat rein garnichts mit ST zu tun.

Es geht hier um den STM32duino Core. Das ist die konkrete 
Implementierung von Arduino, auf Basis der Cube HAL. Beides kommt von 
ST. Das map File meines Arduino Sketches und die Ausgabe von nm haben 
bestätigt, dass überwiegend die HAL für den großen Code verantwortlich 
ist.

Außerdem schrieb ich bereits im Eröffnungsbeitrag, dass auch eine reine 
HAL Anwendung ebenso groß ist.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Niklas G. schrieb:
> Aber die APIs der HAL heißen einmal SDIO und
> einmal SDMMC.

Und das macht jetzt genau was besser? Dass ST nicht mal den Begriff HAL 
richtig verstanden hat? Sollte das nicht Plattformunabhängig sein? Also 
sowohl Arduino und HAL? Zumindest beim Begriff HAL sind wir uns ja wohl 
einig.

Nemopuk schrieb:
> Und was kann ich dafür, daß ST sein Produkt "Cube HAL" nennt?

Und was kann ich dafür?

Nemopuk schrieb:
> Nachdem ich 30 Jahre lang auf Registerebene Programmiert habe, darf ich
> mir ja wohl mal die längst etablierten Frameworks anschauen,

Kannst Du, klar. Um so verwunderlicher ist es aber, dass selbst 30 Jahre 
nicht geholfen haben zu verstehen woher der aufgeblasene code kommt.

Nemopuk schrieb:
> Halte dich bitte aus dieser Diskussion heraus.

Ja, genau du wirst mir das verbieten. Ich warte schon drauf! Versuch 
einfach meine Argumente zu verstehen und entspann dich. Versuch einfach 
zu verstehen was println letztendlich bedeutet und friss die Kröte die 
du dir selbst bestellt hast. Versuch rauszufinden was hinter analogRead 
steht und verwende es nicht mehr wenn es zu viel code generiert.

von Nemopuk (nemopuk)


Lesenswert?

Niklas G. schrieb:
> trotzdem blöde dass man nicht die selbe Codebase für beides nutzen kann.

Ja, finde ich auch schade. Wenn ich wie du imstande wäre, die USB 
Schnittstelle selbst zu programmieren, würde ich die HAL (und damit auch 
STM32duino) komplett ablehnen.

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Nick schrieb:
> Um so verwunderlicher ist es aber, dass selbst 30 Jahre
> nicht geholfen haben zu verstehen woher der aufgeblasene code kommt.

Erkläre du es mir! Was habe ich übersehen?

Aber schaue dir dieses mal die Dateien an und probiere es aus. Auf noch 
mehr falschen Blödsinn habe ich nämlich keine Lust.

Die Frage im Eröffnungsbeitrag war:
> Mir ist durchaus Klar, dass das Framework alleine aufgrund seiner
> Struktur einen gewissen Overhead mit sich bringt. Aber dass es so
> viel ist, überrascht mich dann doch.
> Enthält die USB/CDC Implementierung der HAL vielleicht irgend
> welche nützlichen Zwangs-Features, die über die minimale CDC
> Implementierung hinaus gehen?

: Bearbeitet durch User
von Hans-Georg L. (h-g-l)


Lesenswert?

Abstraktionen wie eine HAL haben Vor- aber auch Nachteile. Wenn mal 
etwas nicht funktioniert was nicht davon abgedeckt ist und man muss auf 
Register Ebene herunter, ist es sehr mühsam herauszufinden warum die HAL 
ein bestimmtes Bit nicht gesetzt hat. Ich hatte gerade kürzlich das 
Vergnügen mit den Sync Eingängen vom DMAMUX und DMA bei einem H7.

von Manuel H. (Firma: Universität Tartu) (xenos1984)


Lesenswert?

Ich habe mal einen Blick in den mit der HAL generierten Code geworfen. 
Als erstes ist mir der Interrupt-Handler aufgefallen:
1
08000590 g     F .text  00000976 HAL_PCD_IRQHandler

https://github.com/STMicroelectronics/stm32f3xx-hal-driver/blob/master/Src/stm32f3xx_hal_pcd.c#L859

https://github.com/STMicroelectronics/stm32f3xx-hal-driver/blob/master/Src/stm32f3xx_hal_pcd.c#L1538

Der schlägt schon mit 0x976 = 2422 bytes zu Buche. Die Funktion 
HAL_PCD_IRQHandler sieht zwar auf den ersten Blick kompakt aus, 
allerdings wird die Funktion PCD_EP_ISR_Handler inline eingebunden. So 
weit ich das auf den ersten Blick sehe, werden da mehr mögliche Fälle 
behandelt, als im HAL-freien Interrupt-Handler (und die im kleinen Code 
vermutlich gar nicht auftreten, weil sie zu Dingen gehören,die nicht 
benutzt werden).

Die "umfangreiche" Interrupt-Behandlung hatte 1984now ja auch schon 
erwähnt.

Dann sind mir noch folgende Funktionen zum Systemtakt aufgefallen:
1
08001608 g     F .text  00000138 HAL_RCC_ClockConfig
2
08001740 g     F .text  00000208 HAL_RCCEx_PeriphCLKConfig
3
08001124 g     F .text  0000049c HAL_RCC_OscConfig

https://github.com/STMicroelectronics/stm32f3xx-hal-driver/blob/master/Src/stm32f3xx_hal_rcc.c

Das sind zusammen 0x7dc = 2012 bytes. Wie ich schon vermutet habe, sind 
das generische Initialisierungsroutinen. Je nachdem, welche Parameter 
übergebe werden, initialisieren sie eine Taktquelle und konfigurieren 
diese, und daher ist natürlich Code für alle vorhandenen Quellen und 
Optionen vorhanden - auch wenn der Anwender davon in der Praxis nur eine 
benutzt. Das lässt sich durch direkten Registerzugriff, der die eine 
tatsächlich benötigte Konfiguration vornimmt, natürlich massiv 
verkleinern.

Ein ähnliches Bild bei USB Endpoint Funktionen:
1
08002444 g     F .text  0000046e USB_EPStartXfer

https://github.com/STMicroelectronics/stm32f3xx-hal-driver/blob/master/Src/stm32f3xx_ll_usb.c#L419

Immerhin 0x46e = 1134 bytes für USB_EPStartXfer - das lässt sich auch 
kompakter lösen, wenn man nur CDC haben möchte und keinen generischen 
Code...

So weit ich das bis hierhin sehe, sind im HAL keine Zusatzfunktionen, 
von denen der Anwendungscode irgendwie Gebrauch machen würde. Der größte 
Teil scheint einfach "toter" Code zu sein, der in der konkreten 
Anwendung nie ausgeführt wird, und einfach nur da ist, weil man den HAL 
ja auch für andere Dinge nutzen könnte, wenn man das denn wollte.

Wie schon von anderen hier erwähnt, liegt der Vorteil des HAL meiner 
Meinung nach nur darin, dass der Anwendungsprogrammierer hier ein 
generisches Interface bekommt und sich nicht um die individuellen 
Register kümmern muss, die sich je nach STM32-Familie doch merklich 
unterscheiden. Ich würde vermuten, dass sich der Code mit HAL leichter 
auf andere Familien portieren lässt als ohne HAL.

Zugegebenermaßen könnte man das sicher auf platzsparender erreichen. 
Anstatt z.B. die Taktkonfiguration durch eine Fallunterscheidung in 
einer generischen Funktion zur Laufzeit vorzunehmen, könnte man diese 
Fallunterscheidung auch schon beim kompilieren vornehmen, und dem 
Anwendungsprogrammierer ein dafür passendes Interface geben (z.B. 
separate Funktionen für HSE, HSI, LSE, LSI). Einen generischen 
Interrupt-Handler um ungenutzte Fälle zu verschlanken ist vermutlich 
etwas schwieriger umzusetzen.

von Nick (b620ys)


Lesenswert?

Nemopuk schrieb:
> Erkläre du es mir! Was habe ich übersehen?

Hab ich zwar schon mal, aber ich probier es nochmal anders:
Was ist das Equivalent von println in der C-Standard-Library?
Was hängt dann da noch mit dran?
Gäbe es eine noch einfachere Lösung in C die minimal Resourcen 
verbraucht?

von Nemopuk (nemopuk)


Lesenswert?

Manuel H. schrieb:
> o weit ich das bis hierhin sehe, sind im HAL keine Zusatzfunktionen,
> von denen der Anwendungscode irgendwie Gebrauch machen würde. Der größte
> Teil scheint einfach "toter" Code zu sein

Vielen Dank für deine Analyse.

von Nemopuk (nemopuk)


Angehängte Dateien:

Lesenswert?

Nick schrieb:
> Was ist das Equivalent von println in der C-Standard-Library?
> Was hängt dann da noch mit dran?
> Gäbe es eine noch einfachere Lösung in C die minimal Resourcen
> verbraucht?
1
void setup() {}
2
void loop() {}
ergibt 18 kB ohne lto und 15 kB mit lto

Wenn ich dann noch USB/CDC deaktiviere, sind es 4,2 kB ohne lto und 2,8 
kB mit lto.

Das angehängte Programm kommt auf 20 kB ohne lto und 17 kB mit lto.
Es wurde von Cube MX generiert, mit Cube HAL, ohne Arduino, ohne printf.

Falls du nochmal mit dem 5 kB Code aus dem Forum vergleichen willst: den 
findest du im Anhang des Eröffnungsbeitrages.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Nemopuk schrieb:
> void setup() {}
> void loop() {}
> ergibt 15 kB
>
> Wenn ich dann noch USB/CDC deaktiviere, sind es 2,8 kB.

Also unabhängig davon, ob du USB verwendest wird USB-code mit generiert 
und gelinkt.
Das ist gelinde gesagt eine wenig professionelle Umgebung.*) Aber wenn 
ST es schon nicht hinbekommt eine durchgängige Benamsung bei der HAL 
hinzubekommen, dann vermute ich, dass ST nur mal schnell irgendwas mit 
Duino hinpfuschen wollte für den Hobbybereich. Für mich wäre das dann 
klar das Signal die Finger von STCube zu lassen.
Wenn man sich aber bewusst drauf einlässt, dann kann man sich auch nicht 
darüber beklagen.

*) Wenn die Nicht-Verwendung von USB nicht mal der Compiler/Linker 
schnallt, vermute ich immer noch falsche Einstellungen im Projekt. Aber 
das hab ich ja schon mal gesagt.

von Nemopuk (nemopuk)


Lesenswert?

Nick schrieb:
> Also unabhängig davon, ob du USB verwendest wird USB-code mit generiert
> und gelinkt.

Ja logisch, das muss so sein. Das Ding soll sich schließlich als CDC 
Device beim PC zu erkennen geben, weil ich CDC Support aktiviert habe.

> vermute ich immer noch falsche Einstellungen im Projekt

Zeige mir, was ich einstellen soll. Gerne am Beispiel des leeren 
Sketches, der Einfachheit halber. Oder an dem gerade geposteten Programm 
für die Cube IDE, da hast du mehr Einstellmöglichkeiten.

> vermute ich, dass ST nur mal schnell irgendwas mit
> Duino hinpfuschen wollte für den Hobbybereich

Ich verstehe deinen Eindruck. Vor ein paar Jahren war ich auch mal so 
weit, aber inzwischen pflegen sie das STM32duino Projekt seit 8 Jahren 
und die HAL ist noch älter. Die meinen das wohl ernst.

Kennst du eine Alternative? Wie komme ich als Hobbybastler an eine 
andere/bessere USB Implementierung für die aktuellen Modelle (ich denke 
dabei an die STM32G Familie)?

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Nemopuk schrieb:
> Das Ding soll sich schließlich als CDC Device beim PC zu
> erkennen geben, weil ich CDC Support aktiviert habe.

Wenn das eine Initialisierung im code erfordern würde, dann könnte das 
der Linker rauswerfen. Mitdenken ist aber seitens ST wohl nicht 
erwünscht.

Nemopuk schrieb:
> Kennst du eine Alternative?

Nein, mit STM hab ich keine Erfahrung. Bei den PICs ist die HAL 
durchgängig, den Prozessor zu wechseln (nur innerhalb einer Familie 
tatsächlich gemacht) erfordert keine Code-Änderung. Gleiches für den 
Framework.
Allerdings erfordert auf den PIC32 USB FreeRTOS. Und darauf will ich 
mich nur unter Zwang einlassen. Da mach ich lieber Ethernet oder nimm 
einen FTDI. Der FTDI wäre ja auch eine Option für dich, wenn du deine 
4-lagige Platine machst.

von Nemopuk (nemopuk)


Lesenswert?

Nick, ich bin enttäuscht.

Du hast mich beleidigt und wie einen Dummkopf da stehen lassen. Du hast 
mehrfach von falschen Projekteinstellungen geschrieben, konntest dabei 
aber nicht helfen. Du hast Arduino und Cube HAL scharf kritisiert, 
konntest aber keine Alternative nennen.

Zu deiner Erleichterung muss ich sagen, dass bisher niemand helfen 
konnte. Allerdings wurden meine Erkenntnisse bestätigt.

Aus meiner Sicht sieht das so aus, dass ich alle Möglichkeiten bereits 
vor diesem Thread ausgeschöpft hatte. So viel dazu, dass ich keinen 
blassen Schimmer habe.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nick schrieb:
> Und das macht jetzt genau was besser?

Nichts, aber es zeigt dass die CubeHAL eben nicht deiner Vorstellung 
einer HAL entspricht, auch nicht dahingehend dass sie nicht "dünn" ist. 
Im Übrigen ist die HAL von Windows, Linux, Android alles andere als 
dünn; gerade bei Android ist sie eigentlich das Hauptproblem für die 
Fragmentierung zwischen den unterschiedlichen Herstellern und der daraus 
folgende Mangel an Updates für ältere Geräte.

Nemopuk schrieb:
> Ja, finde ich auch schade. Wenn ich wie du imstande wäre, die USB
> Schnittstelle selbst zu programmieren

So schwierig ist es nicht...

https://www.mikrocontroller.net/articles/USB-Tutorial_mit_STM32#Virtueller_COM-Port

Müsste so in der Art auch für den STM32F3 funktionieren.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Nemopuk schrieb:
> Nick, ich bin enttäuscht.

Das kommt vor im echten Leben.

Nemopuk schrieb:
> Du hast mich beleidigt und wie einen Dummkopf da stehen lassen.

Beleidigt? Kannst du bestimmt belegen. Und dann die Sache mit dem Schuh.

Nemopuk schrieb:
> Du hast Arduino und Cube HAL scharf kritisiert,
> konntest aber keine Alternative nennen.

Hast Du danach gefragt? Ich könnte dir eine nennen, aber die würde dir 
nicht gefallen. Daher lass ich das lieber sein, ich will dich nicht zu 
einer anderen Sekte bekehren und ich bin kein Missionar. Du willst 
Arduino, dann nimm es, aber beklag dich nicht.

Nemopuk schrieb:
> Aus meiner Sicht sieht das so aus, dass ich alle Möglichkeiten bereits
> vor diesem Thread ausgeschöpft hatte.

Schön! Dann hast du also verstanden, dass die CubeHALDingsbums nicht 
Deinen Anforderungen entspricht. Das ist doch schon mal was.

von Nemopuk (nemopuk)


Lesenswert?

Niklas G. schrieb:
> Müsste so in der Art auch für den STM32F3 funktionieren.

So ist es.

Aber die STM32G haben schon wieder andere USB Peripherie.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nemopuk schrieb:
> Aber die STM32G haben schon wieder andere USB Peripherie.

Also auf den ersten Blick sieht es ziemlich ähnlich aus. Die haben auch 
die EPnR-Register. Vermutlich muss man nur ein paar Details anpassen, 
z.B. das jetzt verfügbare Handling des Pull-Up Widerstands auf D+ (enorm 
praktisch).

: Bearbeitet durch User
von Manuel H. (Firma: Universität Tartu) (xenos1984)


Lesenswert?

Nemopuk schrieb:
> Kennst du eine Alternative? Wie komme ich als Hobbybastler an eine
> andere/bessere USB Implementierung für die aktuellen Modelle (ich denke
> dabei an die STM32G Familie)?

Es gibt da auch noch LibOpenCM3:

https://github.com/libopencm3/libopencm3

Auf den ersten Blick sieht es schlanker aus als Cube HAL, wobei es 
vermutlich auch weniger Funktionalität bietet. STM32G0 und STM32G4 
werden unterstützt. Immerhin gibt es ein USB/CDC Beispiel, hier für 
STM32F3:

https://github.com/libopencm3/libopencm3-examples/tree/master/examples/stm32/f3/stm32f3-discovery/usb_cdcacm

Allerdings muss ich dazu sagen, dass ich weder Cube HAL, noch LibOpenCM3 
bisher für eigene Projekte benutzt habe, und auch kein USB in meinen 
Projekten benutzt. Von daher kann ich nicht sicher sagen, ob mein erster 
Eindruck zutreffend ist.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Manuel H. schrieb:

> Wie ich schon vermutet habe, sind
> das generische Initialisierungsroutinen. Je nachdem, welche Parameter
> übergebe werden, initialisieren sie eine Taktquelle und konfigurieren
> diese, und daher ist natürlich Code für alle vorhandenen Quellen und
> Optionen vorhanden - auch wenn der Anwender davon in der Praxis nur eine
> benutzt.

Diesen Teil kann man allerdings (mal abgesehen vom Platzbedarf der 
Strukturen) durch Verwendung der Optimierung (insbesondere LTO) noch 
einigermaßen in den Griff bekommen.

Das klappt aber nicht für die ISRs! Hier ist die Intelligenz von 
Compilern einfach mal nicht ausreichend. Um hier besser zu werden, 
müßten sie verstehen, wie die Hardware funktioniert. Also z.B. wissen, 
dass sich dieses und jenes Flagbit bei der gegebenen Initialierung der 
Hardware mit absoluter Sicherheit nicht ändern wird, also alle 
Verzweigungen im ISR-Code, die nur existieren, um den Fall zu behandeln, 
dass es sich ändert, in der konkreten Anwendung einfach mal überflüsig 
sind.

Das können sie nicht und werden sie wahrscheinlich auch nie "lernen" 
(also beigebracht bekommen) können.

Oder anders ausgedrückt: Hier läßt sich durch manuelle Implementierungen 
am meisten sparen, sowohl Speicherplatz als insbesondere auch Laufzeit.

Aber immerhin: Die HAL enthält zum Glück die Möglichkeit, hier ohne 
große Klimmzüge reinzugrätschen. Man kann als weite Teile des 
Standard-Handling problemlos "abklemmen" (und effektiv wirklich aus dem 
Code entfernen). Aber ist dann natürlich selber dafür verantwortlich, 
einen bezüglich der Anwendung vollständigen und fehlerfreien Ersatz 
bereitzustellen.

Und das Allerbeste ist: man kann aus diesem eigenen Teil dann auch 
wieder den Standard-Callback der HAL aufrufen. Aus Anwendungssicht muss 
sich also dadurch nicht mal zwingend etwas ändern.

Um das alles allerdings tun zu können, muss man die HAL schon ziemlich 
gut verstanden haben, insbesondere deren Schicht-Struktur. Die ist 
leider nirgendwo wirklich gut erklärt. Man muss sich in den HAL-Code 
einlesen, um das Konzept zu verstehen. Bei einfachen Sachen wie etwa 
UART, I2C oder SPI ist das für einen erfahrenen Entwickler noch mit 
recht überschaubarem Aufwand möglich, aber bei USB wird's schon ziemlich 
heftig, da verliert man schnell mal die Orientierung...

von Nemopuk (nemopuk)


Lesenswert?

Ob S. schrieb:
> Bei einfachen Sachen wie etwa
> UART, I2C oder SPI ist das für einen erfahrenen Entwickler noch mit
> recht überschaubarem Aufwand möglich, aber bei USB wird's schon ziemlich
> heftig, da verliert man schnell mal die Orientierung...

Zu blöd, dass USB gerade der Teil ist, weswegen ich mir die HAL und 
Arduino anschaue. Alle anderen Schnittstellen kann ich "zu Fuß" 
programmieren.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Nemopuk schrieb:

> Zu blöd, dass USB gerade der Teil ist, weswegen ich mir die HAL und
> Arduino anschaue. Alle anderen Schnittstellen kann ich "zu Fuß"
> programmieren.

OK. Dann als erstes mal ganz beherzt den Arduino-Kram weglassen. Das ist 
nun wirklich eine völlig unnötige Abstraktionsschicht on top, die nicht 
nur unnötigen Overhead einführt, sonder obendrein alles weitere 
bezüglich einer Optimierung nur unnötig verkompliziert.

von Nemopuk (nemopuk)


Lesenswert?

Ob S. schrieb:
> OK. Dann als erstes mal ganz beherzt den Arduino-Kram weglassen.

Wie ich bereits im Eröffnungsbeitrag schrieb, belegt die Hello-World 
Anwendung ohne Arduino ebenfalls schon ca. 20 kB.

Ich habe sie gestern Abend als Anhang nach gereicht.
Beitrag "Re: Warum ist die USB/CDC Implementierung der Cube HAL so groẞ?"

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Nemopuk schrieb:
> Ob S. schrieb:
>> OK. Dann als erstes mal ganz beherzt den Arduino-Kram weglassen.
>
> Das bringt doch nichts!

Doch, natürlich bringt das was. Du musst nämlich "bloß" nach die HAL 
verstehen, um die gegebenen Hinweise zur Optimierung umsetzen zu können.

Glaub' mir, das ist viel einfacher, als es umzusetzen, wenn da noch ein 
drübergestülptes Arduino rumwerkelt...

von Nemopuk (nemopuk)


Lesenswert?

Ob S. schrieb:
> Doch, natürlich bringt das was. Du musst nämlich "bloß" nach die HAL
> verstehen, um die gegebenen Hinweise zur Optimierung umsetzen zu können.

Zeige mir, wie du das konkret meinst. Optimiere das angehängte Programm. 
Wenn du auf 10 kB kommst bin ich zufrieden.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Nemopuk schrieb:
> Ob S. schrieb:
>> Doch, natürlich bringt das was. Du musst nämlich "bloß" nach die HAL
>> verstehen, um die gegebenen Hinweise zur Optimierung umsetzen zu können.
>
> Zeige mir, wie du das konkret meinst. Optimiere das angehängte Programm.
> Wenn du auf 10 kB kommst bin ich zufrieden.

Zahlst du mir dann auch deinen Lohn für die Zeit aus, die ich dafür 
brauche?

von Nemopuk (nemopuk)


Lesenswert?

Ob S. schrieb:
> Zahlst du mir dann auch deinen Lohn für die Zeit aus, die ich dafür
> brauche?

Du bist jetzt schon der zweite, der behauptet, ich müsse nur die 
Optimierungen richtig einstellen, ohne konkret zu werden.

Heiße Luft bringt mich nicht weiter.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Nemopuk schrieb:

> Du bist jetzt schon der zweite, der behauptet, ich müsse nur die
> Optimierungen richtig einstellen, ohne konkret zu werden.

Nein, das habe ich keinesfalls behauptet, sondern klar abgegrenzt, dass 
das nur bezüglich der Initialiserung etwas bringen kann, nicht aber 
bezüglich all dem Scheiß, der als Folge von Interrupts passiert, sondern 
dass da Handarbeit zur Optimierung nötig wird.

Du kannst also offensichtlich nicht mal deutschen Text lesen. Schlechte 
Voraussetzungen...

Vielleicht ist dir aber auch nur nicht klar, dass bei USB ein sehr 
großer Teil der Funktionalität in den Handlern von ISRs steckt (stecken 
muss).

von Nemopuk (nemopuk)


Lesenswert?

Ob S. schrieb:
> Vielleicht ist dir aber auch nur nicht klar, dass bei USB ein sehr
> großer Teil der Funktionalität in den Handlern von ISRs steckt (stecken
> muss).

Das ist mir durchaus klar. Der kleinere Code, denn ich ganz oben im 
Eröffnungsbeitrag angehängt hatte, zu dem ich schrieb, dass ich ihn 
Zeile für Zeile analysiert und weitgehend verstanden habe, besteht zu 
90% aus einer einzigen ISR.

Umso mehr erstaunt mich, dass du es für möglich hältst, den 20 KB Code 
mit HAL signifikant zu verkleinern. Schade, dass du diesbezüglich nicht 
konkreter werden möchtest.

von Manuel H. (Firma: Universität Tartu) (xenos1984)


Lesenswert?

Ich habe mich spaßeshalber noch mal etwas in STM32 Frameworks 
eingelesen:

http://jeelabs.org/202x/compare/

Da schneidet LibOpenCM3 recht gut ab. Wäre vielleicht einen Versuch 
wert.

von Nick (b620ys)


Lesenswert?

Wirf den Cube in die Tonne und schluck das als Lehrgeld.
Evtl. kommst Du mit Keil MDK 
(https://developer.arm.com/Tools%20and%20Software/Keil%20MDK) weiter. 
K.A. was das kostet. Von Keil gibts glaub ich eine freie (und 
eingeschränkte) Version. Das musst du aber selber rausfinden.
Sicherlich gibts auch eine komplett freie Toolchain. Der gcc sollte ja 
wohl arm können.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Nemopuk schrieb:

> Umso mehr erstaunt mich, dass du es für möglich hältst, den 20 KB Code
> mit HAL signifikant zu verkleinern. Schade, dass du diesbezüglich nicht
> konkreter werden möchtest.

Naja, wollen wir dich nicht mal ganz doof sterben lassen. Der Trick ist: 
Funktionalität aus ISRs entfernen.

Sprich: Das Konzept umsetzen, was auch richtige OS verwenden. Auch die 
sind nämlich mit der dramatischen Unfähigkeit der Compiler geschlagen. 
Die Lösung ist typisch: Es gibt noch eine zusätzliche Schicht zwischen 
Applikation und ISRs. Und zusätzlich: die eigentliche Applikation läuft 
nicht wirklich auf main()-Level, sondern nur dann, wenn das, was nunmehr 
auf main()-Level läuft, also diese zusätzliche Zwischenschicht, mal Zeit 
läßt für Anwendungscode.

Reichere das noch mit entsprechenden Gimmicks an, und du bist du bei 
einem typischen RTOS. Man muss aber nicht notwendigerweise so weit 
gehen. Ein "angedeutetes RTOS-Konzept" reicht halt in vielen Fällen 
auch.

Und falls du dich fragst, warum das nun bezüglich der Größe des Codes 
effizienter ist: weil der recht doofe Compiler so seine Fähigkeiten zur 
Optimierung wesentliche besser ausspielen kann. In main() beherrscht er 
das nämlich ziemlich gut...

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nick schrieb:
> Wirf den Cube in die Tonne und schluck das als Lehrgeld.
> Evtl. kommst Du mit Keil MDK

Und der macht die CubeHAL kleiner?

Nick schrieb:
> Sicherlich gibts auch eine komplett freie Toolchain. Der gcc sollte ja
> wohl arm können.

Also der GCC kann die CubeHAL kleiner kompilieren als der GCC der bei 
Arduino oder STM32CubeIDE mitgeliefert ist?

von Nemopuk (nemopuk)


Lesenswert?

Ob S. schrieb:
> Der Trick ist: Funktionalität aus ISRs entfernen.

Ich will die HAL benutzen, nicht editieren. Andernfalls geht der Sinn 
des Frameworks verloren.

von Nemopuk (nemopuk)


Lesenswert?

Manuel H. schrieb:
> Es gibt da auch noch LibOpenCM3

Manuel H. schrieb:
> Da schneidet LibOpenCM3 recht gut ab.

Das Projekt scheint vor vielen Jahren gestorben zu sein. Das es die 
neuen STM32 Modelle nicht (bzw. nur unvollständig) unterstützt, ist es 
für mich uninteressant.

: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

Niklas G. schrieb:
> Also der GCC kann die CubeHAL kleiner kompilieren als der GCC der bei
> Arduino oder STM32CubeIDE mitgeliefert ist?

Quatsch. Hör endlich auf dir so wirres Zeug zusammen zu fantasieren.

Ich habs schon mal gesagt:
Was das CubeHAL macht ist einfach schlecht angelegt. Die sollten sich 
mal den Unterschied von modularer und monolithischer Programmierung 
ansehen. Und dann ihr Zeug entsprechend zerfleddern und neu 
strukturieren.
Dass das aber bei dir jemals ankommt bezweifle ich inzwischen massiv.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nick schrieb:
> Quatsch. Hör endlich auf dir so wirres Zeug zusammen zu fantasieren.

Haben wir heute unseren lustigen Tag?

von Nemopuk (nemopuk)


Lesenswert?

By the way, der Code von Keil braucht laut deren Doku ebenfalls mehr als 
10 kB plus RTOS.

von Nick (b620ys)


Lesenswert?

Niklas G. schrieb:
> Haben wir heute unseren lustigen Tag?

Ist das dein starrköpfiger thread?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nick schrieb:
> Niklas G. schrieb:
>> Haben wir heute unseren lustigen Tag?
>
> Ist das dein starrköpfiger thread?

Es ist nicht mein Thread.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Nemopuk schrieb:

> Ich will die HAL benutzen, nicht editieren.

Dann wirst du wohl mit der Codegröße leben müssen.

Wie beim Auto. Wenn ich einen Ferrari F350 fahren will, muss ich halt 
auch damit leben können, das 'ne blöde Inspektion ein paar Tausender 
kostet und die Reparatur einer auf dem Parklatz eingedellten Front mal 
eben mit 35000€ zu Buche schlägt.

Nur der Tod ist umsonst.

von Rick (rick)


Lesenswert?

Ob S. schrieb:
> Nur der Tod ist umsonst.
Nein.

.
.
.

Der kostet Dich das Leben...


Noch was zum Thema: Wenn man unbedingt will, kann man USB sicher auch 
ohne HAL verwenden. Dadurch das der USB-Core eingekaufte IP ist, ist die 
Philosophie, die dahinter steckt eine andere als bei der restlichen 
Peripherie von ST. Ich habe für meine Testimplementierung damals dann 
doch die HAL genommen und war relativ schnell fertig mit meiner 
Applikation.

Aber dem TO scheint es wichtiger sein zu lamentieren statt zu 
implementieren.

: Bearbeitet durch User
von Rahul D. (rahul)


Lesenswert?

Nick schrieb:
> K.A. was das kostet.
Für Privatanwender / Hobbyisten? Zu viel. (irgendwas im oberen 
kEuro-Bereich...)

> Von Keil gibts glaub ich eine freie (und
> eingeschränkte) Version.
Zum Glauben geht man in die Kirche.
Es gibt eine Version, die auf eine maximale Codegröße beschränkt ist.
Die unterstützt aber nicht alle Funktionalitäten der Vollversion.
Ein USB-Device kann man damit AFAIR programmieren - einen USB-Host 
nicht.
Ich arbeite dienstlich mit der Vollversion, daher weiß ich nicht genau, 
ob USB von der beschränkten Version überhaupt unterstützt wird.
Ist aber sinnfrei, wenn man Privatanwender ist, und die CubeIDE 
verwendet.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Nur mal so als uninteressante Zusatzinfo: Bei der libopencm3 gibt's in 
der Nachbarschaft auch uninteressante libopencm3-examples. Dort u.a. 
unter:
libopencm3-examples/examples/stm32/f4/stm32f429i-discovery/usb_cdcacm
ein uninteressante Simpelbeispiel, was wohl nur so eine Art 1:1 RX-TX 
Verbindung per USB macht:
1
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
2
{
3
    (void)ep;
4
5
    char buf[64];
6
    int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
7
8
    if (len) {
9
        while (usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0);
10
    }
11
}

Da wird (wohl aus Gruenden der Einfachheit des Beispiels) nichts mit 
Interrupts gemacht, sondern mit polling.
Das .bin file ist 6760 bytes gross.

Gruss
WK

von Nick (b620ys)


Lesenswert?

Niklas G. schrieb:
>> Ist das dein starrköpfiger thread?
>
> Es ist nicht mein Thread.

Da hätte ich besser nach dem Autor sehen müssen. Nein, nicht Dein 
Thread.
Gesagtes gilt aber nach wie vor für den TO.

von Ein T. (ein_typ)


Lesenswert?

Vanye R. schrieb:
> Die allgemeine Antwort ist, die Welt besteht heute aus unfaehigen und
> faulen Programmierern die

... jeden Scheiß selbst von Hand machen, weil sie sich für die 
genialsten Entwickler unter G~ttes schöner Sonne und alle anderen für 
unfähige und faule Vollidioten halten.

Als Kollegen sind solche Leute eine absolute Pest. Jeder Quatsch wird 
extra manuell implementiert, jedes Mal neu und nach ganz eigenen 
"Standards", und das Ergebnis ist ein Kartenhaus aus Not-Invented-Here, 
das augenblicklich in sich zusammenfällt und exorbitante Aufwände 
erforderlich macht, sobald sich die Anforderungen nur minimal ändern. 
Zudem sind solche Leute extrem langsam und ziehen die Produktivität 
ihres ganzen Teams in den Keller, was sie dann zwar mit ihrer besonderen 
Sorgfalt zu rechtfertigen versuchen, aber...

> Achte darauf das du nicht selbst zu so einem Loser wirst. .-)

Achte vor allem sehr genau darauf, Dich von solchen Losern fernzuhalten.

von Georg M. (g_m)


Lesenswert?

> Warum ist die USB/CDC Implementierung der Cube HAL so groẞ?

Warum?

von Rahul D. (rahul)


Lesenswert?

Georg M. schrieb:
>> Warum ist die USB/CDC Implementierung der Cube HAL so groẞ?
>
> Warum?

Um Multinominatus zu ärgern.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Ein T. schrieb:
> Jeder Quatsch wird extra manuell implementiert, jedes Mal neu und nach
> ganz eigenen "Standards",

Was wenn man Dinge nach etablierten Standards neu implementiert, aber 
nach neumodischen Standards - z.B. OOP aus den 80ern statt 
strukturierter Programmierung aus den 60ern?

von Nemopuk (nemopuk)


Lesenswert?

Ob S. schrieb:
>> Ich will die HAL benutzen, nicht editieren.
> Dann wirst du wohl mit der Codegröße leben müssen.

Sieht so aus.

Rick schrieb:
> Noch was zum Thema: Wenn man unbedingt will, kann man USB sicher auch
> ohne HAL verwenden.

Noch habe ich reichlich STM32F303 Board vorrätig, von denen ich zehre. 
Sollte ich irgendwann auf neue Modelle (z.B. STM32G4) wechseln müssen, 
steht mir ja immer noch die von Niklas empfohlene Möglichkeit offen, den 
Code aus dem Eröffnungsbeitrag zu portieren.

> Aber dem TO scheint es wichtiger sein zu lamentieren statt
> zu implementieren.

Ich wollte eigentlich nur die Frage aus dem Eröffnungsbeitrag klären:

Nemopuk schrieb:
> Enthält die USB/CDC Implementierung der HAL vielleicht irgend
> welche nützlichen Zwangs-Features, die über die minimale CDC
> Implementierung hinaus gehen?

Lamentiert haben andere, die auf den Optimierungseinstellungen herum 
geritten habe, obwohl ich ausdrücklich darum bat, das nicht zu tun:

Nemopuk schrieb:
> Aber bitte hängt euch nicht an kleinen Unterschieden in den Compiler
> Optionen und loop() bzw. main() auf. Mir geht es nicht um 1 kB mehr
> oder weniger

Solange noch nicht alles von jedem gesagt wurde, geht es hier 
wahrscheinlich noch lange weiter.

von Ein T. (ein_typ)


Lesenswert?

Niklas G. schrieb:
> Was wenn man Dinge nach etablierten Standards neu implementiert, aber
> nach neumodischen Standards - z.B. OOP aus den 80ern statt
> strukturierter Programmierung aus den 60ern?

Darum ging es nicht, aber das weißt Du ja selbst. Wenn Du das 
diskutieren möchtest, dann mach dazu bitte einen eigenen Thread auf.

von Frank L. (florenzen)


Lesenswert?

Nemopuk schrieb:
[...]
> Noch habe ich reichlich STM32F303 Board vorrätig, von denen ich zehre.
> Sollte ich irgendwann auf neue Modelle (z.B. STM32G4) wechseln müssen,
> steht mir ja immer noch die von Niklas empfohlene Möglichkeit offen, den
> Code aus dem Eröffnungsbeitrag zu portieren.
[...]

Du könntest dir mal http://www.tinyusb.org ansehen. Das ist mit 
Sicherheit nicht so kompakt wie das Beispiel aus dem 
Eröffnungsbeitrag, aber schmaler als der HAL-USB-Code.

Gruß,
f

von Nemopuk (nemopuk)


Lesenswert?

Frank L. schrieb:
> Du könntest dir mal http://www.tinyusb.org ansehen.

Dankeschön. Sieht sehr umfangreich aus!

von Nemopuk (nemopuk)


Lesenswert?

Ich habe mir gerade zwei STM32G431CBT6 Boards für sagenhafte 9 Euro 
(incl. Versand) bestellt. Im nächsten Urlaub werde ich versuchen, den 
USB Code aus dem Eröffnungsbeitrag darauf zu portieren.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nemopuk schrieb:
> Sollte ich irgendwann auf neue Modelle (z.B. STM32G4) wechseln müssen,
> steht mir ja immer noch die von Niklas empfohlene Möglichkeit offen, den
> Code aus dem Eröffnungsbeitrag zu portieren.

Also mein USB-Treiber sollte sich sowohl auf den F3 als auch auf den G4 
portieren lassen, die haben nahezu identische Hardware wie der F1, für 
den ich den Treiber ursprünglich geschrieben hatte.

von Klaus M. (klaus_me)


Lesenswert?

Das ist doch W.S. Implementierung von USB/CDC. Gab's da von ihm mal eine 
Lizenzaussage? Wie groß ist denn der Unterschied zwischen der 103 
Version von deiner Seite 
https://stefanfrings.de/stm32/stm32f1.html#vcpnohal und der 303 in 
diesem Thread?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Klaus M. schrieb:
> Das ist doch W.S. Implementierung von USB/CDC

Meinst du mich? Ahem, ich habe meine eigene CDC Implementierung, und 
ich habe eine Meinung zur Codequalität von W.S. ...

Meine Library ist diese:
http://github.com/Erlkoenig90/f1usb
https://www.mikrocontroller.net/articles/USB-Tutorial_mit_STM32

Klaus M. schrieb:
> Gab's da von ihm mal eine Lizenzaussage?

Ja:

Beitrag "Re: USB CDC von Stefan Frings und WS"

Hier die von mir fehlerbereinigte Version der W.S. Library:

https://github.com/Erlkoenig90/WSusb

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Klaus M. schrieb:
> Gab's da von ihm mal eine Lizenzaussage?

Ja: Es gibt keine Lizenz, frei für alle.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nemopuk schrieb:
> Ja: Es gibt keine Lizenz, frei für alle.

Wenn es keine Lizenz gibt, ist der Code eben nicht frei - dann darf 
man ihn lesen, mehr nicht. Alles was nicht explizit erlaubt ist, ist 
verboten. Daher ist das Angeben von Lizenzen bei OpenSource-Projekten ja 
so wichtig, weil der Code sonst nicht verwendbar ist. Aber W.S. hat sich 
nach vielem Murren ja überreden lassen, eine Lizenz in seiner besonderen 
Ausdrucksweise anzugeben.

von Nemopuk (nemopuk)


Lesenswert?

Klaus M. schrieb:
> Wie groß ist denn der Unterschied zwischen der 103 Version von deiner
> Seite https://stefanfrings.de/stm32/stm32f1.html#vcpnohal und der 303 in
> diesem Thread?

Die kommen beide von dieser Webseite und unterscheiden sich lediglich in 
Konfigurationsparametern in der usb.c, sowie uC spezifische 
Konfiguration der Taktquellen und I/O Pins in main c.

von Ein T. (ein_typ)


Lesenswert?

Niklas G. schrieb:
> Wenn es keine Lizenz gibt, ist der Code eben nicht frei - dann darf
> man ihn lesen, mehr nicht. Alles was nicht explizit erlaubt ist, ist
> verboten. Daher ist das Angeben von Lizenzen bei OpenSource-Projekten ja
> so wichtig, weil der Code sonst nicht verwendbar ist.

Absolut richtig. Das ist ja gerade der Trick der GPL: man darf den Code 
nur dann benutzen, wenn man sich an seine Lizenzbedingungen hält.

Es ist aus meiner Sicht extrem erschreckend, daß sich sogar viele 
erfahrene Entwickler nicht mit Lizenz- und Nutzungsrechten auskennen.

von Nemopuk (nemopuk)


Lesenswert?

Kurze Rückmeldung:

Ich konnte die oben genannte kompakte USB Implementierung von W.S. auf 
meinem STM32G431 Board ans Laufen bringen. Wie bereits vermutet wurde, 
hat der G4 im Prinzip die selbe Peripherie. Nur die Konfiguration der 
I/O Pins und des Taktes ist (wie üblich) im Detail etwas anders.

Ich habe es dort zum Download bereit gestellt.
https://stefanfrings.de/stm32/stm32g4.html#vcpnohal

: Bearbeitet durch User
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.