Probleme mit "rjmp 0000" und "CLI" (ASSEMBLER) ATmega8

OP #333627
Lesenswert?

Hallo,

mir fehlt momentan eine logische Erklärung auf folgendes Problem:

In meinem sehr umfangreichen ASSEMBLER-Programm für den ATmega8
(16MHz)möchte ich an einer bestimmten Stelle den µC Reset-en.

SPRUNGMARKE_NEUSTART:
        clt temp
        OUT MCUCSR, temp
  rjmp 0000

So weit, so gut.

Aber plötzlich dauert die Ausführung des Programms extrem lange
(5x soviel Zeit wie sonst), bis die Startprozedur (PORTS und TIMER
initialisieren, verschidene TEXTE an LCD ausgeben usw.) abgeschlossen
ist.

Anmerkung:
Über USART werden permanent ca. 500Byte pro Sekunde Daten von einer
GPS-MOUSE empfangen. Wenn ich die Datenzufuhr unterbreche geht es
gewohnt schnell.



Dann habe ich folgendes geändert:

SPRUNGMARKE_NEUSTART:
        clt temp
        OUT MCUCSR, temp
        CLI                ; Interrupt Enable FLAG löschen
  rjmp 0000

Und plötzlich funktioniert die Abarbeitung der Start-Prozedur in der
gewohnt schnellen Zeit.


Liegt die Ursache für die Programm-Verzögerung bei den noch aktivierten
Interrupts?

Danke


Bernhard
#333632
Lesenswert?

Vor einem Neustart empfiehlt es sich, die komplette MCU in einen
definierten Zustand zu bringen. Den Controller einfach den Codeanfang
zu zeigen führt zwangsläuftig zu Problemen.

Ich empfehle den Watchdog-Reset. (Bit3 im WDTCR setzen und einfach in
eine Endlosschleife treten).
OP #333633
Lesenswert?

@Niels

>Ich empfehle den Watchdog-Reset. (Bit3 im WDTCR setzen und einfach in
>eine Endlosschleife treten).

Gute Idee, aber dann dann bleibt das (Bit3-WDTCR im MCUCSR gesetzt)

und das MCUCSR-Register soll bei Programmstart nicht glöscht werden,

denn ich möchte bei einem Programm-Absturz die Ursache des Absturzes
erfahren (BO/PO/WD/EXT).

Mein GPS-Projekt ist sehr komplex, bei Tests unterwegs auf dem Fahrrad
kam es mehrfach zu Neustarts.

War es nur ein Problem der Stromversorgung, oder habe ich noch einen
BUG in der Berechnung.

Bernhard
#333634
Lesenswert?

Moment, jetzt verstehe ich die Problematik nicht.

Zuerst sagst du, das du den MCU an einer bestimmten Stelle resetten
möchtest, und postest einen Codeschnipsel, der das MCUCSR löscht und
zum Speicheranfang springt. (das das nicht ordnungsgemäss funktionieren
kann, sollte eigentlich jedem klar sein)

Jetzt sagst du, das du nicht möchtest, das das MCUCSR gelöscht wird?!
OP #333635
Lesenswert?

>Jetzt sagst du, das du nicht möchtest, das das MCUCSR gelöscht wird?!

Das MCUCSR soll bei einem normalen Programmstart, z.B. einschalten des
Gerätes, nicht gelöscht werden.

Das MCUCSR soll nur im o.g. Codeschnipsel gelöscht werden und
anschließend soll ein SOFTWARE-Neustart erfolgen.

Bernhard
Gast #333636
Lesenswert?

Grenze den Fehler doch einmal ein, indem Du das SEI bei der
Initialisierung immer weiter nach vorne holst. Vermutlich wird der
Start ja auch so langsam sein, wenn Du gleich mit SEI anfängst, oder?
Vielleicht gibt es da einen Zwischenzustand in der Initialisierung, in
dem z.B. der RX als Digitaleingang mit Interrupt funktioniert oder so
etwas. Den findest Du auf diese Art.

Hat die Sache für Dich denn noch praktische Gründe (d.h. Du willst die
Interrupts beim Reset gerne aktiv lassen?) oder geht es Dir nur um das
beruhigende Gefühl, den Controller ganz zu verstehen?
#333637
Lesenswert?

Ein Programmneustart durch einen Sprung nach 0000 funktioniert aber
nunmal nicht, da flags- und steuerregister keinen definierten zustand
haben und in deinen initialisierungsroutine wahrscheinlich etliches
schiefläuft.

Nochmal:
Wenn du an einer bestimmten stelle im Code neustarten willst, empfielt
es sich, den Watchdog gezielt den Chip resetten zu lassen. Dadurch
wird, wie gewünscht, MCUCSR gelöscht und an den Codeanfang gesprungen.
OP #333638
Lesenswert?

@Philipp

