Forum: Mikrocontroller und Digitale Elektronik AVR Watchdog Debuggen


von Alex F (Gast)


Lesenswert?

Hallo zusammen,

ich möchte gerne den Watchdog debuggen, genauer gesagt möchte ich mir 
die Register ansehen wenn der Watchdog ausgelöst wird.

Mein Plan ist dabei folgender:
Databreakpoint setzen auf die Adressen am Anfang des Programms, bzw. auf 
den Sprung des Watchdogs (Ist der Watchdog überhaupt als jmp 
implementiert?)

Dann wenn dieser Breakpoint erreicht wird eben die entsprechenden 
Register/Stack ansehen.

Um dieses Vorhaben durchzuführen habe ich das mal in ein kleines 
Programm geschrieben, um es zu testen.

Leider funktioniert das ganze nicht so wie es soll.

Meine Umgebung ist das Atmel Studio 6.2.
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <avr/wdt.h>
5
#include <avr/interrupt.h>
6
#include <util/delay.h>
7
8
ISR(TIMER1_COMPA_vect)
9
{
10
  static int ir_cnt=0;
11
  ir_cnt++;
12
  wdt_reset();
13
}
14
15
void sys_init(void)
16
{
17
  wdt_enable(WDTO_15MS); // Watchdog aktiveren - Reset nach 15ms wenn keine triggerung erfolgt
18
  
19
  TCCR1B = (1 << WGM12) | (1 << CS12);  // CTC OCR1A, 1/256 Prescaler // 16µs pro Takt
20
  OCR1A=15625; // 250 ms
21
  TIMSK1= (1 << OCIE1A);
22
  
23
  sei();
24
}
25
26
int main(void)
27
{
28
  static int cnt=0;
29
  sys_init();
30
  
31
  OCR1A=30000; // Reset zu spät
32
  
33
    while(1)
34
    {
35
    cnt++;
36
    _delay_ms(20);
37
    if(cnt%1000==0)cnt=0; // darf nie erreicht werden, da davor watchdog reset erfolgen soll
38
    }
39
}

