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
> 'clt temp'? was soll das bewirken? clt hat keine Operanden...
sorry, hatte mich vertippt, muss natürlich heißen:
clr temp
Bernhard
>Ach, und ich glaube, die Betreffzeile ist a bissl lang geraten...
Habe es auch gerade bemerkt, wenn man antworte möchte, muss man vorher
ein paar Zeichen aus der Betreffzeile löschen.
Bernhard
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).
@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
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?!
>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
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?
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.
@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
> 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!!
@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
"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
@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
Ich glaube die Reset-Flags kann man nur loeschen, nicht setzen. Gruss Thomas
>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.
Das Datenblatt hab ich auch gelesen, wo steht das sich die Bits setzen lassen ? Ich hatte noch keinen Mega8, beim Mega8515 geht es definitiv nicht. Gruss Thomas
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.
Bit 5 des MCUCR ist nur lesbar. (fällt einem natürlich erst auf, nachdem man den Beitrag abgschickt hat...)
Die Bits sind beschreibbar, aber nur von 1 auf 0. Gruss Thomas
@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
Ich wollte gerade mal nur das PORF-BIT löschen cbi MCUCSR,0 geht nicht !! so funktionierts: in temp, MCUCSR andi temp, 0b11111110 out MCUCSR,temp Gibt es noch weitere Möglichkeiten? Bernhard
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
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
> 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... ...
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?!
@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
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.