Forum: Mikrocontroller und Digitale Elektronik problem mit wdt zurücksetzen


von Vlad T. (vlad_tepesch)


Lesenswert?

Hi,
Ich finde den Fehler nicht:

Ich benutze einen WDT zum resetten des Mega328.
Das funktioniert soweit.

Allerdings funktioniert das zurücksetzen des WDT am Systemstart nicht.
(WinAVR 20090313)
1
/** deactivates the watch dog timer as soon as possible in Program flow */
2
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init1")));
3
void wdt_init(void)
4
{
5
    MCUSR = 0;
6
    wdt_disable();
7
    return;
8
}

wenn man ins Mapfile schaut, ist das init1-segment leer.
Auch ist der Code gleich groß, egal, ob das ding drin ist, oder nicht.

Hat jemand einen vorschlag?

Danke im Voraus

von holger (Gast)


Lesenswert?

>Hat jemand einen vorschlag?

Setz deinen Kram an den Anfang von main() ?

von Vlad T. (vlad_tepesch)


Lesenswert?

holger schrieb:
> Setz deinen Kram an den Anfang von main() ?

naja, der Code soll ja vor den ganze inits der CRT ausgeführt werden.


EDIT:
ich hab das genau so auch schon in anderen Projekten benutzt.

von holger (Gast)


Lesenswert?

>naja, der Code soll ja vor den ganze inits der CRT ausgeführt werden.

Warum?

von Josef D. (jogedua)


Lesenswert?


von Vlad T. (vlad_tepesch)


Lesenswert?

holger schrieb:
> Warum?

damits keine endlosresetschleife gibt, wenn der initcode länger dauert 
als ein wdt-Zyklus

von Josef D. (jogedua)


Lesenswert?

so habe ich's bei mir am laufen

1
static void WDT_off(void){
2
  cli();               // __disable_interrupt();
3
  wdt_reset();          //__watchdog_reset();
4
  /* Clear WDRF in MCUSR */
5
  MCUSR &= ~(1<<WDRF);
6
  /* Write logical one to WDCE and WDE */
7
  /* Keep old prescaler setting to prevent unintentional time-out */
8
  WDTCSR |= (1<<WDCE) | (1<<WDE);
9
  /* Turn off WDT */
10
  WDTCSR = 0x00;
11
  // sei();             //__enable_interrupt();
12
}
13
14
// s. http://www.rn-wissen.de/index.php/Avr-gcc/Interna#Frühe_Codeausführung_vor_main.28.29
15
/* Kopie daraus:
16
.init2
17
    Initialisieren von R1 mit 0 und setzen des Stackpointers
18
.init4
19
    Kopieren der Daten vom Flash ins SRAM (.data) und löschen von .bss
20
.init6
21
    C++ Konstruktoren
22
.init9
23
    Sprung zu main
24
*/
25
void code_init3() __attribute__ ((naked, section (".init3")));
26
// !!! never call this function !!!
27
void code_init3 (void){
28
  WDT_off();
29
  // Code...
30
}

von holger (Gast)


Lesenswert?

>> Warum?

>damits keine endlosresetschleife gibt, wenn der initcode länger dauert
>als ein wdt-Zyklus

Hä?

Was hast du denn noch so alles in deinem initcode?

von Vlad T. (vlad_tepesch)


Lesenswert?

Josef D. schrieb:
> ist hier gut beschrieben:
>
> "http://www.rn-wissen.de/index.php/Avr-gcc/Interna#...

danke für den Link.

es funktioniert mit keiner der verschiedenen Varianten:
1
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init1")));
2
void wdt_init(void) __attribute__((naked, section(".init1")));
3
4
void __attribute__((naked, section(".init1"))) wdt_init(void);

von Josef D. (jogedua)


Lesenswert?

init3 ?

von g457 (Gast)


Lesenswert?

> __attribute__((section(".init1")));
                          ^^^^^^

Wenn ich das richtig seh dann nutzt wdt_disable() das __zero_reg__, 
selbiges wird aber erst in .init2 gesetzt. Verschieb den Köter doch mal 
in .init3 zum testen.

HTH

von Vlad T. (vlad_tepesch)


Lesenswert?

Josef D. schrieb:
> init3 ?

an dem segment selbst kanns ja nicht liegen, dann würde es 
möglicherweise in init1 liegen, aber nicht funktioniernen.

von Vlad T. (vlad_tepesch)


Lesenswert?

ARGHHHH

Ich geh kaputt.
die whole-program-optimization optimiert das weg!!!
schalte ich die ab, liegts im spezifiziertem segment.

nur ist der Code jetzt auch ein ganzes Stück größer.

hat jemand eine Idee, wie man der Optimierung verbieten kann, die 
Funktion zu entfernen?

