Forum: Compiler & IDEs Interner Reset?


von Ralf Krapf (Gast)


Lesenswert?

Hallo,

Der Code auf meinem AT90s2313 sieht prinzipiell so aus:

int main (void) {
init ();
do {
//tut was
} while (1);
}

Anzunehmen ist nun, dass die do/while Schleife immer wiederholt wird,
während die init-Funktion nur einmal aufgerufen wird (Abgesehen vom
timerintrrupt). Nun führt der uc allerdings die init-Funktion in
unregelmässigen Zeitabständen aus (.5 - 10s). Das riecht schwer nach
unbeabsichtigtem Reset, doch sehe ich mit KO keine Änderung des
Reset-Pins. Den Watchdog timer habe ich ausgeschaltet. Kann mir da
jemand weiterhelfen?

Gruss Ralf

von Peter (Gast)


Lesenswert?

naja, da der rest nich dasteht:
hast du die möglichen interruptfälle abgedeckt?selbst wenn nur dasteht
SIGNAL(SIG_OVEFLOW0)
{
}
und signal.h miteinbinden

gruß
peter

von OldBug (Gast)


Lesenswert?

Es gibt einen Handler für unerwartete Interrupts, das sollte also nicht
das Problem sein...

von Jörg Wunsch (Gast)


Lesenswert?

Der macht aber einen jmp 0.

von OldBug (Gast)


Lesenswert?

Worauf ich damit hinaus wollte: gerade weil es diesen Handler gibt,
braucht man nicht die ganzen Deklarationen für jeden möglichen oder
unmöglichen Interrupt im Source vorzuhalten.

Benötigt man keinen Interrupt, dann braucht man auch die avr/signal.h
nicht. Allerdings darf man dann auch kein GIE-Flag setzen.

von Peter (Gast)


Lesenswert?

Hi,
vielleicht sollte Ralf mal den gesamten Code posten. Er erwähnte einen
Timerinterrupt und, falls er den außer Acht lässt, resetet das Ding aus
Verzweiflung, weil es nicht weiß wohin mit sich....oder irr ich mich?
Bin ja auch noch ein Greenhorn ;)

von Jörg Wunsch (Gast)


Lesenswert?

Ich vermute, es wird das übliche Problem werden: Schreibfehler im
Namen des Vektors.

