mikrocontroller.net

Forum: Compiler & IDEs STM32: von HAL nach LL umsteigen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Ralf (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Hallo,

ich möchte einen STM32L011 (8kB Flash / 2kB SRAM) programmieren. Der 
Einfachheit halber verwende ich Atollic TrueStudio und CubeMX.

Wenn die HAL verwendet wird, bleibt ja nicht mehr wirklich Platz für die 
eigentliche Applikation übrig - aktuell sind nur mit Initialisierung von 
GPIOs, Timer 2 und USART2 schon 5-6kB für den Release-Build weg. Der 
Debug-Build sprengt die 8kB, wenn man nicht weitere Einstellungen 
vornimmt.

Versuchsweise habe ich auch MDK5 von Keil installiert, dafür gibt's ja 
eine kostenfreie Version für STM32x0yy Devices - nur unterstützt die 
wohl keine LinkTimeOptimization, von der ich mir erhofft hatte, dass 
dann weniger Speicher verbraten wird. Da liegt der Verbrauch dann bei 
~7kB.

Aktiviere ich im TrueStudio die LTO, dann passt es mit hängen und würgen 
rein, aber dann kann ich nicht mehr richtig debuggen (trotz 
Optimierungslevel -Og).

Dass die HAL eher was für die dickeren und schnelleren Boliden ist, ist 
mir klar - also bleibt wohl nur der Umstieg auf die LowLevel-Treiber.

Hat jemand einen Tip, wie ich da am besten vorgehen könnte? Vom Ansatz 
her hätt ich mir jetzt jeweils eine Peripherie aus HAL-Sicht angeschaut, 
und dann versucht das, was ich brauche per LL nachzubilden.

Gibt es sonst noch was, was ich bei LL beachten sollte? Also 
beispielsweise, was macht die HAL automatisch, was die LL nicht macht? 
=> Die Aktivierung des SysTick-Timers scheint so ein Kandidat zu sein...

Grüße

Autor: Sebastian E. (sbe_15)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
IIRC kann CubeMX mittlerweile Init-Code mit LL-Treibern generieren.
Dazu helfen die Examples (z.T. auch von anderen Modellen, wenn für 
deinen L011 keins vorhanden ist. Ging mir mit meinem F091 so, da halfen 
dann idR die F072 Examples). Ansonten schadet auch ein Blick in die 
HAL-Sourcen nicht.

Autor: Bimbo. (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Download mal das Reference Manual.

Schaue dir zuerst die GPIOs an - nur die Registerbeschreibung. Die sind 
äußerst simpel, wie bei vielen anderen Mikrocontrollern auch. Ein 
Register pro Port für Lesen, Schreiben, Modus (analog, Input, Output, 
Alternate Funktion), eines für die Pullups etc.
Am besten schreibst du dir ein Makro, habe ich auch gemacht, das sieht 
dann so aus:
#define PINCONFIG(P_PORT, P_PIN, P_MODE, P_TYPE, P_PULLUP, P_AFUNC) [...]

Dann schau dir das RCC Register an. Dort kannst du die Clocks einstellen 
- ist viel einfacher als befürchtet. Ein Bit setzen - HSE ist aktiviert. 
Dann warten bis ein weiteres Bit gesetzt - dann ist die HSE bereit. Dann 
die PLL konfigurieren und aktivieren. So durchschlängeln. Das sind ca. 
10 Zeilen bei mir im Schntt, um die Clock tree zu konfigurieren.

Generell gilt: nach einem Reset sind die meisten Funktionen deaktiviert. 
Das heißt, wenn du z.B. bei einem Timer mit dem ARR Register sagst, bis 
welchen Wert gezählt werden soll, im RCC den Clock für den Timer 
aktivierst (zu jeder Peripherie muss der Clock durchreicht werden - ein 
Bit setzen) und den Timer aktivierst, hast einen ganz simplen Timer, der 
bis zu einem bestmmten Wert zählt. Das wars. Wenn du mehr brauchst 
kannst du es aktivieren, ansonsten belasse es dabei. Einfach mal die 
Register durchgehen und schauen, was man alles schalten und walten kann.

Nimm am Anfang natürlich die Startup.s von Atollic, genauso das 
Linkerscript.

Wenn du RCC, GPIO, Timer und NVIC durchgegangen bist, hast du das 
Grundgerüst geschafft. Achtung, der NVIC tseht im Programming manual 
beschrieben - warum auch immer.

Letztendlich finde ich, dass die Registerebene nicht anders ist, als bei 
z.B. einem Atmega. Nur - wenn man möchte - mit komplexeren 
Einstellmöglichkeiten und alles halt in 32bit.

Autor: CubeMX Hater (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Bir vor wenigen Wochen wusste ich es nicht bis ich
hier darauf hingewiesen wurde dass CubeMX auch LL Code
generieren kann.

Ob das schon auch bis zu dir durchgedrungen ist?
Vielleicht geht da was mit einsparen ...

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo sbe_15, Bimbo und CubeMX Hater,

danke für eure Antworten.

@sbe_15:
die Beispiele werd ich mal durchwühlen, das mit dem 072 ist ein guter 
Tipp.

@Bimbo:
Das nimmt mir doch schon mal ein wenig die Sorgen :) Im Prinzip ist es 
doch eigentlich "zu Fuß die Bits konfigurieren", oder? Ich muß mir noch 
klar werden, was mir davon die LL abnimmt bzw. ob es dann nicht auch 
ganz ohne geht.
Soweit ich bisher sehen konnte, werden zumindest auch die 
Interrupthandler installiert, aber ganz ohne Funktion - besser als nix.
Das Bitbeissen dürfte auch kein Problem sein - hab auf nem 8052 die 
Ausbildung gemacht, da waren Bits an der Tagesordnung :) Nur nimmt einem 
die HAL das alles ab und ich könnte das Projekt dann zügiger 
abhandeln... Da ich aber an den F011 gebunden bin, dürfte das mal wieder 
eine gute Übung sein.

@CubeMX Hater:
Ja, wenn ich alles auf LL setze, komme ich bei etwa 2-3kB raus. Das wär 
okay. Nur weiß ich eben nicht, was das an Mehraufwand bedeutet, da man 
dann doch einiges zu Fuß machen muss. Bimbo konnte mir in der Hinsicht 
wie gesagt etwas die Sorgen nehmen, das Konvertieren von HAL nach LL 
scheint nicht ohne Aufwand zu gehen, ist aber auch nicht unlösbar.

Grüße

Autor: Bimbo. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf schrieb:
> Soweit ich bisher sehen konnte, werden zumindest auch die
> Interrupthandler installiert, aber ganz ohne Funktion - besser als nix.

Wenn du ein Projekt in Atollic erstellst, wird auch eine .s Startup 
Datei erzeugt, in dem die Interrupts alle definiert sind. In deinem 
Programm rufst du den Interrupt nur noch auf durch (Beispiel Timer6 
Überlauf):
void TIM6_IRQHandler(){
  TIM6->SR &= ~TIM_SR_UIF;
}

Musst nur Bedenken:
a) Clock für Timer aktivieren - sonst geht nichts ;)!
b) Interrupt im Timer freigeben für z.B. Überlauf (hat mehrere 
Interruptmöglichkeiten)
c) Im NVIC den Interrupt vom Timer6 priorisieren und freigeben
d) Im void TIM6_IRQHandler(){} werden sämtliche Interrupts vom Timer6 
abgearbeitet. Brauchst also eine If-Abfrage, welcher Interrupt vorliegt 
und musst oftmals das Flag per Software zurücksetzen.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Bimbo,

das ist schon mal eine gute Orientierung, besten Dank.

Speziell für Punkt d), das hab ich innerhalb der HAL auch so gesehen, so 
werden dann die verschiedenen Callbacks aufgerufen. Dann kann ich mich 
glaube ich wirklich an der HAL orientieren und Stück für Stück umbauen.

Besten Dank, werd ich so mal in Angriff nehmen.

Gruß

Autor: Zweig (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf schrieb:
> ich möchte einen STM32L011 (8kB Flash / 2kB SRAM) programmieren

schon mal dran gedacht das es auch größere Bausteine gibt?

Je nach Stuckzahl ist die Frage wo man das Geld/Zeit verbuddelt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.