der erzeugte Assembler Code:
1
00000000  RJMP PC+0x004A    Relative jump 
2
00000001  NOP     No operation 
3
00000002  RJMP PC+0x0058    Relative jump 
4
00000003  NOP     No operation 
5
00000004  RJMP PC+0x0056    Relative jump 
6
00000005  NOP     No operation 
7
00000006  RJMP PC+0x0054    Relative jump 
8
00000007  NOP     No operation 
9
00000008  RJMP PC+0x0052    Relative jump 
10
00000009  NOP     No operation 
11
0000000A  RJMP PC+0x0050    Relative jump 
12
0000000B  NOP     No operation 
13
0000000C  RJMP PC+0x004E    Relative jump 
14
0000000D  NOP     No operation 
15
0000000E  RJMP PC+0x004C    Relative jump 
16
0000000F  NOP     No operation 
17
00000010  RJMP PC+0x004A    Relative jump 
18
00000011  NOP     No operation 
19
00000012  RJMP PC+0x0048    Relative jump 
20
00000013  NOP     No operation 
21
00000014  RJMP PC+0x0046    Relative jump 
22
00000015  NOP     No operation 
23
00000016  RJMP PC+0x0044    Relative jump 
24
00000017  NOP     No operation 
25
00000018  RJMP PC+0x0043    Relative jump 
26
00000019  NOP     No operation 
27
0000001A  RJMP PC+0x0040    Relative jump 
28
0000001B  NOP     No operation 
29
0000001C  RJMP PC+0x003E    Relative jump 
30
0000001D  NOP     No operation 
31
0000001E  RJMP PC+0x003C    Relative jump 
32
0000001F  NOP     No operation 
33
00000020  RJMP PC+0x003A    Relative jump 
34
00000021  NOP     No operation 
35
00000022  RJMP PC+0x0038    Relative jump 
36
00000023  NOP     No operation 
37
00000024  RJMP PC+0x0036    Relative jump 
38
00000025  NOP     No operation 
39
00000026  RJMP PC+0x0034    Relative jump 
40
00000027  NOP     No operation 
41
00000028  RJMP PC+0x0032    Relative jump 
42
00000029  NOP     No operation 
43
0000002A  RJMP PC+0x0030    Relative jump 
44
0000002B  NOP     No operation 
45
0000002C  RJMP PC+0x002E    Relative jump 
46
0000002D  NOP     No operation 
47
0000002E  RJMP PC+0x002C    Relative jump 
48
0000002F  NOP     No operation 
49
00000030  RJMP PC+0x002A    Relative jump 
50
00000031  NOP     No operation 
51
00000032  RJMP PC+0x0028    Relative jump 
52
00000033  NOP     No operation 
53
00000034  RJMP PC+0x0026    Relative jump 
54
00000035  NOP     No operation 
55
00000036  RJMP PC+0x0024    Relative jump 
56
00000037  NOP     No operation 
57
00000038  RJMP PC+0x0022    Relative jump 
58
00000039  NOP     No operation 
59
0000003A  RJMP PC+0x0020    Relative jump 
60
0000003B  NOP     No operation 
61
0000003C  RJMP PC+0x001E    Relative jump 
62
0000003D  NOP     No operation 
63
0000003E  RJMP PC+0x001C    Relative jump 
64
0000003F  NOP     No operation 
65
00000040  RJMP PC+0x001A    Relative jump 
66
00000041  NOP     No operation 
67
00000042  RJMP PC+0x0018    Relative jump 
68
00000043  NOP     No operation 
69
00000044  RJMP PC+0x0016    Relative jump 
70
00000045  NOP     No operation 
71
00000046  RJMP PC+0x0014    Relative jump 
72
00000047  NOP     No operation 
73
00000048  RJMP PC+0x0012    Relative jump 
74
00000049  NOP     No operation 
75
0000004A  CLR R1    Clear Register 
76
0000004B  OUT 0x3F,R1    Out to I/O location 
77
0000004C  SER R28    Set Register 
78
0000004D  LDI R29,0x10    Load immediate 
79
0000004E  OUT 0x3E,R29    Out to I/O location 
80
0000004F  OUT 0x3D,R28    Out to I/O location 
81
00000050  LDI R18,0x01    Load immediate 
82
00000051  LDI R26,0x00    Load immediate 
83
00000052  LDI R27,0x01    Load immediate 
84
00000053  RJMP PC+0x0002    Relative jump 
85
00000054  ST X+,R1    Store indirect and postincrement 
86
00000055  CPI R26,0x04    Compare with immediate 
87
00000056  CPC R27,R18    Compare with carry 
88
00000057  BRNE PC-0x03    Branch if not equal 
89
00000058  RCALL PC+0x0034    Relative call subroutine 
90
00000059  RJMP PC+0x0082    Relative jump 
91
0000005A  RJMP PC-0x005A    Relative jump 
92
{
93
0000005B  PUSH R1    Push register on stack 
94
0000005C  PUSH R0    Push register on stack 
95
0000005D  IN R0,0x3F    In from I/O location 
96
0000005E  PUSH R0    Push register on stack 
97
0000005F  CLR R1    Clear Register 
98
00000060  PUSH R24    Push register on stack 
99
00000061  PUSH R25    Push register on stack 
100
  ir_cnt++;
101
00000062  LDS R24,0x0102    Load direct from data space 
102
00000064  LDS R25,0x0103    Load direct from data space 
103
00000066  ADIW R24,0x01    Add immediate to word 
104
00000067  STS 0x0103,R25    Store direct to data space 
105
00000069  STS 0x0102,R24    Store direct to data space 
106
  wdt_reset();
107
0000006B  WDR     Watchdog reset 
108
}
109
0000006C  POP R25    Pop register from stack 
110
0000006D  POP R24    Pop register from stack 
111
0000006E  POP R0    Pop register from stack 
112
0000006F  OUT 0x3F,R0    Out to I/O location 
113
00000070  POP R0    Pop register from stack 
114
00000071  POP R1    Pop register from stack 
115
00000072  RETI     Interrupt return 
116
  wdt_enable(WDTO_15MS); // Watchdog aktiveren - Reset nach 15ms wenn keine triggerung erfolgt