>Grenze den Fehler doch einmal ein, indem Du das SEI bei der
>Initialisierung immer weiter nach vorne holst. Vermutlich wird der
>Start ja auch so langsam sein, wenn Du gleich mit SEI anfängst, oder?

Habe SEI mal an 1. STELLE gesetzt, Du hast Recht, da läuft das Programm
mit dem gleichen Fehler(alles dauert ziemlich lange) ab.

Danke für den Tipp :)


>Vielleicht gibt es da einen Zwischenzustand in der Initialisierung,
>indem z.B. der RX als Digitaleingang mit Interrupt funktioniert oder
>so etwas. Den findest Du auf diese Art.

Der USART-Interrupt verlangsamt, warum auch immer, sind sicherlich auch
undefinierte Zustände dabei, den Programm-Ablauf extrem.


>Hat die Sache für Dich denn noch praktische Gründe (d.h. Du willst
>die Interrupts beim Reset gerne aktiv lassen?)

Die Interrupts können/müssen beim SOFTWARE-RESET deaktiviert werden, da
erst alles in eine definierte Start-Position gebracht werden muss.

>oder geht es Dir nur
>um das beruhigende Gefühl, den Controller ganz zu verstehen?

Bei solchen komplexen Programmen untersuche ich gerne Anomalien, denn
diese können verheerende Auswirkungen haben, wenn man sie nicht
ergründet.

----------------------------------------------------------------

@Niels

>Ein Programmneustart durch einen Sprung nach 0000 funktioniert aber
>nunmal nicht, da flags- und steuerregister keinen definierten zustand
>haben und in deinen initialisierungsroutine wahrscheinlich etliches
>schiefläuft.

Ich gebe Dir nur zum Teil Recht, mit "rjmp 0" kann unter normalen
umständen ein Software-Reset durchgeführt werden, aber wenn sich
gewisse Steuerregister durch Elektro-Smog verrstellt haben
(z.B. OSCAL) könnte man Probleme bekommen.

Also "rjmp 0" ist mit Vorsicht zu genießen.

Man müsste alle Register beim Start in einen definierten Zustand
bringen, auch diese, die man im eigentlichen Programm nicht benötigt
(z.B. SPI oder TWI)
Der Aufwand hierfür wäre sehr umfangreich (ca. 100 Register)


>Nochmal:
>Wenn du an einer bestimmten stelle im Code neustarten willst,
>empfielt es sich, den Watchdog gezielt den Chip resetten zu lassen.
>Dadurch wird, wie gewünscht, MCUCSR gelöscht und an den Codeanfang
>gesprungen.

Ist eine sehr gute Idee, ich denke schon die ganze Zeit darüber nach,
weil dieses Verfahren viele Vorteile zeigt, alle Steuer-Register werden
definiert zurückgesetzt.

Aber

Ich möchte gern wissen, ob der µC durch einen WD-Reset neu gestartet
worden ist. (z.B. Berechnungen dauern zu lange)

Wenn ich mein Programm in eine Endlos-Schleife schicke, ohne "WDR",
dann wird gnadenlos der WD-Reset nach einigen Sekunden durchgeführt

und

WDRF-Bit wird gesetzt und bleibt auch gesetzt.


Man könnte natürlich vorher, bevor man den WD zubeissen lässt,
den µC sagen (im EEPROM diese Info hinterlegen), dass jetzt ein
WD-Reset bewusst durchgeführt wird.

Wäre doch eine Idee, oder?


Bernhard
#333639
Lesenswert?

> Man könnte natürlich vorher, bevor man den WD zubeissen lässt,
> den µC sagen (im EEPROM diese Info hinterlegen), dass jetzt ein
> WD-Reset bewusst durchgeführt wird.

Dazu brauchst du kein EEPROM, da reicht sogar eine SRAM-Zelle. Da
kannst du auch vor Berechnungen eine Art Status-Byte hinterlegen,
welches eim Reset bzw. durch dein Benutzermenü am Display angezeigt
werden könnte. - Prima Debug-Feature...

...

@Admin:
Danke für das Feature zur Rettung des Textes!!
OP #333640
Lesenswert?

@HanneS

Schön, wieder mal was von Dir zu lesen :)

>Dazu brauchst du kein EEPROM, da reicht sogar eine SRAM-Zelle. Da
>kannst du auch vor Berechnungen eine Art Status-Byte hinterlegen

Gute Idee, um den EEPROM zu schonen, denn der SRAM wird bei "rjmp 0"
nicht angetastet.

Eigentlich könnte man auch ein Register, z.B R0 für den gleichen Zweck
verwenden? Denn es wird ebenfalls nicht standart-mäßig durch "rjmp 0"
verändert.

Bernhard
Gast #333641
Lesenswert?

"Man könnte natürlich vorher, bevor man den WD zubeissen lässt,
den µC sagen (im EEPROM diese Info hinterlegen), dass jetzt ein
WD-Reset bewusst durchgeführt wird."


Man könnte das PORF-Bit setzen, ist es mit dem WDRF gesetzt, dann war
es ein absichtlicher WD-Reset.

