Forum: Mikrocontroller und Digitale Elektronik Wie kann ich debuggen während das Programm im Mikrocontroller lauft?


von Andy11 (Gast)


Lesenswert?

geht das überhaupt`?
wenn ja, wie kann ich das in AVR Assembler machen?

mein Programm bleibt nämlich an einer Stelle stehen und ich weiß nicht 
warum, in der Simulation lässt sich das nicht sehr gut nachvollziehen, 
da wäre es ideal wenn ich während des Betriebs schau was es da hat

lg andy

von Mh. M. (mhm)


Lesenswert?

Natürlich kannst du Debuggen wenn das Programm im µC läuft, brauchst 
eben ein geeignetes Entwicklungswerkzeug dafür (für Controller unter 
32kB Flash reicht der AVR Dragon, ansonsten eben das ICE). Oftmals ist 
sowas aber gar nicht nötig, könntest ja z.B. auch per LED oder serieller 
Ausgabe debuggen. Ist halt auch die Frage wie zeitkritisch dein Programm 
abläuft.

von nixchecker (Gast)


Lesenswert?

Du kannst dich doch Schritt für Schritt durch deinen Code steppen...da 
siehst du doch wo es hängt.

von Andy11 (Gast)


Lesenswert?

>Natürlich kannst du Debuggen wenn das Programm im µC läuft, brauchst
>eben ein geeignetes Entwicklungswerkzeug dafür (für Controller unter
>32kB Flash reicht der AVR Dragon, ansonsten eben das ICE). Oftmals ist
>sowas aber gar nicht nötig, könntest ja z.B. auch per LED oder serieller
>Ausgabe debuggen. Ist halt auch die Frage wie zeitkritisch dein Programm
>abläuft.

ich hab ne STK 500, ich vermute mal, dass das mit der auch geht aber 
wie?


>Du kannst dich doch Schritt für Schritt durch deinen Code steppen...da
>siehst du doch wo es hängt.

ist schon richtig, aber da drinnen sind auch Zeitschleifen und es würde 
ziemlich lange dauern bis er jede durch ist

von Mh. M. (mhm)


Lesenswert?

Andy11 schrieb:
> ich hab ne STK 500, ich vermute mal, dass das mit der auch geht aber
> wie?

Soweit ich weiß kann man mit dem STK500 nicht debuggen.

von nixchecker (Gast)


Lesenswert?

Na du kannst bei den Schleifen doch ans Ende der Zählschleife 
springen...bzw. einzelne Aufrufe "überspringen" (jump over) und danach 
weiter machen...klar will keiner ne Schleife von 5000 Durchgängen 
durchklicken. OK, ich benutze IAR, aber ich denke nicht, dass das bei 
anderen Compilern nicht geht.

von spess53 (Gast)


Lesenswert?

Hi

>ich hab ne STK 500, ich vermute mal, dass das mit der auch geht aber
>wie?

Nein.

>ist schon richtig, aber da drinnen sind auch Zeitschleifen und es würde
>ziemlich lange dauern bis er jede durch ist

Dann setze hinter die Schleife einen Breakpoint und lass die Simulation 
bis dahin rennen.

MfG Spess

von Chris (Gast)


Lesenswert?

Ein STK500 ist kein Debugger. Du benötigst ein Dragon oder ein JTAGICE 
mkII. Entgegen dem obigen Posting funktioniert das Dragon mittlerweile 
auch bei mehr als 32K Flash.

Bleibt noch die Frage nach deinem Controller. Manche Typen (wie z.B. der 
ATmega8) lassen sich gar nicht debuggen.

von nixchecker (Gast)


Lesenswert?

Echt? Hab die nie benutzt, aber das hätt ich mir garnicht vorstellen 
können.

von nixchecker (Gast)


Lesenswert?

Das ist doch essentiell : )

von Andy11 (Gast)


Lesenswert?

>Bleibt noch die Frage nach deinem Controller. Manche Typen (wie z.B. der
>ATmega8) lassen sich gar nicht debuggen.
ok dann vergessma mal das ganze

>Dann setze hinter die Schleife einen Breakpoint und lass die Simulation
>bis dahin rennen.
naja muss die Sim dann nicht die Stelle mit der Schelife durchgehen?
aber ok

danke mal

von nixchecker (Gast)


Lesenswert?

Ja klar geht die die dann durch.

von Andy11 (Gast)


Lesenswert?

>Ja klar geht die die dann durch.

ja aber dann war ich wieder, da hilft anscheinend nur ein überspringen 
sowie du schon gesagt hast

von nixchecker (Gast)


Lesenswert?

Nein "Jump over" ist nicht überspringen in Form von auslassen, sondern 
sie macht die Stelle durch ohne dein zutun, und hält danach an.

von nixchecker (Gast)


Lesenswert?

Andy11 schrieb:
> ja aber dann war ich wieder

Sofern das warten heisst....wie lang sind deine Schleifen?

von Andy11 (Gast)


Lesenswert?

dann hilft mir das ja in keinem fall etwas, dann muss ich halt die 
zeiten kleiner stellen oder ganz rauswerfen, denn an denen kanns ja der 
fehler nicht liegen

von spess53 (Gast)


Lesenswert?

Hi

Oder zum Debuggen die Schleifen einfach auskommentieren.

MfG Spess

von nixchecker (Gast)


Lesenswert?

Dann beschreib mal bitte genauer, wann es stehen bleibt.

von Andy11 (Gast)


Lesenswert?

>Oder zum Debuggen die Schleifen einfach auskommentieren.

jap, werd ich wohl machen

von Andy11 (Gast)


Lesenswert?

>Dann beschreib mal bitte genauer, wann es stehen bleibt.

Das Problem ist, wenn ich jetzt mit meinem coding komme, dann werd ich 
wieder niedergemacht und es wird dann einem vorgeworfen man solle sich 
selber schlau machen warum was nicht funktioniert, nicht dass ich das 
nicht schon versucht habe aber trotzdem ich halt mich diesmal wirklich 
zurück und versuch auch selber den Fehler zu finden, erst wenn ich es 
dann wirklich aufgebe werd ich wohl oder über mein coding posten und 
dann hoffen, dass da irgendeinem mal langweilig ist
ich will ja auch den fehler selber finden!

lg andy

von nixchecker (Gast)


Lesenswert?

Ich kann dich sehr gut verstehen, das ist hier leider oft so. Die, die 
es sehr viel besser wissen, die machen sich leider sehr oft mehr 
Gedanken darüber, wie sie den Anderen nieder machen können : )

Nee, aber nicht den Code...kannst du denn eingrenzen, wo dein Programm 
hängt?

von nixchecker (Gast)


Lesenswert?

Also ich kenn die Syntax vom AVR sowieso nicht, benutze die garnicht. 
Wenn du MIR das jetzt hinknallen würdest wäre ich dir da eh keine Hilfe 
:\ Aber wenn es um grundlegende Sachen im Quelltext geht, dann macht das 
keinen Unterschied.

von spess53 (Gast)


Lesenswert?

Hi

>jap, werd ich wohl machen

Die elegante Variante wäre noch:

Vor dein Programm

   .equ debug = 1

  ...
  Programm
  ...

   .if debug == 0

  Deine Schleife

   .endif

  Weiter im Programm
  ...

Wenn   .equ debug = 1 wird deine Schleife nicht assembliert
Wenn   .equ debug = 0 wird deine Schleife assembliert

MfG Spess

von nixchecker (Gast)


Lesenswert?

Der Spress hat auch immer gute Ratschläge parat!

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:
> dann hilft mir das ja in keinem fall etwas, dann muss ich halt die
> zeiten kleiner stellen oder ganz rauswerfen, denn an denen kanns ja der
> fehler nicht liegen

Würd ich nicht tun.
Damit veränderst du unter Umständen das Timing deines Programms.
Stell dir den Simulator einfach als einen µC vor, der sehr langsam 
läuft.
Wenn du den auf einen Breakpoint auflaufen lässt, dann dauert das zwar 
in Realzeit länger als wie wenn das Programm auf dem µC laufen würde, 
aber: in der Simualtion ist der komplette µC einfach nur langsamer. D.h. 
die Relationen der einzelnen Programmteile bleiben erhalten.

Ausserdem: sooooo langsam gehts dann in der Simulation auch wieder 
nicht. Breakpoint hinter die Zeitschleife und den Simulator ohne 
Benutzerinteraktion durchackern lassen, dann geht das einigermassen 
flott.

von Andy11 (Gast)


Angehängte Dateien:

Lesenswert?

>Nee, aber nicht den Code...kannst du denn eingrenzen, wo dein Programm
>hängt?

ich hab mal den Teil rausgenommen:
1
Messeschwellwert:
2
rcall  EnableADC
3
;***************************************
4
rcall  ADC_Kanal0
5
rcall    StartADC
6
        in r25, ADCH
7
8
rcall  ADC_Kanal1
9
rcall    StartADC
10
        in r26, ADCH      ;Messe alle Werte der LDRs bei weißem Untergrund
11
12
rcall  ADC_Kanal2
13
rcall    StartADC
14
        in r27, ADCH
15
;***************************************
16
17
rcall wait1        ;WARTE 1 SEK
18
19
sbi PORTB, 1
20
21
rcall wait3        ;WARTE 3 SEK
22
23
cbi PORTB, 1----------------------DAS ZEIGT ER NOCH AN
24
25
;Linker Schwellwert--------------
26
rcall  ADC_Kanal0
27
rcall    StartADC
28
        push r28
29
        clr r28
30
        in Messergebnisleft, ADCH    ;Messe Wert auf schwarz vom linken LDR
31
        add r25, Messergebnisleft    ;Summe von Wert auf Schwarz und Wert auf Weiß
32
        in r28, SREG
33
        sbrc r28, 0
34
        ldi r28, 0b10000000        
35
        mov r30, r25          ;Lade Divident in Divisionsregister r30
36
        ldi r31, 2            ;Lade Divisor in Divisionsregister r31
37
rcall      division            ;dividiere die zwei zahlen
38
        mov Schwellwertleft, Ergebnis  ;bringe errechneten Schwellwert in definierte Variable(Register)
39
        add Schwellwertleft, r28
40
        push Ergebnis          ;sichere Ergebnis
41
          
42
          mov r25, Schwellwertleft    ;da r25 in Write EEPROM zum schreiben der Variable 
43
                          ;verwendet wird muss das Register kopiert werden  
44
          ldi ZH, 0             ;niederwertige Bit der EEPROM Adresse = 0
45
          ldi ZL, 1            ;schreibe EEPROM an adresse 1
46
rcall        Write_EEPROM          ;schreibe Wert in EEPROM
47
        
48
        pop Ergebnis          ;stelle ergebnis wieder her        
49
        subi Ergebnis, 5        ;Ausschaltschwelle (Schmitttriggerfunktion)
50
        mov Linksaus, Ergebnis      ;Lade es in fixen SPeicher
51
          
52
          mov r25, Linksaus        ;da r25 in Write EEPROM zum schreiben der Variable 
53
                          ;verwendet wird muss das Register kopiert werden  
54
          ldi ZH, 0             ;niederwertige Bit der EEPROM Adresse = 0
55
          ldi ZL, 4            ;schreibe EEPROM an adresse 1
56
rcall        Write_EEPROM          ;schreibe Wert in EEPROM  
57
        pop r28
58
rcall wait1   
59
;--------------------------------
60
61
sbi PORTB, 1 --------------DA DAS NICHT MEHR ANGEZEIGT WIRD VERMUTE ICH MAL dass in der BERECHNUNG DER FEHLER LIEGT, die FRAGE ist halt wo
62
sbi PORTB, 2
63
64
rcall wait3

Anbei noch die Unterprogramme

von spess53 (Gast)


Lesenswert?

Hi

>Der Spress hat auch immer gute Ratschläge parat!

Spess bitte.

MfG Spess

von nixchecker (Gast)


Lesenswert?

OK :) Dann klink ich mich da aus, ich programmiere nur C. Sorry!

von nixchecker (Gast)


Lesenswert?

spess53 schrieb:
> Spess bitte

Sorry, verschrieben! War aber ernst gemeint! :)

von Andy11 (Gast)


Lesenswert?

nixchecker schrieb:
> Also ich kenn die Syntax vom AVR sowieso nicht, benutze die garnicht.
> Wenn du MIR das jetzt hinknallen würdest wäre ich dir da eh keine Hilfe
> :\ Aber wenn es um grundlegende Sachen im Quelltext geht, dann macht das
> keinen Unterschied.

ok war vielleicht ein bisschen zu spät als ich das gelesen habe

spess53 schrieb:
> Die elegante Variante wäre noch:
>
> Vor dein Programm
>
>    .equ debug = 1
>
>   ...
>   Programm
>   ...
>
>    .if debug == 0
>
>   Deine Schleife
>
>    .endif
>
>   Weiter im Programm
>   ...
>
> Wenn   .equ debug = 1 wird deine Schleife nicht assembliert
> Wenn   .equ debug = 0 wird deine Schleife assembliert

ist vielleicht auch wirklich die elegantere Methode, jedoch habe ich 
keine ahnung von .equ
mir können die schleifen eigentlich wurscht sein, da sie sowieso nur 
signalisieren.

von spess53 (Gast)


Lesenswert?

Hi

>OK :) Dann klink ich mich da aus, ich programmiere nur C. Sorry!

Bedingte Compilierung sollte es doch eigentlich auch bei C geben. Oder.

MfG Spess

von nixchecker (Gast)


Lesenswert?

Ich kann keinen Assembler-Text lesen.

von Karl H. (kbuchegg)


Lesenswert?

Hier
1
Write_EEPROM:
2
    push r17
3
  sbic    EECR, EEWE                  ; prüfe ob der letzte Schreibvorgang beendet ist
4
    rjmp    Write_EEPROM                ; wenn nein, nochmal prüfen
5
    out     EEARH, ZH                   ; Adresse schreiben
6
    out     EEARL, ZL                   ; 
7
    out     EEDR,r25                   ; Daten  schreiben
8
    in      r17,SREG              ; SREG sichern
9
    cli                                 ; Interrupts sperren, die nächsten
10
    sbi     EECR,EEMWE                  ; Schreiben vorbereiten
11
    sbi     EECR,EEWE                   ; Und los !
12
    out     SREG, r17             ; SREG wieder herstellen
13
  pop r17
14
ret

Wenn das EEPROM am Anfang noch nicht fertig ist, bügelst du dir elegant 
mit dem push r17 den Stack nieder. Du pusht und pusht und pusht holst 
aber nur mit 1 pop r17 wieder zurück. Der darauffolgende ret geht dann 
.... irgendwo hin.

von nixchecker (Gast)


Lesenswert?

Zugegeben, ich müsst mir das langsam mal reintun...allein weil IAR in 
Assembler unbegrenz zu benutzen ist und in C auf 4k begrenzt.

von Andy11 (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Wenn das EEPROM am Anfang noch nicht fertig ist, bügelst du dir elegant
> mit dem push r17 den Stack nieder. Du pusht und pusht und pusht holst
> aber nur mit 1 pop r17 wieder zurück. Der darauffolgende ret geht dann
> .... irgendwo hin.

stimmt habs grad korrigiert, und es fubnktioniert,
du bist ein Held, zwar geht zwar der Rest nicht, aber die Messungen 
macht er scheinbar durch

danke, das war auch logisch was du vermutet hast

lg andy

von Thomas T. (knibbel)


Lesenswert?

Karl Heinz hat recht. Unten ist der Quelltext so geändert, dass r17 nur 
einmal gesichert wird...
1
Write_EEPROM:  sbic    EECR, EEWE                  ; prüfe ob der letzte Schreibvorgang beendet ist
2
    rjmp    Write_EEPROM                ; wenn nein, nochmal prüfen
3
    push r17
4
    out     EEARH, ZH                   ; Adresse schreiben
5
    out     EEARL, ZL

Gruß,
Thomas

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:
>
> danke, das war auch logisch was du vermutet hast

So :-)

Was hab ich denn vermutet?
Kannst du die Gedankengänge nachvollziehen, wie ich die bewusste Stelle 
in 30 Sekunden gefunden habe?

(Hinweis: Es hat etwas mit deiner Fehlerbeschreibung und der Reihenfolge 
der Programmausführung zu tun)

von Andy11 (Gast)


Lesenswert?

>(Hinweis: Es hat etwas mit der Reihenfolge der Programmausführung zu
>tun)

kein plan

von Karl H. (kbuchegg)


Lesenswert?

Wenn eine bewusste Stelle (bei dir das Kontrolled anschalten) offenbar 
nie erreicht wird, dann muss es zwischen dem vorletzen Kontroll-LED 
einschalten und dem bewussten irgendwo einen JUMP geben. Ansonsten geht 
der Prozessor einfach nur linear einen Befehl nach dem anderen durch und 
landet zwangsweise irgendwann beim LED-Einsschalten. Nun, Sprung hast du 
keinen, aber ein paar Calls. Ein Call muss mit seinem ret wieder an die 
Stelle zurückkommen, von wo er aufgerufen wurde. Offenbar ist das nicht 
der Fall (denn ansonsten, eh schon wissen, geht der Prozessor ja nur 
einen Befehl nach dem anderen durch und landet unweigerlich beim 
LED-Anschalten). Und die einzige Möglichkeit dass ein ret nicht mehr 
dorthin zurückkehrt von wo der call weggegangen ist, ist Unordnung auf 
dem Stack. Und die häufigste Ursache dafür wiederrum ist, dass die 
Anzahl der push/pop nicht übereinstimmt.
Von dieser Erkentniss weg, ist es dann nicht mehr schwer, sich einfach 
alle, im bewussten Codeabschnitt aufgerufenen, Funktionen anzusehen und 
daraufhin abzuklappern, ob die Anzahl der Push mit der Anzahl der Pop in 
ALLEN Fällen übereinstimmt.

von Andy11 (Gast)


Lesenswert?

spess53 schrieb:
> Vor dein Programm
>
>    .equ debug = 1
>
>   ...
>   Programm
>   ...
>
>    .if debug == 0
>
>   Deine Schleife
>
>    .endif
>
>   Weiter im Programm
>   ...

eine frage noch dazu, ist das nicht eher hochsprache`?