117
00000073  LDI R18,0x08    Load immediate 
118
00000074  LDI R24,0x18    Load immediate 
119
00000075  LDI R25,0x00    Load immediate 
120
00000076  IN R0,0x3F    In from I/O location 
121
00000077  CLI     Global Interrupt Disable 
122
00000078  WDR     Watchdog reset 
123
00000079  STS 0x0060,R24    Store direct to data space 
124
0000007B  OUT 0x3F,R0    Out to I/O location 
125
0000007C  STS 0x0060,R18    Store direct to data space 
126
  TCCR1B = (1 << WGM12) | (1 << CS12);  // CTC OCR1A, 1/256 Prescaler // 16�s pro Takt
127
0000007E  LDI R24,0x0C    Load immediate 
128
0000007F  STS 0x0081,R24    Store direct to data space 
129
  OCR1A=15625; // 250 ms
130
00000081  LDI R24,0x09    Load immediate 
131
00000082  LDI R25,0x3D    Load immediate 
132
00000083  STS 0x0089,R25    Store direct to data space 
133
00000085  STS 0x0088,R24    Store direct to data space 
134
  TIMSK1= (1 << OCIE1A);
135
00000087  LDI R24,0x02    Load immediate 
136
00000088  STS 0x006F,R24    Store direct to data space 
137
  sei();
138
0000008A  SEI     Global Interrupt Enable 
139
0000008B  RET     Subroutine return 
140
  sys_init();
141
0000008C  RCALL PC-0x0019    Relative call subroutine 
142
  OCR1A=30000; // Reset zu sp�t
143
0000008D  LDI R24,0x30    Load immediate 
144
0000008E  LDI R25,0x75    Load immediate 
145
0000008F  STS 0x0089,R25    Store direct to data space 
146
00000091  STS 0x0088,R24    Store direct to data space 
147
    if(cnt%1000==0)cnt=0; // darf nie erreicht werden, da davor watchdog reset erfolgen soll
148
00000093  LDI R18,0xE8    Load immediate 
149
00000094  LDI R19,0x03    Load immediate 
150
    cnt++;
151
00000095  LDS R24,0x0100    Load direct from data space 
152
00000097  LDS R25,0x0101    Load direct from data space 
153
00000099  ADIW R24,0x01    Add immediate to word 
154
0000009A  STS 0x0101,R25    Store direct to data space 
155
0000009C  STS 0x0100,R24    Store direct to data space 
156
  __builtin_avr_delay_cycles(__ticks_dc);
157
0000009E  SER R20    Set Register 
158
0000009F  LDI R24,0xF9    Load immediate 
159
000000A0  LDI R25,0x00    Load immediate 
160
000000A1  SUBI R20,0x01    Subtract immediate 
161
000000A2  SBCI R24,0x00    Subtract immediate with carry 
162
000000A3  SBCI R25,0x00    Subtract immediate with carry 
163
000000A4  BRNE PC-0x03    Branch if not equal 
164
000000A5  RJMP PC+0x0001    Relative jump 
165
000000A6  NOP     No operation 
166
    if(cnt%1000==0)cnt=0; // darf nie erreicht werden, da davor watchdog reset erfolgen soll