von Ralf Krapf (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Danke für die vielen Antworten!
Ich sende mal den Code als Anhang - vielleicht seht ihr dann mehr...

von Reinhard Biegel (Gast)


Lesenswert?

Hi!

Kann es sein, dass der Compiler das 'do {...} while(1);' wegoptimiert
und der µC den Inhalt des kompletten Code-Speichers ausführt? Verwendet
man nicht überlicherweise 'while(1){...}' ?

mfg
Reinhard

von Jörg Wunsch (Gast)


Lesenswert?

Das wäre ein Bug, wenn er das wegoptimieren würde.

von Reinhard Biegel (Gast)


Lesenswert?

Wieso ein Bug?

AFAIK is es bei den 8051er Compilern so... warum also nicht auch beim
avr-gcc?

mfg

von Jörg Wunsch (Gast)


Lesenswert?

Auch wenn es bei den 8051er Compilern tatsächlich so sein sollte,
ändert das nichts daran, daß es ein Bug wäre.

do { ... } while (1); besagt eindeutig, daß der Block in einer
Endlosschleife auszuführen ist, genauso wie while(1) { ... } oder
for (;;) { }.

Wegoptimiert darf da höchstens dann was werden, wenn in der Schleife
effektiv nichts passiert.  Also für

do {
  /* nix */
} while (1);

muß der Compiler keinen Code erzeugen, auch nicht für

int
main(void)
{
  int foo;

  do {
    foo++;
  } while (1);
}

(das Ergebnis von `foo' kann nirgends mehr benutzt werden), wohl aber
für

int foo;
extern int foobar(void);

int
main(void)
{

  do {
    foo++;
    foobar();
  } while (1);

}

da hier für den Compiler nicht ersichtlich ist, daß die externe
Funktion foobar() keinerlei Seiteneffekte bezüglich foo hat.

von Ralf Krapf (Gast)


Angehängte Dateien:

Lesenswert?

Momentan habichs mit Optimierungsstufe 's' compiliert. Mit Stufe 1,2,3
geschieht dasselbe. Der Stufe 0 - Code ist zu gross für den uc.
Mit der 'while(1){...}' Methode dasselbe.
Die compilierte Hex-Datei der mainfkt. mit Stufe 's' und
'while(1){...}' ist im Anhang - vielleicht seht ihr etwas...

von Ralf Krapf (Gast)


Lesenswert?

Ich glaub, ich hab das Problem gelöst!

Es war tatsächlich kein softwarproblem -> einfach ein 1uF C direkt in
die Speisung des uC und nun gehts ohne Probleme. Die Spannung schwankte
vorher scheinbar genug stark, dass der uC einen Reset auslösste...

Danke für die vielen Antworten!

von Jörg Wunsch (Gast)


Lesenswert?

OK, nun kannst Du Dich zum Abschluß auch noch hinsetzen und all die
seit 2 Jahren schon veralteten inp/outp/sbi/cbi rauswerfen.  Teilweise
wie hier:

  if (USR & 0x18)

hast Du ja schon neue Syntax benutzt, warum dann nicht überall?

In der nächsten `major' Version der avr-libc wird sich Dein Code
sonst
nicht mehr compilieren lassen -- auf dem avr-libc-1.1er Arbeitsstand
schon jetzt nicht mehr.  Da ich bei mir diesen Arbeitsstand fahre,
werde ich notgedrungen auch irgendwann aufhören, Anfragen für Code,
den ich nicht mehr compilieren kann, zu beantworten.

von Ralf Krapf (Gast)


Lesenswert?

Tut mir leid, das war mir bis jetzt nicht bewusst. Ist das hier
beschrieben? http://jubal.westnet.com/AVR/doc/avr-libc-user-manual/

Vermutlich bin ich zu blöd, aber wie sieht denn z.B. die neue Syntax
für cbi(x,y) aus?

von Reinhard Biegel (Gast)


Lesenswert?

@Jörg:

Sorry, hab das '//tut was' im 1. Post übersehen....

mfg

von Jörg Wunsch (Gast)


Lesenswert?

Naja, jubal.westnet.com war ein temporärer Standort.  Wo geistert die
URL denn noch herum?  Ich weiß nicht, ob die noch aktuell gehalten
wird.  Offiziell ist

http://www.nongnu.org/avr-libc/user-manual/index.html

Beschrieben ist das soweit dort schon, insbesondere sind die alten
Makros auch allesamt als `deprecated' markiert.

Die Syntax für cbi(x, y) sieht in Standard-C so aus:

x = x & ~(1 << y);

oder kurz

x &= ~(1 << y);

Sollte in jedem besseren C-Lehrbuch stehen. ;-) Der cbi-Makro macht
übrigens exakt das (insbesondere garantiert er Dir eben nicht, daß
auch wirklich ein CBI herauskommt).

Mit eingeschaltetem Optimierer und passenden Operanden kommt aber
am Ende ein CBI heraus.

Da der Konstrukt (1 << y) sehr häufig benöigt wird, bietet die
avr-libc dafür den Makro _BV().  Du kannst das also auch als

x &= ~_BV(y);

schreiben.

von Lutz Müller (Gast)


Lesenswert?

Hallo,

saublöde Anfängerfrage: Kann man statt

x = x & ~(1 << y);

nicht einfach

x = (0 << y);

schreiben? Dann würd´s mir viiiiiiel leichter verständlich werden.

Gruß

Lutz

von Mike (Gast)


Lesenswert?

Kannst du nicht! Das siehst du, wenn du dir einmal die einzelnen Schrite
des Befehls ansiehst.

(1<<y)  ->  Schiebt eine 1 an die Stelle y
~( )    ->  An der Stelle y steht eine 0 an allen anderen eine 1
x &     ->  Und-Verknüpfung

bei deiner Lösung würdest du eine 0 an die Stelle y schieben und dann
x den den Inhalt 0%00000000 zuweisen. Damit wären alle gelöscht.
Und selbst mit einen x &= (0<<y) würdest du alles löschen, weil 0 und
irgendwas immer noch 0 ist.

Mike

von Lutz Müller (Gast)


Lesenswert?

Danke Mike,

Du hast recht, das ist nachvollziehbar. Würde dann eine
ODER-Verknüpfung gehen wie

x |= (0<<y);

Wenn ich mich nicht wieder vertue (was leider sehr gut sein kann), dann
bleiben die anderen Bits des Registers so wie sie sind (Wenn vorher eine
1 war: 1 ODER 0 = 1, wenn vorher eine 0 war: 0 ODER 0 = 0)und das Bit y
wird durch das Bit-Shift auch 0. Wenn ich das jetzt nicht mit Java
vermixe, dann wird doch erst der rechte Wert errechnet und dann dem
linken zugewiesen. Oder ist die Reihenfolge doch anders, dann kann das
gerade geschriebene natürlich Quatsch sein.

Ich hoffe, daß ich mich jetzt nicht gerade restlos blamiert habe!

Gruß
Lutz

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Wenn du eine 0 um y Stellen verschiebst und den Rest mit Nullen
auffüllst, was kommt dann raus? Eine Null. Und etwas mit Null zu
verODERn ist nicht sinnvoll ;)

von Jörg Wunsch (Gast)


Lesenswert?

Ein bißchen hast Du das schon. ;-)

Der indirekte Beweis ist hier wohl einfacher.  Der Ausdruck "(0 <<
y)"
ergibt schlicht eine 0, mithin könntest Du gleich "0" schreiben.
Wenn
Du nun einen beliebigen Wert ODER 0 hast, kommt wieder der Wert selbst
heraus, ergo ist das nicht, was Du haben wolltest.

von Lutz Müller (Gast)


Lesenswert?

Besten Dank, so leuchtet´s ein und auch ich kann´s mir merken.

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.