AVR: .init nach reset überspringen

Gast #2749367
Lesenswert?

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
Gast #2749642
Lesenswert?

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
}
Moderator Persönliche Seite #2749650
Lesenswert?

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.
Gast #2749664
Lesenswert?

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
#2750826
Lesenswert?

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
Moderator Persönliche Seite #2750849
Lesenswert?

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.

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