www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Fehlermöglichkeiten in diesem Code


Autor: mr.chip (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Der folgende Code (von C aufgerufene Assembler-Routine) lässt offenbar 
meinen AVR abstürzen. Ich sehe aber trotz intensiver Analyse _keine 
einzige Möglichkeit_, wie dies geschehen könnte.

Sieht hier irgend jemand eine Möglichkeit, wann der Controller abstürzen 
könnte? VRAM und VRAM_SIZE sind Pointer bzw. Grössenangaben für ein 
Array. Die Werte sind so korrekt und funktionieren auch.
// clearscreen
.global clearscreen
.func clearscreen

clearscreen:

push ZL
push ZH
push TMPL
push TMPH

ldi ZL, lo8(VRAM)
ldi ZH, hi8(VRAM)

ldi TMPL, 0b00000000;
ldi TMPH, hi8(VRAM + VRAM_SIZE)

clearscreen_loop:
;mov TMPL, ZL
;andi TMPL, 0b00000001
;ld TMPL, Z
st Z+, TMPL
cpi ZL, lo8(VRAM + VRAM_SIZE)
cpc ZH, TMPH
brne clearscreen_loop

pop TMPH
pop TMPL
pop ZH
pop ZL

ret

.endfunc

Gruss

Michael

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktionierts denn, wenn Du alle Zeilen dieser Routine (außer das "ret" 
am Schluss - klar) auskommentierst?  Ja?  Und was ist, wenn Du die push- 
und pop-Zeilen zuläßt?  Läufts dann auch noch?  Wenn dem so ist, 
aktivier die vier "ldi"-Zeilen nach den "push"-Zeilen.  Es funzt 
weiterhin?  Dann hast Du den Fehler auf die vier Zeilen der 
"clearscreen_loop"-Schleife eingegrenzt.

Ach so: Wenn es schon "vorher" nicht funktioniert, z. B. sobald Du die 
push- und pop-Zeilen zuläßt, solltest Du überprüfen, ob Du evtl. 
Interruptroutinen hast, die die in "clearscreen" benutzten Register 
verändern.  Das wäre eine mögliche Ursache für Deinen "unerklärlichen" 
Fehler.

Viel Erfolg :-).

Autor: mr.chip (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Jetzt ist einiges klar:

Die Schleife schreibt irgendwo in den Speicher, wo sie nicht sollte. 
Ersetze ich die st Anweisung durch eine ld Anweisung, dann stürzt nix 
mehr ab. Könnte es sein, dass der Compiler in den Speicherbereich meines 
Arrays noch eine andere Variable platziert, obwohl ich das Array im 
C-File korrekt deklariert habe?

Gruss

Michael

Autor: Bernhard S. (bernhard)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
clearscreen:

push ZL                        ; Hilfsregister sichern
push ZH
push TMPL
push TMPH

ldi ZL, lo8(VRAM)               ; Z-Zeiger initialisieren
ldi ZH, hi8(VRAM)

ldi TMPL,0                      ; Hilfsregister auf 0

clearscreen_loop:

st Z+, TMPL                      ; TMPL in Z schreiben Z+1

cpi ZH, hi8(VRAM + VRAM_SIZE)    ; vergleich H-Byte
brne clearscreen_loop            ; ist nicht gleich ==> SPRUNG

cpi ZL, lo8(VRAM + VRAM_SIZE)    ; vergleich L-Byte
brne clearscreen_loop            ; ist nicht gleich ==> SPRUNG


pop TMPH                          ; Hilfsregister wieder herstellen
pop TMPL
pop ZH
pop ZL

ret




Müsste so funktionieren


Bernhard

Autor: mr.chip (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Danke für eure Antworten.

Der Fehler liegt nicht wirklich in diesem Code. Das Problem ist 
folgendes: Ich habe einen Interrupt, der jeweils 32 mal in kurzer Zeit 
aufgerufen wird. Nach diesen 32 aufrufen folgt eine längere Pause, 
während der Funktionen wie die obige ausgeführt werden. Nun gibt es aber 
offensichtlich ein Problem, diese Funktion mit den Interrupts zu 
koordinieren, d.h. die Funktion rutscht irgendwie zwischen die 
Interrupts.

Eigentlich habe ich ja einen Zähler, der jeden Interrupt zählt und nach 
dem 32. ein Flag setzt, welches die Hauptschleife veranlasst, obige 
Funktion auszurufen, doch scheinbar kann die Funktion auch schonmal 
zwischen den Interrupts kommen. Ist Gegenstand der Untersuchung ;-)

Gruss

Michael

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas... Stell Dir mal vor, Du hättest einen Interrupt, der von 
"außerhalb des µC" zu völlig unvorhersehbaren Zeitpunkten ausgelöst 
wird, so dass es unmöglich wäre, irgendetwas in Deinem Programm mit 
diesem Interrupt zu "koordinieren"... Was meinst Du dazu? lach

Wodurch werden Deine Interrupts denn auf so seltsame Weise ausgelöst?

Autor: mr.chip (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wodurch werden Deine Interrupts denn auf so seltsame Weise ausgelöst?

Von einem zweiten Controller, der diese 32 Interrupts alle 40 ms auslöst 
um Daten zu übertragen. Da die Controller synchron laufen, geht sowas 
eigentlich schon. Nur sollte man nicht zu blöd dazu sein, die 
Rechenarbeit in die Interrupt-Pause zu legen.

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zweiter synchron laufender Controller... Aha... Na dann mal noch viel 
Spaß und Erfolg :-)

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.