Hallo allerseits! Zunächst das allgemeine: Prozessor: AVR Mega168 Compiler: GNU C-Compiler Ich habe folgendes Problem: Ich möchte beim Hochlauf die Initialisierung des RAM-Bereiches UNTERDRÜCKEN. Grund: Die Schaltung läuft im Batteriebetrieb. Darum möchte ich den Controller nach Ausführung eines Programmes "Schlafen legen" (mittels SLEEP-Befehl) um wenig Strom zu verbrauchen,und diesen dann durch einen Watchdog-interrupt wieder aufwecken. Die RAM-Variablen sollten somit nach neuerlichem Anlauf erhalten bleiben. Ich nehme an, dass es dafür sicherlich einen Compilerswitch für das MAKE-File gibt. Vielleicht hat das schon jemand einmal probiert? Anbei der Code, der das RAM beim Anlauf mit 0x00 initialisiert (habe ich mit dem AVR-Studio im Singlestep herausgefunden): +0000006D: 921D ST X+,R1 Store indirect and postincrement +0000006E: 3AA9 CPI R26,0xA9 Compare with immediate +0000006F: 07B1 CPC R27,R17 Compare with carry +00000070: F7E1 BRNE PC-0x03 Branch if not equal Vielen Dank im Voraus für eventuelle Tipps und Lösungsvorschläge! Viele Grüße, Christian
Lt. Linker-Script werden data und BSS in der section .init4 inititialisiert. Mglw. funktioniert es, eine Funktion in .init3 (attribute section...) anzulegen, und von dort aus direkt main() aufzugerufen. Ist nicht "elegant" und hat sicher einige Seiteneffekte, aber vielleicht ein Ansatz. Ausserdem waere es einen Versuch wert, die nicht-zu-initialisierenden Daten in der Section .noinit anzulegen. Wenn es funktioniert, ist dies im Vergleich zum Vorschlag oben die bessere Loesung. Falls Resetquelle "echter Reset/Power-On-Reset": nicht vergessen "von Hand" zu initialisieren. Martin
Es genügt die Variablen .noinit zu deklarieren: z.B. static uint16_t count __attribute__((section(".noinit")));
Hallo Peter, Hallo Martin! Vielen Dank für die schnellen Antworten. Die Lösung mit "static uint8_t ucTest __attribute__((section(".noinit")));" funktioniert. Der RAM-Inhalt bleibt nach dem Watchdog-RESET erhalten! Für die Erst-Initialisierung habe ich mir ein Flag angelegt, das beim Programmstart auf einen bestimmten Wert abgefragt wird. Damit ist die Erst-Initialisierung auch gesichert. viele Grüße, Christian
Hallo Christian, aus einer Variable einen Reset zu erkennen halte ich für gefährlich. Denn beim einschalten könnte diese Speicherstelle ja zufällig den Wert haben, denn du abfrägst und es passiert dann keinen Initialisierung mehr. Sicherer währe es wenn du die Prozessorinternen Register abfrägst. Da gibt es eins MC??? aus dem man die Quelle vom letzten Reset auslesen kann. Gruß, Florian
Hallo Florian! Danke für den Tipp! Diese Neustartquelle kann man aus dem register "MCUSR" auslesen! So werd ich es eh machen! Am besten ists, wenn man den Hochstartgrund und dann noch ein 16-bit-value abfragt. Dann könnte (fast) nichts mehr schief gehen! (Anbei der Code, wie man den Neustart-Grund abfragen kann) viele Grüße, Christian //hochstartgrund am programmbegin per MCUSR-register abfragen: if (MCUSR & BV(WDRF)) { //grund: watchdog-reset } if (MCUSR & BV(PORF)) { //grund: power-on-reset } if (MCUSR & BV(EXTRF) { //grund: external reset } if (MCUSR & BV(BORF) { //grund: brown-out reset }
> (Anbei der Code, wie man den Neustart-Grund abfragen kann)
Nicht völlig OK. Du solltest als allererstes (vielleicht sogar in
einer .initX-section) den Inhalt von MCUSR in eine Variable übernehmen
und dieses Register danach ausnullen. Andernfalls akkumulieren die
einzelnen Bits und du hättest plötzlich ,,mehrere Reset-Gründe''. :)
Als allererstes deshalb, weil der Zeitraum bis zum Löschen des
MCU[C]SR natürlich eine race condition darstellt. Tritt innerhalb
dieser Zeit ein neuer Rest auf, hast du wirklich zwei Gründe für
Reset.
Hallo Jörg! Du hast recht. Wenn man das Register beim Hochlauf in eine Variable speichert ist es auf jeden Fall sicherer! Werde das Programm diesbezüglich umbauen. Vielen Dank! Gruß,Christian
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.