Hallo allerseits, vor kurzem habe ich ein Bastlerprojekt mit einem STM32F7-Nucleo angefangen und habe jetzt gewisse grundsätzliche Schwierigkeiten mit der HAL. Das erste Problem war, dass es mir beim Codegenerieren meinen eigenen Code ohne Vorwarnung gelöscht hat. Gut, anscheinend darf man nur in den vorgegbenen /* USER CODE */ -Blöcken schreiben. Aber auch das bringt Probleme mit sich, bspw. verwende ich die UART und den Netzwerkanschluss. Da die Initialisierung der Netzwerkperipherie den Verbindungsaufbau mit IP-Vergabe mittels DHCP beinhaltet, dauert das ein paar Sekunden. Also möchte is sofort nach Initialisierung der UART den Status an den PC senden und nicht erst auf das LAN warten. Einen USER-CODE-Abschnitt gibt es aber nicht zwischen beiden Inits. Mein Workaround war einfach den UART doppelt zu initialisieren, also vorher im User-Code selber MX_USART3_UART_Init(); aufzurufen. Das Vorgehen scheint mir aber nicht ideal. Das nächste Problem ist, dass das Handle für den UART in main.c definiert ist. Wie kann ich das in anderen Dateien verwenden, ohne das Handle vorher in eine globale Variable zu kopieren, was mir wieder eher wie ein Hack vorkommt? Mir scheint das alles brutal unflexibel, offensichtlich mache ich was falsch. Andererseits ist die main.c schon ohne mein Zutun recht aufgebläht, was m.E. schlechter Stil ist. Wie ist also das richtige Vorgehen im Umgang mit der HAL? Vielleicht gibt es ja ein paar Tricks, die man verstanden haben muss. Wo legt man seinen eigenen Code am Besten an, welche Dateien und Bereiche lässt man lieber unangetastet? Vielen Dank!
Maxe schrieb: > Wie ist also das richtige Vorgehen im Umgang mit der HAL? Man nimmt sie bestenfalls zur Initialisierung der diversen PLLs und IO und schreibt seine eigenen Funktionen in separate Dateien. Schnell noch Stollen, Lebkuchen, Spekulatius und Glühwein besorgen ;-)
FreeRTOS verwenden, das wird im CubeMX ja per Click & Play angeboten. Den Ethernet Code dann in eine Task verlagern. Oder ein OS verwenden das nicht dieses fürchterliche 'hier darst du schreiben' und 'hier nicht' verwendet. git hilft auch, nur nicht vergessen vor dem Code generieren einen Commit zu machen.
:
Bearbeitet durch User
Maxe schrieb: > Das nächste Problem ist, dass das Handle für den UART in main.c > definiert ist. Wie kann ich das in anderen Dateien verwenden, ohne das > Handle vorher in eine globale Variable zu kopieren Kannst ja im main.h einfach eine Vorwärtsdeklaration mit "extern ..." auf das Handle anlegen und dann in deinen anderen Dateien das main.h includen. Hat mit der HAL nichts zu tun, sondern ist eine normale C Programmiertechnik.
J. S. schrieb: > git hilft auch, nur nicht vergessen vor dem Code generieren einen Commit > zu machen. Man kann in CubeMX einstellen, dass es vor der Codegenerierung automatisch ein Backup erstellt; diese Option würde ich immer aktivieren. Also wenn man sich konsequent daran hält, den eigenen Code in die vorgesehenen Blöcke (User Code Begin, User Code End) zu platzieren, dann gibts in der Regel überhaupt keine Probleme mit überschriebenem Code.
:
Bearbeitet durch User
und man kann den Code für die Devices in eigene Dateien legen lassen, dann werden die includes mit den externals auch automatisch generiert. das 1. Häkchen in 'Generated files' in dem Screenshot.
:
Bearbeitet durch User
@johnny Das sind gute Tipps, und ohne dein Screenshot wäre es schwierig zu finden gewesen. Danke! Mit Extern lässt sich auch gleich noch ein anderes Problem lösen, auf das ich gestoßen bin :) @jojos Ich wollte es nicht noch komplizierter machen und mit einem RTOS eine weitere 'Abstraktion' einführen. @m.n. Das mit den eigenen Dateien mach ich auch so wo möglich, nur braucht man ja auch irgendwo die Anbindung an den Rest.
Die CubeMX Init Routinen bereiten doch nur die Hardware vor. Ein Init mit DHCP usw machen die doch gar nicht. Von daher sollet es kein Problem sein, seine eigenen Applications Init Routinen anderweitig zu verwursten und auszulagern
Maxe schrieb: > Das mit den eigenen Dateien mach ich auch so wo möglich, nur braucht man > ja auch irgendwo die Anbindung an den Rest. Rufe nach der Initialisierung Dein 'hauptprogramm()' auf und ignoriere HAL. Die STM32 lassen sich bestens auch auf Registerebene programmieren. Damit sind dann alle Probleme mit HAL abgehakt ;-)
A. B. schrieb: > Die CubeMX Init Routinen bereiten doch nur die Hardware vor. Ein Init > mit DHCP usw machen die doch gar nicht. Von daher sollet es kein Problem > sein, seine eigenen Applications Init Routinen anderweitig zu verwursten > und auszulagern In meim Testprojekt sieht das wie folgt aus, in MX_LWIP_Init() steckt die komplette Initialisierung des Ethernet inklusive Hardwareinitialisierung (netif) als auch DHCP drin. Aber ja, ich versuch jetzt nur das Nötigste in die Main reinzupacken.
1 | /* Initialize all configured peripherals */
|
2 | MX_GPIO_Init(); |
3 | MX_USART3_UART_Init(); |
4 | MX_LWIP_Init(); |
5 | /* USER CODE BEGIN 2 */
|
6 | /* USER CODE END 2 */
|
m.n. schrieb: > Die STM32 lassen sich bestens auch auf Registerebene programmieren. > Damit sind dann alle Probleme mit HAL abgehakt ;-) Mir ging es hauptsächlich darum LwIP zum Laufen zu bekommen. Ich versuch das jetzt mal zu entheddern um aus dem Codegeneratorenzeug rauszukommen.
Ganz unabhängig von Cube HAL bietet sich Git an, um Änderungen zur protokollieren. Nach der Installation von Git gebe im Projektverzeichnis folgendes ein:
1 | git init |
2 | git add * |
3 | git commit -am "Dein Kommentar" |
Es ist wirklich so einfach. Später kannst du den commit Befehl wiederholen, um weitere Schnappschüsse deiner Dateien zu erstellen. Mit Git kannst du anschließend alle Änderungen nachvollziehen und ggf. rückgängig machen. Weitere Git Kommandos, siehe http://stefanfrings.de/git/index.html Die Schnappschüsse werden in dem Unterverzeichnis ".git" gespeichert, welches der init Befehl angelegt hat. Wenn du das alles wieder los werden willst, lösche einfach dieses Verzeichnis. Natürlich hat deine IDE dafür auch Funktionen in ihrer GUI. Die werden aber erst nach dem init Befehl benutzbar.
m.n. schrieb: > Die STM32 lassen sich bestens auch auf Registerebene programmieren. > Damit sind dann alle Probleme mit HAL abgehakt ;-) Tja. Seit wievielen Jahren gibt es dieses Zeug von ST nun schon? Und immer noch lassen sich die Leute da drannageln. Und wenn sie mal etwas machen wollen, was von den Konstrukteuren von HAL, CUBE und so nicht vorgesehen ist, dann stehen sie hilflos da. Ein jeder hätte sich im Verlaufe der letzten Jahre ein Portfolio von Treibern, eigener Middleware und Konfigurationsfunktionen machen/zulegen können und wäre damit in der Lage, ohne viel Aufwand seine Firmware so zu machen, wie er sie haben will. Aber das hätte anfangs etwas mehr Arbeit gemacht und die Faulheit hat wie üblich gesiegt. W.S.
W.S. schrieb: > Tja. Seit wievielen Jahren gibt es dieses Zeug von ST nun schon? Und > immer noch lassen sich die Leute da drannageln. Und wenn sie mal etwas > machen wollen, was von den Konstrukteuren von HAL, CUBE und so nicht > vorgesehen ist, dann stehen sie hilflos da. Was dann eher daran liegt, daß sie durch die HAL "noch" nicht wirklich durchblicken. Die ST-HAL ist nun mal nix, was man "mal eben" an einem Wochenende durchschaut, aber die Dokumentation kann sich inzw. auch sehen lassen. W.S. schrieb: > Ein jeder hätte sich im Verlaufe der letzten Jahre ein Portfolio von > Treibern, eigener Middleware und Konfigurationsfunktionen machen/zulegen > können Bla bla bla... Soviel Middleware, Treiber etc, wie inzw. zum Cube-Ecosystem gehören kannst du in deinem ganzen Leben nicht schreiben. Klar hakts da hier und da auch mal, aber in >99% aller Fälle in denen es nicht funktioniert sitzt das Problem 50cm vor dem Monitor. Und wenn ich die Qualität deines Code mit dem der HAL vergleiche, stellt sich mir die Frage ohnehin nicht mehr.
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.