mikrocontroller.net

Forum: Compiler & IDEs Interner Reset?


Autor: Ralf Krapf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: OldBug (Gast)
Datum:

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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der macht aber einen jmp 0.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Jörg Wunsch (Gast)
Datum:

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

Autor: Ralf Krapf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

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

Autor: Reinhard Biegel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre ein Bug, wenn er das wegoptimieren würde.

Autor: Reinhard Biegel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso ein Bug?

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

mfg

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ralf Krapf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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...

Autor: Ralf Krapf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ralf Krapf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Reinhard Biegel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg:

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

mfg

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lutz Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lutz Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lutz Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besten Dank, so leuchtet´s ein und auch ich kann´s mir merken.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.