kann man nicht generell Bedingungen damit stellen?

von Andy11 (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Wenn eine bewusste Stelle (bei dir das Kontrolled anschalten) offenbar
> nie erreicht wird, dann muss es zwischen dem vorletzen Kontroll-LED
> einschalten und dem bewussten irgendwo einen JUMP geben. Ansonsten geht
>...
aufgerufenen, Funktionen anzusehen und
> daraufhin abzuklappern, ob die Anzahl der Push mit der Anzahl der Pop in
> ALLEN Fällen übereinstimmt.

ok das weiß ich natürlich, an der einen Stelle ist mir halt einen Fehler 
passiert.

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:
> Karl heinz Buchegger schrieb:
>> Wenn eine bewusste Stelle (bei dir das Kontrolled anschalten) offenbar
>> nie erreicht wird, dann muss es zwischen dem vorletzen Kontroll-LED
>> einschalten und dem bewussten irgendwo einen JUMP geben. Ansonsten geht
>>...
> aufgerufenen, Funktionen anzusehen und
>> daraufhin abzuklappern, ob die Anzahl der Push mit der Anzahl der Pop in
>> ALLEN Fällen übereinstimmt.
>
> ok das weiß ich natürlich, an der einen Stelle ist mir halt einen Fehler
> passiert.

Ist ja nicht schlimm. Fehler passieren.
Ich wollte dir nur den Gedankengang erläutern, wie ich den Fehler 
gefunden habe, ausgehend von deiner Beschreibung was passiert und was 
nicht passiert.

von spess53 (Gast)


Lesenswert?

Hi

>eine frage noch dazu, ist das nicht eher hochsprache`?

Was haben Assemblerdirektiven mit Hochsprache zu tun? Die gehören 
genauso wie z.B. Macros zu Handwerkszeug wie die Controller-Befehle.

>kann man nicht generell Bedingungen damit stellen?

Wenn du das meinst, was ich vermute: ja. In diese Weise wähle ich z.B. 
in einer Lib für Dog-Displays zwischen Ansteuerung mit SPI, USART im 
SPI-Mode, USI im SPI-Mode oder Software-SPI aus.

MfG Spess

von Michael M. (Gast)


Lesenswert?

sicherlich nicht uninteressant:
http://www.labcenter.co.uk/products/vsm_overview.cfm

damit kannst du deine schaltung nachbauen und deinen AVR simulieren.
dazu zählt, dass du dir sämtliche register, den RAM, das eeprom, usw 
ansehen kannst und breakpoints auf bestimmte zustände oder werte setzen 
kannst.

außerdem kannst du deine restliche hardware auch gleich mitsimulieren. 
ldr, lcd, potis, usw... alles mit dabei.

proteus kolaboriert dabei mit dem AVR-Studio, sodass breakpoints aus 
deinem programm im simulator übernommen werden.

ich kanns nur empfehlen!

von Martin V. (oldmax)


Lesenswert?

Hi
Das Problem kenn ich, das schreibt man ein Programm und irgendwie 
läuft's nicht. Da ich für (fast) alle meine Programme eine serielle 
Schnittsstelle brauche, habe ich diese genutzt und mir ein Tool auf dem 
PC geschrieben, welches mir die Inhalte der Variablen anzeigt. Oder 
vielleicht besser, die Inhalte der Speicherstellen im SRam. Das Programm 
hab ich hier irgendwo allgemein zugänglich gemacht. Such mal nach 
OpenEye. Da findest du die Exe und eine Doku dazu.
wenn du einen Ablauf von deinem Programm verfolgen willst, dann hast du 
die Möglichkeit, einzenen Bereichen ein Bit zu spendieren. Anhand von 
Ergebnissen in anderen Variablen ist einigermaßen leicht ein Prüfen 
möglich. Du hast einen Einzelzugriff auf die Werte, oder du läßt dir 
ständig die Werte anzeigen, Aktualisierung im 100ms Takt.
Gruß oldmax

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.