von Josef D. (jogedua)


Lesenswert?

ich glaube mal gelesen zu haben, dass es dafür eine Link-Option gibt.
Ich finde es aber momentan nicht.

von holger (Gast)


Lesenswert?

>whole-program-optimization optimiert das weg!

Knabberst du schon an den letzen zwei Bytes Flash rum?
-O2 oder -Os tuts bei mir eigentlich immer ganz brav.

von Josef D. (jogedua)


Lesenswert?

wieviel Flash spart dir denn die Optimierung?
Wenn ich das richtig verstehe, kann es doch nur darum gehen, nicht 
verwendete Funktionen zu entfernen.
Das kann man ja immer auch per #ifdef erreichen.

Wenn das aber zu viel Arbeit sein sollte, könnte man auch den Optimizer 
überlisten, indem man einen Aufruf der gewünschten Funktion in eine 
if-Abfrage schreibt, die zur Laufzeit nie TRUE wird (aber so, dass der 
Compiler das zur Compile-Zeit noch nicht wissen kann); kostet aber 
natürlich auch ein paar Byte.

von Josef D. (jogedua)


Lesenswert?

mit der gewünschten Funktion meine ich die wdt_init(), die nicht 
wegoptimiert werden soll.

von Stefan E. (sternst)


Lesenswert?

Vlad Tepesch schrieb:
> hat jemand eine Idee, wie man der Optimierung verbieten kann, die
> Funktion zu entfernen?

Attribut "used".

von Vlad T. (vlad_tepesch)


Lesenswert?

Josef D. schrieb:
> Wenn ich das richtig verstehe, kann es doch nur darum gehen, nicht
> verwendete Funktionen zu entfernen.
> Das kann man ja immer auch per #ifdef erreichen.

naja, die whole-program-optimization macht noch mehr.
funktionen, die nur einmal genutzt werden oder sehr klein sind, werden 
geinlined, obwohl sie nicht im selben c-File oder im header stehen.

bei stark modularisierten Projekten mit strikter 
Deklaration/Code-Trennung, kann das schon ein paar kB ausmachen. und 
geschwindigkeit bringts natürlich auch, wenn der Compiler kleine 
funktionen inlined, anstatt erst zu callen und register zu retten

Momentan störts im aktuellen Projekt nicht. drauf gestoßen bin ich nur, 
da ich ein Makefile wiederverwertet habe.
deswegen werde ich das jetzt erst mal nicht weiterverfolgen.

von Uwe S. (de0508)


Lesenswert?

Hallo,

Josef D. schrieb:
> ich glaube mal gelesen zu haben, dass es dafür eine Link-Option gibt.
> Ich finde es aber momentan nicht.

ja gibt es, ich habe für eine ein Optimum der C- und Linkflags gefunden:
1
CFLAGS += -Os
2
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
3
CFLAGS += -Wall -Wstrict-prototypes
4
## Zusatz Flags
5
CFLAGS += -fno-split-wide-types 
6
CFLAGS += -fno-tree-scev-cprop
7
CFLAGS += -fno-move-loop-invariants
8
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections
9
CFLAGS += -Wl,--relax
10
## -- ende --
11
CFLAGS += -std=gnu99

Für C++ bedarf es nur einer kleinen Anpassung.

von Vlad T. (vlad_tepesch)


Lesenswert?

da is doch die wpo auch nicht dabei

--combine -fwhole-program

von Uwe S. (de0508)


Lesenswert?

Hallo Vlad!

ja richtig,
da ich auch mit C Modulen programmiere und nicht wie hier beschrieben

http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html

eine großen "C" Datei benutze in die alle Programmteile (c)#include(/c) 
wird.

von Peter D. (peda)


Lesenswert?

Vlad Tepesch schrieb:
> damits keine endlosresetschleife gibt, wenn der initcode länger dauert
> als ein wdt-Zyklus

Dazu muß man aber schon sehr großen SRAM initialisieren und ne kleine 
F_CPU setzen.
Die 2kB des 328 sind schnell genug geladen, da kann man den Wachhund 
ruhig erst im Main resetten.


Peter

von Vlad T. (vlad_tepesch)


Lesenswert?

Uwe S. schrieb:
> a richtig,
> da ich auch mit C Modulen programmiere
genau hier mach die whole-program-optimization ja Sinn.

> und nicht wie hier beschrieben
>
> http://www.tty1.net/blog/2008-04-29-avr-gcc-optimi...
wo soll das denn da stehen?
>
> eine großen "C" Datei benutze in die alle Programmteile (c)#include(/c)
> wird.
hier brauchst die wpo nicht, da es ja nur noch ein zu compilierendes 
File gibt.

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
Noch kein Account? Hier anmelden.