Bei einem echten Power on wird ja das PORF gesetzt und das WDRF
gelöscht.


Peter
OP #333642
Lesenswert?

@Peter

>Man könnte das PORF-Bit setzen, ist es mit dem WDRF gesetzt, dann war
>es ein absichtlicher WD-Reset.

Gute Idee

>Bei einem echten Power on wird ja das PORF gesetzt und das WDRF
>gelöscht.

was ist ein "echten Power on" ?
Wie kann man erreichen, das PORF-BIT gesetzt wird?
(ich meine nicht mit SBI...)


Habe gerade meiner Schaltung die Betriebsspannung verweigert:
     ===>BORF-BIT gesetzt

Nach betätigen der RESET-TASTE:
     ===>EXTRF-BIT gesetzt



Bernhard
Gast #333644
Lesenswert?

>Ich glaube die Reset-Flags kann man nur loeschen, nicht setzen.
Deswegen bin ich der Kirche abgeneigt... die glauben auch immer
Sachen...

Seite 39 im Datenblatt, Register MCUCR: Sämtliche Bits sind R/W.
MCUCR wird auf Seite 31 auch noch behandelt.
Gast #333646
Lesenswert?

Atmega8515: Seite 49 im Datenblatt.

[OT]
Ich nenn mich jetzt nur noch "88issmeineOma"...
[/OT]


Wenn man sich dann den "Balken" anguckt, in dem die Bits markiert
sind, dann steht links darunter "read/write" und unter dem jeweiligen
bit "R/W", was soviel bedeutet, dass das Bit auch beschreibbar ist.
Es gibt auch Bits, die nur lesbar sind, weiß jetzt aber keine ausm
Kopf.
OP #333649
Lesenswert?

@ALLE

Danke für die Zahlreichen Antworten und Hilfestellungen.


Wie würdet Ihr Euch folgendes erklären:

Die µC-Schaltung wird durch AKKU-Betrieb gestartet:   PORF-gesetzt

Die Schaltung wird durch NETZ-BETRIEB gestartet: BORF und PORF


Ich vermute, der Spannungsanstieg ist im Akku-Betrieb steiler, daher
der Unterschied?


Am RESET-PIN befindet sich ein Elko (10µ) gegen GND und ein Widerstand
4,7k gegen +5V.

Warum löst diese RC-Kombination keinen EXTRF im MCUCSR-Register beim
Einschalten der Schaltung aus?

Bernhard
Gast #333651
Lesenswert?

Nur die ersten 32 Ports sind bitadressierbar (SBI,CBI,SBIS,SBIC).

Das sollte auch funktionieren ist aber keine echte Alternative:

  lds temp,MCUCSR+32
  cbr temp,1
  sts MCUCSR+32,temp


Gruss Thomas
Gast #333652
Lesenswert?

wie wärs mit rjmp reset bzw. rjmp 0x00 dann wäre es etwas
übersichtlicher;
schönere alternative:
wenn du den resetpin per Outbefehl umschaltest dann hättest du die
gesammte chipinterne resetprozedur ausgeführt und müsstest nicht noch
davor in irgenwelchen registern etwas herumstellen, somit kannst du
dann gleich evtl. peripherie reseten; ---> Vorteile^n
#333653
Lesenswert?

> schönere alternative:
> wenn du den resetpin per Outbefehl umschaltest dann hättest du die
> gesammte chipinterne resetprozedur ausgeführt und müsstest nicht
> noch
> davor in irgenwelchen registern etwas herumstellen, somit kannst du
> dann gleich evtl. peripherie reseten; ---> Vorteile^n

Hast du das schonmal praktisch gemacht? Wenn ja, dann berichte mal
Einzelheiten...

...
Gast #333654
Lesenswert?

Was vorstellbar ist, ist den Resetpin (über einen Widerstand) mit einem
anderen Portpin zu verbinden, der dann per "Out" den Reset auf Low
zieht und somit den Prozi resetet, aber was bringt das gegenüber der
Watchdog-Version?!
OP #333655
Lesenswert?

@uli

>wie wärs mit rjmp reset bzw. rjmp 0x00 dann wäre es etwas
>übersichtlicher;


rjmp 0x00 =  rjmp reset = rjmp 0 = rjmp 0000

Ist nach meiner Meinung kein Unterschied, nur die Schreibweise ist
anders

>wenn du den resetpin per Outbefehl umschaltest dann hättest du die
>gesammte chipinterne resetprozedur ausgeführt

Ist auch eine mögliche Variante, aber ein zusätzlicher PIN wird
benötigt


@TravelRec

>der dann per "Out" den Reset auf Low
>zieht und somit den Prozi resetet, aber was bringt das gegenüber der
>Watchdog-Version?!

Deine Frage ist berechtigt, das Ergebnis ist absolut das gleiche, nur
der Hardware-Aufwand ist unterschidelich.


Bernhard

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren