PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mittels goto an Programmanfang springen



demmy
28.11.2012, 12:06
Hallo zusammen,

ich hätte folgende Frage, ich würde gerne um einen µC Reset zu erzeugen mittels Goto-Befehl an den Anfang meines Programmes springen. Bzw. an einen Punkt nach der Hardwarekonfiguration und vor den Variablenzuweisungen.

Ist das möglich?

Was passiert mit den Variablen wenn sie neu erstellt werden? Sie müssten doch dann alle wieder unbeschrieben sein oder?

Gruß

Kampi
28.11.2012, 12:19
Hey,

wenn du mit dem Goto an eine Stelle springst wo du die Variablen auf 0 setzt geht das (nicht an die Stelle wo du die Variablen deklarierst).
Generell kannst du so einen "Reset" auslösen.
Du kannst den Reset aber auch z.B. auslösen indem du den Reset-Pin per Transistor schaltest.

demmy
28.11.2012, 12:51
Das mit dem Resetpin usw. kenne ich.

Ich wollte aber eigentlich nur die Variablen "richten" keinen Hardwarereset. Das heißt ich müsste mir eine Funktion schreiben in der alle Variablen gerichtet werden.

Was passiert denn wenn ich an den Punkt springe an dem die Variablen deklariert werden? Hängt sich der µC dann auf oder so?

oberallgeier
28.11.2012, 12:54
... einen µC Reset ... mittels Goto-Befehl an den Anfang meines Programmes springen ...Die Frage lässt vermuten, dass Du Dinge vorhast, die unschön sind - oder dass Dein Programm vermeidbare Macken hast. Ich spreche da aus Erfahrung - leider.

Watchdog-Reset hier ausführlich (http://www.rn-wissen.de/index.php/Avr-gcc#Reset_ausl.C3.B6sen), in BAscom hier. (http://www.rn-wissen.de/index.php/Watchdog)


... Resetpin usw. kenne ich ... wollte aber eigentlich nur die Variablen "richten" ...Für solche Zwecke - Einrichten von VARIABLNE - habe ich in fast allen Programmen eine Routine


void init_KO_lst(void) ; // Vorgabe von Konstanten in dieser Liste
da weiß ich dann recht genau, was ich tue . . . denn bekanntlich tut der Computer/Controller immer das was man ihm sagt, das ist aber nicht immer das, was man meint, ihm gesagt zu haben.

demmy
28.11.2012, 13:04
da weiß ich dann recht genau, was ich tue . . . denn bekanntlich tut der Computer/Controller immer das was man ihm sagt, das ist aber nicht immer das, was man meint, ihm gesagt zu haben.

das hast du schön gesagt. ;)

Also was ich genau vor habe ist, wenn ein bestimmter Befehl über die UART rein kommt, soll der µC an den Anfang des Programmes springen (aus der Hauptschleife raus) und sein Programm von vorne anfangen ohne komplett neu gestartet zu werden. Da vor der Hauptschleife einmalig ein paar Berechnungen stattfinden. Dazu müsste ich ein paar Variablen zurücksetzen und eben auf den besagten Punkt springen. Ich denke so ein "Softwarereset" müsste doch ohne Probleme mittels einer Routine zum Richten der Variablen und der Verzweigung auf einen Einstigespunkt möglich sein oder?

Sauerbruch
28.11.2012, 14:56
Es dürfte wohl kein Problem sein, mittels eines GOTO vor die Deklaration der Variablen zu springen.


Was passiert mit den Variablen wenn sie neu erstellt werden? Sie müssten doch dann alle wieder unbeschrieben sein oder?

Das kann man wunderschön im Simulator testen! Ich habe es gerade versucht, und die Variablen bleiben absolut unverändert! Sie durch erneutes Deklarieren auf 0 zu setzen, funktioniert wenigstens in der Simulation nicht.

Da wirst Du wohl um eine Rücksetz-Routine nicht herumkommen...

peterfido
28.11.2012, 16:57
Wenn UART Empfang nicht in der Hauptschleife ausgewertet wird, passen die Werte auf dem Stack nicht. Irgendwann wird dieser dann überlaufen.
Ich würde für die Berechnungen am Anfang des Programmes eine Sub erstellen und diese dann nach dem bestimmten UART Befehl aufrufen.

Goto 0 springt an den Anfang des Programmes (Adresse 0). Dort wird normal auch alles neu initialisiert. Aber so weit wolltest Du ja nicht zurückspringen. Ich nutze für einen Reset
immer den Watchdog. Einfach einschalten und dann ein do:loop hinterher und der AVR startet neu.

oberallgeier
28.11.2012, 16:59
... Da vor der Hauptschleife einmalig ein paar Berechnungen stattfinden ...Die doofe Bemerkung vorneweg: ich kenn mich mit Bascom nicht aus, ich programmiere in C, sehr selten in Assembler. Ne Vermutung hinterher: kann es sein, dass es bei Bascom Direktiven für den Präprozessor gibt (den Präprozessor müssts doch da auch geben)?

Feststellung: Wenn ich vorneweg EINMALIG ein paar Berechnungen anstelle, dann nenne ich diese Werte ("... ein paar Variablen zurücksetzen ...") aber KONSTANTEN. Diese Berechnungen lasse ich dann nach Möglichkeit vom Präprozessor erledigen, das spart Programmspeicher. Auch wenn Programmspeicherplätze bei mir selten ein Problem sind. Und ne Konstante muss ja nicht online oder im Controller berechnet werden. WENN sie neu berechnet würde - dann müssten sich doch die Gegebenheiten ändern/geändert haben . . . oder versteh ich da was falsch?

