Guten Tag
Ich habe eine Frage, die mir etwas peinlich ist, da ich wirklich gerade
ein wenig auf dem Schlauch stehe.
Ich arbeite mit einem Nucleo Board STM32G071 und versuche mit einem
kleinen Übungsprogramm schlicht ein Relais hin und her zu schalten. Bzw
toggle ich zwei Pins der CPU.
Das Nucleo Board speise ich über die USB-Schnittstelle mithilfe des
integrierten ST-Link.
So weit so gut, nun aber folgendes: Wenn ich die Spannungsversorgung
trenne und nachher wieder herstelle, ist das Programm weg, heisst also
ich muss das Programm wieder über die Entwicklungsumgebung laufen
lassen. So lange die Versorgung nicht unterbrochen wird funktioniert
alles, sobald ich aber trenne und neu connecte, müsste das Programm ja
automatisch wieder anlaufen, ohne dass ich es über die
Entwicklungsumgebung starte, oder sehe ich das falsch?
Ob Flash oder RAM wird normalerweise per Hardware Pins ausgewählt.
Es kann aber auch sein, dass das Programm nicht an der Flash Adresse
liegt, an der der Controller beim Start sucht.
(Wenn man per Debugger startet springt der Controller an die richtige
Adresse)
Das sind dann alles Einstellungen des Links bzw. allgemein der
Toolchain.
Dretox schrieb:> Das könnte sein. Gibt es eine Möglichkeit das über den Compiler> einzustellen oder muss das softwaremässig geschehen?
Welcher Speicherbereich für dein Programm verwendet wird hängt davon ab,
was im verwendeten Linker-File (*.ld) steht. Dort gibt es die
verfügbaren Speicherbereiche (Flash, RAM, ...) sowie die Anweisung
welche Sektionen wohin gelinkt werden sollen, also bspw möchtest du
.text nach FLASH haben, genauso wie die ganzen Konstanten und
Library-Sachen.
Vielleicht gibt es in Deinem Projekt ja Linker-Files für FLASH und für
RAM?
Ansonsten halte ich das Schauen nach den BOOT0/BOOT1 Pins für
lohnenswert:
Mike R. schrieb:> Ob Flash oder RAM wird normalerweise per Hardware Pins ausgewählt.
Die Entwicklungsumgebung kann nämlich beim Debuggen die hardwareseitige
Einstellung umgehen und den Program Counter auf dein Programm zeigen
lassen.
Phantomix X. schrieb:> also bspw möchtest du> .text nach FLASH haben, genauso wie die ganzen Konstanten und> Library-Sachen.
Das scheint auch so zu klappen.
Phantomix X. schrieb:> Ansonsten halte ich das Schauen nach den BOOT0/BOOT1 Pins für> lohnenswert:
Möglicherweise ist hier der Wurm drin. Wenn ich das Programm per
Breakpoint stoppe, sehe ich im Flash Register, dass BOOT0 und BOOT1
beide auf 1 sind. Laut Reference Manual ist die selected boot area in
diesem Fall nicht das Flash sondern das System Memory (also das RAM?)
Um vom Flash zu booten, müsste der Pin BOOT0 low sein. Das kann ich
allerdings nicht einfach so machen, da dieser die alternate function
SWCLK hat...
Dretox schrieb:> Um vom Flash zu booten, müsste der Pin BOOT0 low sein. Das kann ich> allerdings nicht einfach so machen, da dieser die alternate function> SWCLK hat...
Mach einen Pull-Down Widerstand dran. Nachdem der µC gestartet hat, darf
er jeden beliebigen Pegel haben.
Das habe ich versucht, leider ohne Erfolg. Wenn ich im Programm stoppe
wird BOOT0 weiterhin als 1 angezeigt. Allerdings habe ich im Reference
Manual nochmal nachgesehen. Wenn BOOT0 und BOOT_SEL beide 1 sind, was
der Fall ist, hat BOOT1 keinen Einfluss und die CPU bootet vom Main
Flash Memory. Also auch hier dürfte alles richtig funktionieren..
Ich habe mit dem CubeProgrammer einen Flash Erase durchgeführt und das
Flash dann überprüft. An der Adresse 0x08000000 Steht dann FF, wenn ich
dann mit dem CubeProgrammer mein Hex File aufspiele, steht da zwar was,
aber das Programm läuft halt trotzdem nicht ab.
Das Flash wird also definitiv beschrieben und ich kann mir auch nicht
vorstellen, dass die CPU nicht vom Flash bootet. Ich vermute nach wie
vor ein Problem mit der Einstellung des Compilers. Ich nutze
CrossStudio, evtl. kennt sich da jemand aus?
werden evtl. Ausgaben über Semihosting gemacht? Müsste in den Linker
oder Debugeinstellungen zu sehen sein ob es aktiviert ist. Dann hängt
das Programm wenn Ausgaben gemacht werden sollen und kein Debugger
vorhanden ist.
Mittlerweile konnte ich heute das Problem nun lösen.
Einerseits habe ich firmeninterne Projekteinstellungen übernommen.
Üblicherweise wird an der Flashadresse 0x08000000 ein Bootloader
aufgespielt und die Hauptapplikation bei 0x08002000. Da ich keinen
Bootloader verwende, galt es das in den Linkeroptions anzupassen.
Das ist aber noch nicht alles. Beim generieren des Projekts wird ein
STM32_Startup.s File erzeugt. Dort sind über die Preprocessor
Definitions mehrere Optionen auswählbar, wie sich die CPU beim
Aufstarten oder nach einem Reset zu verhalten hat. Entscheidend war hier
folgender Codeblock:
1
#ifndef STARTUP_FROM_RESET
2
.thumb_func
3
reset_wait:
4
1: b 1b /* endless loop */
5
#endif
Also habe ich in den Preprocessor Definitions "STARTUP_FROM_RESET"
definiert und nun funktioniert das Programm auch nach einem Neustart der
CPU.