Da ich die Grundlagen lernen will, experimentiere ich mit einem STM32F103 Mikrocontroller ohne HAL. Jedes mal, wenn ich für mich zufriedenstellend herausgefunden habe, wie man eine Funktion benutzt (Takt, ADC, PWM, RTC, usw) habe ich danach mal in Tutorials geschaut, wie das denn mit der HAL gemacht würde. Dabei ist mir immer wieder aufgefallen, dass die HAL Beispiele weder kürzer noch übersichtlicher noch Hardware-Unabhängiger sind. Darüber hinaus vergibt die HAL für Register und Bits neue Namen, die nicht mit dem Reference-Manual überein stimmen, um die Verwirrung zu maximieren. Ständig muss ich in die Quelltexte der HAL hinein schauen, um nachzuvollziehen, was sie tut (denn die Doku ist Rotz, sorry). Das kann doch nicht Sinn der Sache sein? Ich glaube die HAL ist nur dann nützlich, wenn darauf aufbauende Libraries auf höherer Ebene nutzt (z.B. für USB). Allerdings habe ich auch dafür längst kompaktere und verständlichere Alternativen gefunden (und zwar hier im Forum). Ist meine Erkenntnis im Groben und Ganzen korrekt?
Ich denke nicht das es darauf eine Antwort gibt. Jeder Bastler wie er mag, jeder Profi so wie er es vorbereitet (vorgefunden) hat bzw. so wie ihm befohlen wird.
Ich verzichte auch auf die STM32Cube und verwende CMSIS. Gent meistens sehr viel einfacher und direkert, zumindestens für die einfachen Peripherie Funktionen wie UART, SPI, I2C, Timer und ADC. Nur wenn ich einen Ethernet Controller mit LwIP verwende, benutze ich dafür die STM32Cube da ich noch keine Zeit dafür gefunden habe einen eigenen Treiber zu schreiben.
So meinte ich das nicht. Ich wollte keine Empfehlung für oder gegen die
HAL, sondern eine Einschätzung, ob meine Erkenntnisse bezüglich der
Nachteile korrekt sind. Ich habe mit der HAL ja noch fast gar nichts
gemacht und schätze die Situation daher womöglich völlig falsch ein.
> Nur wenn ich einen Ethernet Controller mit LwIP verwende ...
Heißt das: wenn du einen Treiber auf Basis der CMSIS hättest, würdest du
ihn bevorzugen?
Auf jeden Fall bin ich ganz froh darüber, dass man nach dem Erstellen
des Grundgerüstes mit Cube MX einfach mit CMSIS weiter arbeiten kann.
Niemand zwingt einen dazu, ALLES mit der HAL zu machen.
Ich finde HAL sehr gut. Im Zusammenspiel mit CubeMX und der Auto-Vervollständigung vom SW4STM32 unterstützt es einen auch wenn das Gehirn nicht mehr alles selbst speichert. Ausserdem kommt man schnell ans Ziel. Wenn du natürlich für alles Nötige deine eigenen Funktionen schon hast, bleib dabei.
Übrigens ist das Meiste, dass die HAL Funktionen größer macht die Sicherheit. Man kann z.B. mit ein paar Bytes den Takt einstellen, man kann aber auch den Erfolg jeder Funktion Abfragen und Auswerten, so wie HAL das macht.
Du weist aber schon, daß dioe CMSIS Bestandteil der HAL ist und auch von der genutzt wird? Wenn die Frage sinnvoll sein soll, dann eher "HAL, SPL oder ohne Middleware?" Wober es für die neueren STM32 keine SPL mehr gibt, da geht nur mit oder ohne HAL.
Die HAL ist extrem resourcenfressend. Ich habe mal DMA fullduplex mit HAL ausgemessen. Aufsetzen der DMA frisst alleine 5 Mikrosekunden. Dann werden 3 Interrupts von der HAL ausgeführt, alle auch arschlangsam. HAL generiert 3 (!) Interrupts. Die machen einen Interrupt, wenn DMA halb leer ist (völliger unsinn) und je einen wenn TxDMA und RxDMA fertig ist. Insgesamt werden mehr als 12 us verbraten. Ich habe es mit den ebenfalls in CubeMX enthaltenen Low level sourcen nachgebaut und komme damit auf 1.3 us (72 MHz Takt, nucleo STM32F411) Beim einfachen Setzen eines GPIO sieht es ähnlich aus. Mit den Low Level erreicht man um die 30 MHz beim einfachen einauschalt Test. Mit Hal gehts arg in die Knie.
Stefan U. schrieb: > Ist meine Erkenntnis im Groben und Ganzen korrekt? Jap total! Ich hatte im März rum mit den STM32 angefangen und bin mit HAL gestartet. Hatte aber damit nur Probleme und die Abstraktionsebenen waren mir zu krass. Da wird auch so ein Haufen an Overhead (vorallem alles, was mit Interrupts gemacht wird) mitkompiliert, das hatte mir dann auch nicht gefallen. Nachdem ich quasi schon ein fertiges Projekt auf CMSIS umgebaut hatte, war es nicht nur übersichtlicher, es lief auch wesentlich performanter. Ich finde HAL schrecklich :) Dummerweise wird man für neue STM32-µCs wohl keine StdPeriphLib mehr erhalten :/ Ehrlich gesagt, ein Grund für mich von den STM32 auf lange Sicht wieder zu verabschieden, obwohl ich im Grunde sehr zufrieden war. HAL ist aber für mich ein Nogo ... Allerdings verwende ich sehr gerne CubeMX, um die Peripherie für meine Pins auszuwählen. Der Code, der dann für die GPIOs generiert wird, kann schnell auf CMSIS umgebaut werden.
:
Bearbeitet durch User
Eins der Dinge, die mich an der ST HAL ganz gewaltig stört, ist dass sie einen interruptgesteuerten HW 1ms Timer ungefragt installiert - und zwar zu dem einzigen Zweck, einen Timeout auf HAL Initialisierungsfunktionen zu implementieren. Das ist nicht nur für die meisten praktischen Zwecke sinnfrei (wenn die Prozessorinitialisierung nicht durchgeht, gibt es in aller Regel kein kontrolliertes recovery, also wozu einen Timeout? Was tut man, wenn der zuschlägt? Und wenn es Sinn macht, den Fall zu unterscheiden, darf man an der Stelle auch ruhig mal mit Busy Wait und Polling auf eine Flag schaffen, da die Zeit eh nicht Anders genutzt werden kann), sondern hat Auswirkungen auf alle möglichen Systemteile, wie z.B. - Bootloaderkompatibilität (was wenn die IVT umgebogen werden muss?) - Low Power Sleep Modus (wie verhindere ich, dass dieser nutzlose ISR mich jede Millisekunde völlig effektfrei aufweckt?) - Footprint - Ressourcennutzung (ich würde in den meisten Fällen gerne selber bestimmen, wie viele und welche Timer meine Applikation nutzt) Etc pp. Die STMLib war mir im grossen und Ganzen symapthischer, hat aber ihre eigenen Probleme (z.B. wurden bibliotheksglobale Variablen gehalten, in denen die Prozessorfrequenz zwischengespeichert wurde. Da man in der als lib kompilierten Variante Probleme hat, das Layout der Variable zu beeinflussen, gibt es i.Z. mit Bootloadern interessante Effekte, die so manche Woche Entwicklungszeit für Fehlersuche schlucken). Die CMSIS ist ja nichts weiter als ein PAL (Processor Abstraction Layer), in den neueren Varianten ein PMAL (Processor and Middelware Abstraction Layer). Da sie weniger Annahmen über die zu Grunde liegende HW machen kann (eigentlich nur den jeweiligen Cortex Kern), ist sie weniger invasiv. Man muss sich aber immer vor Augen halten, dass all diese Layers nicht (jedenfalls nicht primär) aus altruistischen Gründen (so wie dem Entwickler das Leben zu erleichtern) gemacht wurden, sondern um Geschäftsziele umzusetzen (Stichwort vendor lock in). Das ist erstmal nicht verwerflich oder unmoralisch. Aber es sollte sich Niemand der Illusion hingeben, dass die Verwendung so eines HAL (egal wie er heisst und von wem er kommt) tatsächlich zu einem Plug and Play Click-Compile-and-run Entwicklungszyklus führt. Ich nutze übrigens lwip komplett ohne HAL, und es geht problemlos.
> Du weist aber schon, daß dioe CMSIS Bestandteil der HAL ist > und auch von der genutzt wird? Ja natürlich. In der Tat habe ich CMSIS Files aus einem HAL Projekt extrahiert da ich keine separate Quelle gefunden habe.
Hallo, zum Bootloader habe ich auch noch eine Geschichte. Hatte länger dran debuggt. Der Bootloader lief, aber wie nun das zu loadende Programm generieren? den *.ld file anpassen, damit die IVT stimmt, reicht leider nicht! HAL generiert einen file namens system_stm32f4xx.c darin enthalten ein define: #define VECT_TAB_OFFSET 0x00 das muss man anpassen, es ist ein Offset! bei mir lag die IVT bei 0x8010000 im *.ld file dann muss man den offset als 0x10000 definieren, sonst funzt das Ganze nicht. so was ist einfach Sch....! Die load Adresse muss man händisch in den generierten sourcen anpassen. Wenn man dann CubeMX noch mal generieren lässt, weil man was vergessen hatte, muss man das wieder händisch anpassen. Cube überschreibt das define wieder. Beschrieben war das in einer UM, aber bis ich das fand. . . .
Martin B. schrieb: > bei mir lag die IVT bei 0x8010000 im *.ld file > dann muss man den offset als 0x10000 definieren, sonst funzt das Ganze > nicht. Ähm, dann hast du obskure Linker-Scripte mit dem generierten Source-Code von HAL gemixt ... Wüsste in diesem Fall nicht, was HAL dafür können soll ...
Mampf F. schrieb: > Martin B. schrieb: >> bei mir lag die IVT bei 0x8010000 im *.ld file >> dann muss man den offset als 0x10000 definieren, sonst funzt das Ganze >> nicht. > > Ähm, dann hast du obskure Linker-Scripte mit dem generierten Source-Code > von HAL gemixt ... > > Wüsste in diesem Fall nicht, was HAL dafür können soll ... Ich habe nichts gemixt, nur was geändert. Der *.ld file wurde von CubeMX generiert und dort habe ich die Start Adresse geändert. Ich wüsste nicht wo sonst. in CubeMX habe ich keine Möglichkeit gesehen, die startadresse zu ändern. Vielleicht habe ich ja was übersehen.
Martin B. schrieb: > Die HAL ist extrem resourcenfressend. Ich habe mal DMA fullduplex mit > HAL ausgemessen. > Aufsetzen der DMA frisst alleine 5 Mikrosekunden. Dann werden 3 > Interrupts von der HAL ausgeführt, alle auch arschlangsam. HAL generiert > 3 (!) Interrupts. Die machen einen Interrupt, wenn DMA halb leer ist > (völliger unsinn) und je einen wenn TxDMA und RxDMA fertig ist. > Insgesamt werden mehr als 12 us verbraten. > > Ich habe es mit den ebenfalls in CubeMX enthaltenen Low level sourcen > nachgebaut und komme damit auf 1.3 us (72 MHz Takt, nucleo STM32F411) > > Beim einfachen Setzen eines GPIO sieht es ähnlich aus. Mit den Low Level > erreicht man um die 30 MHz beim einfachen einauschalt Test. Mit Hal > gehts arg in die Knie. Mit Optimierung und LTO? Compilerversion? Das mit dem GPIO-Toggle glaub ich dir nicht. Und ohne LTO musst du gar nicht erst kommen, das macht extrem viel aus. Ich nutze die HAL inzwischen bei jedem Projekt und hatte mit ihr noch nie Geschwindigkeitsprobleme. Die hat man eher in den Algorithmen, auf welche man sich dann konzentrieren kann. Was interessiert mich ob die Initialisierung eine µs länger dauert? Ruediger A. schrieb: > Man muss sich aber immer vor Augen halten, dass all diese Layers nicht > (jedenfalls nicht primär) aus altruistischen Gründen (so wie dem > Entwickler das Leben zu erleichtern) gemacht wurden, sondern um > Geschäftsziele umzusetzen (Stichwort vendor lock in). Ja das liest man hier desöfteren. Aber der Vergleich hinkt, so lange du keine Alternative vorweist, die herstellerunabhängig ist. Egal welche sinnvolle Middleware ich nutze (dazu gehört mMn embed und Arduino nicht dazu), ich bin an STM gebunden. Wer das nicht möchte und seine Bibliotheken plattformunabhängig einsetzen möchte, der zieht eben nach der STM-Middleware noch ein Abstraktionslayer ein und Dank LTO kostet das exakt 0% Overhead.
Stefan U. schrieb: > Ist meine Erkenntnis im Groben und Ganzen korrekt? Ja! Die HAL ist Rotz, schlecht dokumentiert, handwerklich schlecht umgesetzt und abstrahiert exakt garnichts :-)
Stefan U. schrieb: > Ist meine Erkenntnis im Groben und Ganzen korrekt? Klar und einfach: Ja. Es gibt hier ganz viele Leute, die sehr fleißig all die XYZ_InitStruct's ausfüllen, brav all die vielen dargebotenen Funktionen aufrufen, sich ihre Einstellungen von Hilfszeugs wie Cube und so generieren lassen - und die dabei erstens garnichts über das Pferd lernen, das sie reiten wollen und zweitens glauben, das seien die Dinge, auf die es ankäme. Sieh das mal so: All die herstellerseitigen Hilfestellungen sind zwar nicht böswillig gemacht, aber sie sind dennoch sehr einseitig auf die jeweiligen Produkte gerichtet. Es sind sozusagen die Würmer auf den jeweiligen Angelhaken. Funktionieren tut das erstaunlich gut, weil die Masse der Möchtegern-Programmierer es rundweg ablehnt, die jeweiligen Referenz-Schriften durchzulesen, ein klitzeklein wenig Assembler zu lernen und das Aufrufen der Tools wie Compiler usw. zu erlernen. Kurzum: was machen wollen, ohne was zu lernen und zu können. System Schlaraffenland. Obendrein lehnen es viele aus ideologischen Gründen ab, ihren Horizont zu erweitern. Sie nehmen und kennen nix anderes als den Gcc und haben keinen Begriff davon, wie andere Toolchains (z.B. Keil, IAR) funktionieren. Mein Rat ist immer wieder, nicht geradewegs drauflos zu programmieren, sondern strikt getrennt nach Startcode (in Assembler), Setup-Units, Treibern und höheren Programmschichten zu schreiben, wobei die Treiber eine wirklich sinnvolle Schnittstelle nach oben hin haben sollen, also funktional abstrahieren sollen. Und dabei schafft man sich mit der Zeit sein eigenes Portfolio an Quellen, von denen man einige völlig unverändert von einem System auf's andere mitnehmen kann und andere bloß im Detail anzupassen braucht, um sie zu portieren. Auf diese Weise wird man weitgehend unabhängig von einzelnen Herstellern - und man wird effektiv, weil man ne Menge Algorithmen weiterverwenden kann. W.S.
avr schrieb: > Mit Optimierung und LTO? Compilerversion? Das mit dem GPIO-Toggle glaub > ich dir nicht. Und ohne LTO musst du gar nicht erst kommen, das macht > extrem viel aus. Ich nutze die HAL inzwischen bei jedem Projekt und > hatte mit ihr noch nie Geschwindigkeitsprobleme. Die hat man eher in den > Algorithmen, auf welche man sich dann konzentrieren kann. Was > interessiert mich ob die Initialisierung eine µs länger dauert? Habe einen GCC und alle Optimierungen ausgetestet. Weil die performance bei mir das Problem war! Solche Untersuchungen, macht man nur, wenn man muss. Problem war: Alle 15 us kommt ein Interrupt und dann müssen 27 byte per SPI übertragen werden. Wenn ich HAL benutze ohne DMA wirds richtig grausam. Ausser diskussion. Low Level Funktion ohne DMA hatte ich um die 15 us, also 100% nur mit LL und DMA läuft das Teil. Warum die HAL so langsam erschliesst sich, wenn man die die Sourcen der HAL guckt! P.S. wegen GPIO: Wenn Du das mal mit Oszi nachmisstst, brauchst Du Deinen Glauben nicht bemühen.
Martin B. schrieb: > Ich habe nichts gemixt, nur was geändert. > > Der *.ld file wurde von CubeMX generiert und dort habe ich die Start > Adresse geändert. Ich wüsste nicht wo sonst. Ah okay verstehe ... Hmm, damals mit den alten SAM7Sxx hatte ich den Bootloader immer in das Programm integriert und der Code, der vom Bootloader ausgeführt werden muss, in das SRAM gepackt. Im Grunde war das dann kein Bootloader sondern ein Flash-Tool, das on-demand von der Applikation aus gestartet werden kann. Die Alternative dazu war, den default-Bootloader zu verwenden. Die hatten einen im ROM, war aber ultranervig zu verwenden. Jedesmal musste man eine Boot-Recovery-Prozedur durchführen, die aufwändig war. Haben die STM32 nicht auch einen Bootloader schon eingebaut?
:
Bearbeitet durch User
avr schrieb: > > Ruediger A. schrieb: >> Man muss sich aber immer vor Augen halten, dass all diese Layers nicht >> (jedenfalls nicht primär) aus altruistischen Gründen (so wie dem >> Entwickler das Leben zu erleichtern) gemacht wurden, sondern um >> Geschäftsziele umzusetzen (Stichwort vendor lock in). > > Ja das liest man hier desöfteren. Aber der Vergleich hinkt, so lange du > keine Alternative vorweist, die herstellerunabhängig ist. Welcher Vergleich? Warum muss ich (oder irgendjemand Anders) eine Alternative vorweisen? Die Frage war hier schlicht und einfach nach dem praktischen Wert der STM HAL. Wie Viele Andere hier habe ich in der Praxis auftauchende Probleme mit den HALs (also CMSIS, STMLib und der STM HAL) geschildert. Daraus darf Jeder machen, was er/sie will. Wenn Dein Schluss daraus ist, dass man (so interpretiere ich es jetzt erstmal) ja irgendwas nutzen muss und dann eben die am Wenigsten schlechte Alternative nimmt - ist erstmal legitim, ändert aber nichts an den potentiellen Problemen der jeweiligen Layer (s.u.). > Egal welche > sinnvolle Middleware ich nutze (dazu gehört mMn embed und Arduino nicht > dazu), ich bin an STM gebunden. Wer das nicht möchte und seine > Bibliotheken plattformunabhängig einsetzen möchte, der zieht eben nach > der STM-Middleware noch ein Abstraktionslayer ein und Dank LTO kostet > das exakt 0% Overhead. Du meinst Link Time Optimierung ala Somnium? Wird der mir auch den überflüssigen Timer ISR wegoptimieren? Automatisierte Optimierungen können keine architektonischen Probleme lösen.
Mampf F. schrieb: > > Haben die STM32 nicht auch einen Bootloader schon eingebaut? Die STM32 haben bootloader eingebaut. Die funktionieren auch, aber ich will meinen Firmware file schützen durch crypten. Und das können die nicht. Also selber schreiben.
W.S. schrieb: > Es gibt hier ganz viele Leute, die sehr fleißig all die XYZ_InitStruct's > ausfüllen, brav all die vielen dargebotenen Funktionen aufrufen, sich > ihre Einstellungen von Hilfszeugs wie Cube und so generieren lassen Ist für Hobbybedarf ja auch OK, wenn man nur ein wenig basteln will. Noch einen Schritt weiter in die Richtung geht dann gleich die Arduino-Umgebung. Profis setzen das nicht ein, zumindest habe ich derlei noch in keinem industriellen Projekt gesehen. Was wohl auch daher kommt, daß man Leute, die ohne CubeMX nicht klarkommen, gar nicht erst einstellt. > Sie nehmen und kennen nix anderes als den Gcc und haben > keinen Begriff davon, wie andere Toolchains (z.B. Keil, IAR) > funktionieren. Keil und IAR sind aber nur für Miniprojekte kostenlos und kosten ansonsten schnell ein paar tausend Euro. Das würde ich privat auch nicht ausgeben. Zudem spielt es auch keine wirkliche Rolle, weil Register an absoluten Adressen sich mit GCC nicht anders beschreiben als mit Keil und IAR. Die Syntax des Inline-Assemblers kann sich etwas unterscheiden, aber das sind Bagatellen. Zudem, wenn man privat Opensource-Projekte macht, dann ergeben Keil und IAR keinen Sinn, weil das Projekt dann effektiv hinter einer Paywall versteckt ist. Für Industrieprojekte ist hingegen entscheidend, daß man bei Keil und IAR bei Bedarf schnell professionellen Support bekommt, statt sich durch Foren zu wühlen. Mich würde interessieren, welche Nachteile Du beim GCC siehst. Außer daß er von sich aus den SVC nicht unterstützt und man das daher selber reinbasteln muß, wenn man das benutzen will, was aber auch kein Hexenwerk ist. > wobei die Treiber > eine wirklich sinnvolle Schnittstelle nach oben hin haben sollen, also > funktional abstrahieren sollen. Genau das! Und eben das leistet die HAL nicht, weil sie die Hardware gerade nicht funktional abstrahiert.
Ich habe auch das Gefühl, dass die Hardware Abstraktion bei Arduino deutlich gelungener ist, als bei Cube HAL. Und dass, obwohl ich ganz sicher kein Fan von Arduino bin. Cube HAL ist einfach nur klicki-bunti. Aber technisch nichts halbes und nichts ganzes. Wetten, das wird spätestens in 5 Jahren wieder durch was anderes angelöst?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.