Nochne Vermutung: kann es sein, dass es bei Dir garnicht um Berechnungen im Controller geht - sondern im Präprozessor? Irgendwie sind solche Fragereien gelegentlich mit eher nicht vollständiger oder unklarer oder .... Problembeschreibung verbunden.

Vitis
29.11.2012, 11:35
Man kann mit Goto 0 an den Programmanfang springen und wenn das NOINIT nicht gesetzt ist werden dann auch die Variablen auf Null gesetzt, aber, es hat ja einen Grund warum Du das Programm neu starten willst, eine Fehlfunktion z.B. und es werden eben nur die Varablen neu gesetzt, der Stack bleibt. Wenn Dein Programmfehler in nem Überlauf besteht, dann geht das so in einem fort :(
Besser ist es einen kompletten Reset durchzuführen, auch für die Peripherie, sprich, zum Einen per Watchdog einen Reset herbeiführen und in der Startroutine Deines Programmes z.B. nen externen AD-Wandler vor der Initialisierung zu resetten.
Der Vorteil ist auch, dass ggf. ein Bootloader dann ausgeführt werden kann für Firmwareupdates, da der noch vor dem Programmstart ausgeführt wird.

demmy
30.11.2012, 07:19
Hi zusammen,
nein nein, es handelt sich nicht um eine Fehlfunktion oder ähnliches. Es ist etwas komplizierter das hier zu erklären und würde sicher den Rahmen hier sprengen.

Bei der Problematik mit den Konstanten / Variablen gebe ich dir nur bedingt recht. Wenn es sich um Konstanten handelt, dann hätte ich sie auch so bezeichnet. In Wirklichkeit sind es aber Variablen, deren Startwert berechnet wird, die dann aber im laufenden Programm überschrieben werden.

Ich habe es jetzt so gelöst, das ich mittels goto an einen definierten Startpunkt springe, da vor diesem Startpunkt noch Verzögerungszeiten / Wartezeiten / Berechnungen usw. ausgeführt werden. Die wirklich nur bei einem kompletten neustart des Systems einmalig benötigt werden um angeschlossene , ich bezeichne sie jetzt mal als "Pheripherie" zu Initialisieren bzw. Ihr Zeit zum Anlaufen zu geben.

Was ich erreichen wollte ist im Prinzip nur ein simpler "Softwarereset", wo an einem definierten Punkt wieder neu ins Programm eingesprungen wird.

Searcher
30.11.2012, 08:33
Also ich hätte nichts dagegen obwohl ich versuchen würde es anders zu lösen ;) Der Sprung mit GOTO sollte nur nicht aus einem Unterprogramm oder gar einer Interruptroutine heraus erfolgen, da sonst der Stack durcheinanderkommt.

Gruß
Searcher

oberallgeier
30.11.2012, 10:30
... nichts dagegen obwohl ich versuchen würde es anders zu lösen . Der Sprung mit GOTO ...Sowohl in meinem recht komplexen Transistortester - ähnlich hier, (http://www.mikrocontroller.net/articles/AVR-Transistortester) aber mit I 2 C und weiteren, eigenen Funktionen - als auch in meinem Pacer (hier) (https://www.roboternetz.de/community/threads/48271-ISP-zum-Aufklippen-für-THT-Controller) habe ich GOTO´s. Der Pacer läuft mit sleep - und ich habe eigentlich noch nie nen Absturz erlebt. Der Transitortester wird zwar immer neu gestartet, aber auch hier ist bei längerem, durchgehenden Gebrauch kein Nachteil zu erkennen - und keine Fehlfunktion.

Searcher
30.11.2012, 12:29
@oberallgeier: Ich habe ja auch gar nichts gegen die Nutzung von Goto. Mir ging es darum, daß man auf den Stackpointer achten sollte und bei Sprung aus einer ISR heraus auch noch auf das Global Interrupt Enable Bit. Das könnte kompliziert werden und kann man vermeiden, wenn man Goto vermeidet oder es nur innerhalb des Hauptprogramms verwendet bzw. nur innerhalb von Subroutinen springt.

zB bei sowas wird der Stackpointer immer weiter nach unten gesetzt und es muß irgendwann zum crash kommen.

dim x as byte
dim y as byte

init:
x = 1
y = 2

gosub check

do
loop

check:
if x = 1 goto init
return

end

Steht anstelle von "goto init" ein "goto 0" wird auch der Stackpointer neu initialisiert.
Ist halt eine Frage der Konstellation und wie Demmy es einsetzt.

Gruß
Searcher

demmy
01.12.2012, 14:56
Also ich habe es in etwa so gelöst:



'Hardwarekonfiguration
....

'Variablendeklaration
....

'Anlaufbedingungen / Startberechnungen
....

Resetpunkt:

' Variablen richten
....

' Notwendige Berechnungen
...

' Hauptschleife
Do

if .... then
goto Resetpunkt
end if

Loop


Also bis jetzt funktioniert es einwandfrei.

Searcher
01.12.2012, 17:33
Also ich habe es in etwa so gelöst:
Da finde ich jetzt kein Haar in der Suppe :-) ; ist in Ordnung!

Gruß
Searcher

peterfido
02.12.2012, 06:57
Ja, geht auch.

Ist in etwa das gleiche wie meine Vorgehensweise.




'Hardwarekonfiguration
....
'Variablendeklaration
....
'Anlaufbedingungen / Startberechnungen
....
gosub Resetpunkt
' Hauptschleife
Do
if .... then
gosub Resetpunkt
end if
Loop
end

Resetpunkt:
' Variablen richten
....
' Notwendige Berechnungen
...
return