Hallo an Alle, nach einem Reset soll meine Software nach der Reset-Ursache schauen (watchdog, brown-out, extern oder powerup) und je nach Ursache z.B. die section init_4 überspringen. Nur bei Powerup und brown-out sollen die Variablen neu initialisiert werden. Wer weiß Rat? Klemens
Ich hab es dann doch hinbekommen: die Konstruktion hinter dem "goto" ist ja schon "kniffelig" :-)
1 | void __attribute__ ((naked, section (".init_3"))) _my_init_3 ( void ); |
2 | void __attribute__ ((naked, section (".init_5"))) _my_init_5 ( void ); |
3 | |
4 | void _my_init_3 ( void ) |
5 | {
|
6 | if ( MCUSR & ( (1<<WDRF) + (1<<EXTRF) ) ) |
7 | goto *((void **)) _my_init5); |
8 | }
|
9 | |
10 | .init4 <hier werden die Variablen vom Flash in Ram kopiert> |
11 | |
12 | void _my_init_5 ( void ) |
13 | {
|
14 | <hier geht es mit meinem Code weiter> |
15 | }
|
Du hättest lieber die entsprechenden Variablen in die section ".noinit" legen und diese dann beim Power-On-Reset manuell initialisieren sollen. Dein Code hat übrigens noch einen grundlegenden Fehler: MCUSR wird nicht wieder gelöscht. Damit würde nach einem vorangegangenen Extern-Reset und jetzt neu hinzugekommenen Brown-Out-Reset (nach dem ja die RAM-Daten nicht mehr verlässlich sind) die Initialisierung beispielsweise trotzdem noch übersprungen. Noch schlimmer: beim "neuen" Watchdog (der, der auch im Interrupt-Modus arbeiten kann) lässt sich der Watchdog anschließend nicht mehr deaktivieren und schlägt aller 15 ms immer wieder zu.
Beim regulären Einschalten sollen ja alle Variablen initialisiert werden. Bei Watchdog oder externen Reset will ich die Variablen auslesen können. Na gut - viele Wege führen nach Rom. ich wollte es halt so lösen. Klemens
Jörg Wunsch schrieb: > MCUSR wird nicht wieder gelöscht. [...] > lässt sich der Watchdog anschließend nicht mehr deaktivieren und > schlägt aller 15 ms immer wieder zu. Okay, das ändere ich noch. :-)
Es genügt folgendes:
1 | #include <avr/io.h> |
2 | |
3 | uint8_t mcusr __attribute__((section (".noinit"))); |
4 | |
5 | static void __attribute__((section(".init3"),naked,used)) |
6 | init3 (void) |
7 | {
|
8 | mcusr = MCUSR; |
9 | MCUSR = 0; |
10 | }
|
mcusr kann dann zB in main ausgewertet werden. Beachte daß die Section nicht .init_3 heißt sondern .init3
Die .init4 wird ja vom Linker eingefügt. Mein Problem war, die .init4 bei bestimmten Bedingungen zu überspringen.
Klemens schrieb: > Die .init4 wird ja vom Linker eingefügt. Mein Problem war, die .init4 > bei bestimmten Bedingungen zu überspringen. ...um die Vorinitialisierung bestimmter globaler Variablen durch den Compiler zu unterdrücken. Und dafür hättest du auch alle betroffenen Variablen einfach als .noinit deklarieren können statt am Init-Code zu doktorn. In deiner Main() dann diese Variablen abhängig vom Startup der MCU von Hand initialisieren. Gruß hagen
Hagen Re schrieb: > In deiner Main() dann diese Variablen abhängig vom Startup der > MCU von Hand initialisieren. Geht übrigens gut zu automatisieren, indem man alle diese Daten in eine einzige .noinit-Struktur packt und dann eine entsprechende Initialwerte-Struktur in den Progmem legt, aus der die Daten bei der passenden Kombination von Reset-Flags geladen werden.
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.