167
000000A7  LDS R24,0x0100    Load direct from data space 
168
000000A9  LDS R25,0x0101    Load direct from data space 
169
000000AB  MOVW R22,R18    Copy register pair 
170
000000AC  RCALL PC+0x0008    Relative call subroutine 
171
000000AD  OR R24,R25    Logical OR 
172
000000AE  BRNE PC-0x19    Branch if not equal 
173
--- No source file -------------------------------------------------------------
174
000000AF  STS 0x0101,R1    Store direct to data space 
175
000000B1  STS 0x0100,R1    Store direct to data space 
176
000000B3  RJMP PC-0x001E    Relative jump 
177
000000B4  BST R25,7    Bit store from register to T 
178
000000B5  MOV R0,R23    Copy register 
179
000000B6  BRTC PC+0x03    Branch if T flag cleared 
180
000000B7  COM R0    One's complement 
181
000000B8  RCALL PC+0x0007    Relative call subroutine 
182
000000B9  SBRC R23,7    Skip if bit in register cleared 
183
000000BA  RCALL PC+0x0009    Relative call subroutine 
184
000000BB  RCALL PC+0x000C    Relative call subroutine 
185
000000BC  SBRC R0,7    Skip if bit in register cleared 
186
000000BD  RCALL PC+0x0006    Relative call subroutine 
187
000000BE  BRTC PC+0x08    Branch if T flag cleared 
188
000000BF  COM R25    One's complement 
189
000000C0  NEG R24    Two's complement 
190
000000C1  SBCI R25,0xFF    Subtract immediate with carry 
191
000000C2  RET     Subroutine return 
192
--- No source file -------------------------------------------------------------
193
000000C3  COM R23    One's complement 
194
000000C4  NEG R22    Two's complement 
195
000000C5  SBCI R23,0xFF    Subtract immediate with carry 
196
000000C6  RET     Subroutine return 
197
000000C7  SUB R26,R26    Subtract without carry 
198
000000C8  SUB R27,R27    Subtract without carry 
199
000000C9  LDI R21,0x11    Load immediate 
200
000000CA  RJMP PC+0x0008    Relative jump 
201
000000CB  ROL R26    Rotate Left Through Carry 
202
000000CC  ROL R27    Rotate Left Through Carry 
203
000000CD  CP R26,R22    Compare 
204
000000CE  CPC R27,R23    Compare with carry 
205
000000CF  BRCS PC+0x03    Branch if carry set 
206
000000D0  SUB R26,R22    Subtract without carry 
207
000000D1  SBC R27,R23    Subtract with carry 
208
000000D2  ROL R24    Rotate Left Through Carry 
209
000000D3  ROL R25    Rotate Left Through Carry 
210
000000D4  DEC R21    Decrement 
211
000000D5  BRNE PC-0x0A    Branch if not equal 
212
000000D6  COM R24    One's complement 
213
000000D7  COM R25    One's complement 
214
000000D8  MOVW R22,R24    Copy register pair 
215
000000D9  MOVW R24,R26    Copy register pair 
216
000000DA  RET     Subroutine return 
217
000000DB  CLI     Global Interrupt Disable 
218
--- No source file -------------------------------------------------------------
219
000000DC  RJMP PC-0x0000    Relative jump

Ich würde gerne den Databreakpoit auf 0x00000 setzten allerdings ist das 
im Atmel Stduio nicht möglich. Nur 0x00001 wird akzeptiert.

Dementsprechend setzte ich bei 0x000004A einen Breakpoint aber das führt 
mich noch nicht so richtig zum Ziel.

Ich möchte gerne bevor der Watchdog ausgeführt wird Stoppen.

An welche Adresse bzw. an welche Stelle im Code muss ich den Breakpoint 
setzten um vor dem Watchdog zu stoppen?

von Tim (Gast)


Lesenswert?

>ich möchte gerne den Watchdog debuggen, genauer gesagt möchte ich mir
>die Register ansehen wenn der Watchdog ausgelöst wird.

Das geht so nicht. Der Wachhund ist eine unabhängige Schaltung
im AVR die am RESET hängt. Wenn der zubeißt ist es schon zu spät.

Einige AVRS können jedoch anstelle eines Resets einen IRQ auslösen.
Vielleicht kannst du damit das gewünscht erreichen...

von Alex F (Gast)


Lesenswert?

Das hört sich nicht so gut an. Es handelt sich um einen Atmega128 - der 
kann wenn ich das rchtig sehe keinen Intrrupt auslösen wenn der Watchdog 
kommt.

Wenn der Reset ausgelöst wird, werden dann sofort alle Werte aus dem 
Speicher gelöscht oder könnte ich die noch ansehen, wenn ich den 
Breakpoint auf 0x0000 setzte?

von uwe (Gast)


Lesenswert?

> Wenn der Reset ausgelöst wird, werden dann sofort alle Werte aus dem
> Speicher gelösch
Nö der Speicher bleibt erhalten. Wenn man nun nach einem Start überprüft 
woher der Reset kam  (steht im MCUCSR) kann man sehen das er von einem 
Watchdog ausgelöst wurde und kann sich variablen anzeigen lassen. Das 
muß natürlich vor dem Variablen initialisieren passieren.

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.