Forum: Mikrocontroller und Digitale Elektronik atmega läuft nicht


von schmidti (Gast)


Lesenswert?

Habe die Frage hier schon einmal gestellt, aber leider keine Antwort 
erhalten. Darum stelle ich sie hier noch einmal, etwas anders 
formuliert. Vielleicht findet ja jemand noch eine Lösung.

Also, ich habe ein Programm (war einmal ne ganze Menge, mittlerweile 
besteht es nur noch aus LEDs die ein und ausgeschaltet werden).
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <stdio.h>
5
#include <util/delay.h>
6
7
int main(void){
8
    uint16_t i = 0;
9
    DDRD = 0xff;
10
    PORTD = 0x00;
11
    uint8_t stat = 0;
12
    while(1){
13
        i = 0;
14
  while(i <= 100){
15
            _delay_ms(10);
16
            i++;
17
  }
18
  if(stat == 1){
19
            PORTD = 0xff;
20
            stat = 0;
21
        }
22
        else{
23
            PORTD = 0x00;
24
            stat = 1;
25
        }
26
  }
27
    return 0;
28
}

Läuft auch alles wunderbar. Die LEDs blinken im passenden Takt (etwa 1 
Sekunde bei 16MHz) und alles ist toll.

Nun kompiliere ich noch ein paar mehr Quellen ein. Diese sind noch nicht 
weiter per include eingebunden. Ich nutze alse den gleichen Code. Nun 
blinkt aber nichts mehr. Ich habe keine Ahnung warum. Die beiden 
kompilierten HEX-Files sehen am Anfang fast identisch aus, das mit dem 
zusätzlichen Code kompilierte nur halt länger. Im AVRSimulator läuft das 
ganze auch wunderbar durch.

Hat noch jemand eine Idee, was ich testen könnte? Mir würden evtl auch 
Ansätze oder Ahnung schon weiterhelfen. Nur derzeit habe ich mich echt 
komplett festgerannt.

Aso, der zusätzliche Code ist der UIP-Stack von A.Dunkels. Da ist nichts 
AVR-lastiges dabei.

Hier noch der Link auf mein altes Posting, vllt hilft das ja jemandem:

Beitrag "uIP auf einem Atmega"

Gruß


Schmidti

von Nico (nico123)


Lesenswert?

Gibts denn eine Fehlermeldung beim kompilieren?

Wie sieht der Code aus den Du noch hinzu fügst?

von Thomas B. (escamoteur)


Lesenswert?

Passt das ganze überhaupt noch in Deinen AVR? Optimierung eigeschaltet?

von Michael W. (retikulum)


Lesenswert?

Das Programm startet immer wieder neu. Nach der Initialisierung fehlt 
ein while (1) also die Endlosschleife um das Hauptprogramm.

Michael

von Nico (nico123)


Lesenswert?

Michael W. schrieb:
> Das Programm startet immer wieder neu. Nach der Initialisierung fehlt
> ein while (1) also die Endlosschleife um das Hauptprogramm.

Die while-Schleife ist schon okay! Was genau meinst Du?

von Grrrr (Gast)


Lesenswert?

Nico ... schrieb:
>> Das Programm startet immer wieder neu. Nach der Initialisierung fehlt
>> ein while (1) also die Endlosschleife um das Hauptprogramm.
>
> Die while-Schleife ist schon okay! Was genau meinst Du?

Da es keine while(1)-Schleife in dem Programm gibt, kann sie auch nicht 
"schon okay" sein. Es wäre also gut, wenn Du die Frage neu formulierst.

von schmidti (Gast)


Lesenswert?

Nico ... schrieb:
> Wie sieht der Code aus den Du noch hinzu fügst?

uip-Stack, ist eine ganze Menge. 
http://www.sics.se/~adam/uip/index.php/Main_Page

Aber ist halt ersteinmal nicht für den AVR. Und es gibt keine 
Fehlermeldung.

> Passt das ganze überhaupt noch in Deinen AVR? Optimierung eigeschaltet?

jup, brauche 20kb von 64

> Das Programm startet immer wieder neu. Nach der Initialisierung fehlt
> ein while (1) also die Endlosschleife um das Hauptprogramm.

Nö, ist oben nur ungeschickt formatiert. Das while(1) ist da und, wenn 
ich das HEX durch den Avrsimulator jage, sitzt er auch schon an der 
Stelle und schaltet die Ports ein und aus.  Auch mit dem uip-Stack

Gruß

von Nico (nico123)


Lesenswert?

Grrrr schrieb:
> Nico ... schrieb:
>>> Das Programm startet immer wieder neu. Nach der Initialisierung fehlt
>>> ein while (1) also die Endlosschleife um das Hauptprogramm.
>>
>> Die while-Schleife ist schon okay! Was genau meinst Du?
>
> Da es keine while(1)-Schleife in dem Programm gibt, kann sie auch nicht
> "schon okay" sein. Es wäre also gut, wenn Du die Frage neu formulierst.

Und was ist das dann vor dem Pfeil???
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <stdio.h>
5
#include <util/delay.h>
6
7
int main(void){
8
    uint16_t i = 0;
9
    DDRD = 0xff;
10
    PORTD = 0x00;
11
    uint8_t stat = 0;
12
    while(1){                        <----HIER...
13
        i = 0;
14
  while(i <= 100){
15
            _delay_ms(10);
16
            i++;
17
  }
18
  if(stat == 1){
19
            PORTD = 0xff;
20
            stat = 0;
21
        }
22
        else{
23
            PORTD = 0x00;
24
            stat = 1;
25
        }
26
  }
27
    return 0;
28
}

von Grrrr (Gast)


Lesenswert?

Nico ... schrieb:
> Und was ist das dann vor dem Pfeil???

Ooops.

von schmidti (Gast)


Lesenswert?

Grrrr schrieb:
> Ooops.

Kann ja passieren. Und wüsste ich, wie ich hier solch schicken bunten 
Code einfügen kann, hättest du das sicher auch sehen können. Aber leider 
liegt es nicht daran. So ein Fehler hätte ich wohl spätestens auch dann 
gefunden, wenn ich hier die Forensuche bemüht hätte.

Aber - wie schon erwähnt, der Code, so wie er oben steht, macht ja das 
was er soll - nur wenn ich da was dazukompiliere nicht mehr.

Meine Vermutung geht nun dahin, dass der uip irgendwas an irgendeinem 
Timer pfuscht, aber da ich ncihts davon aufrufe - und auch darin 
eigentlich nichts passendes zu finden ist, weiß ich leider nicht weiter.

Gruß

von Karl H. (kbuchegg)


Lesenswert?

schmidti schrieb:

> Kann ja passieren. Und wüsste ich, wie ich hier solch schicken bunten
> Code einfügen kann, hättest du das sicher auch sehen können.

Vernünftige Formatierung hätte es auch getan :-)

> Meine Vermutung geht nun dahin, dass der uip irgendwas an irgendeinem
> Timer pfuscht, aber da ich ncihts davon aufrufe

Eine Funktion die du nicht aufrufst, kann dir auch nicht ins Handwerk 
pfuschen.

Wie compilierst du denn den uiP-Stack mit ein?
(AVR-Studio Projekt; makefile?)

von schmidti (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Eine Funktion die du nicht aufrufst, kann dir auch nicht ins Handwerk
> pfuschen.

Aber vielleicht werden irgendwelche Register gesetzt.

>
> Wie compilierst du denn den uiP-Stack mit ein?
> (AVR-Studio Projekt; makefile?)

Genaugenommen nutze ich Code::Blocks, habe nur AvrStudio einmal 
getestet, da mir der Simulator gefällt, aber auch das ganze als 
AVR-Studio-projekt und dann kompiliert läuft nicht.

So kompiliere ich nun meist aus Code::Blocks heraus. Alle benötigten 
Dateien sind eingefügt. Als Optimierung noch -0s.

Gruß

von schmidti (Gast)


Lesenswert?

Hallo,

ich mal wieder, habe noch ein wenig an dem Code herumgespielt und habe 
den Spaß nach dem Kompilieren mal disassembliert. Und siehe da. Der Code 
ist fast der gleiche, nur ein paar Register werden anders gesetzt.

Das komplett kompilierte Programm
1
netio.hex:     file format ihex
2
3
Disassembly of section .sec1:
4
5
00000000 <.sec1>:
6
0:  0c 94 2a 00   jmp  0x54  ;  0x54
7
4:  0c 94 47 00   jmp  0x8e  ;  0x8e
8
8:  0c 94 47 00   jmp  0x8e  ;  0x8e
9
c:  0c 94 47 00   jmp  0x8e  ;  0x8e
10
10:  0c 94 47 00   jmp  0x8e  ;  0x8e
11
14:  0c 94 47 00   jmp  0x8e  ;  0x8e
12
18:  0c 94 47 00   jmp  0x8e  ;  0x8e
13
1c:  0c 94 47 00   jmp  0x8e  ;  0x8e
14
20:  0c 94 47 00   jmp  0x8e  ;  0x8e
15
24:  0c 94 47 00   jmp  0x8e  ;  0x8e
16
28:  0c 94 47 00   jmp  0x8e  ;  0x8e
17
2c:  0c 94 47 00   jmp  0x8e  ;  0x8e
18
30:  0c 94 47 00   jmp  0x8e  ;  0x8e
19
34:  0c 94 47 00   jmp  0x8e  ;  0x8e
20
38:  0c 94 47 00   jmp  0x8e  ;  0x8e
21
3c:  0c 94 47 00   jmp  0x8e  ;  0x8e
22
40:  0c 94 47 00   jmp  0x8e  ;  0x8e
23
44:  0c 94 47 00   jmp  0x8e  ;  0x8e
24
48:  0c 94 47 00   jmp  0x8e  ;  0x8e
25
4c:  0c 94 47 00   jmp  0x8e  ;  0x8e
26
50:  0c 94 47 00   jmp  0x8e  ;  0x8e
27
54:  11 24         eor  r1, r1
28
56:  1f be         out  0x3f, r1  ; 63
29
58:  cf e5         ldi  r28, 0x5F  ; 95
30
5a:  d8 e0         ldi  r29, 0x08  ; 8
31
5c:  de bf         out  0x3e, r29  ; 62
32
5e:  cd bf         out  0x3d, r28  ; 61
33
60:  19 e1         ldi  r17, 0x19  ; 25
34
62:  a0 e6         ldi  r26, 0x60  ; 96
35
64:  b0 e0         ldi  r27, 0x00  ; 0
36
66:  ea e2         ldi  r30, 0x2A  ; 42
37
68:  f4 e3         ldi  r31, 0x34  ; 52
38
6a:  02 c0         rjmp  .+4        ;  0x70
39
6c:  05 90         lpm  r0, Z+
40
6e:  0d 92         st  X+, r0
41
70:  ac 3e         cpi  r26, 0xEC  ; 236
42
72:  b1 07         cpc  r27, r17
43
74:  d9 f7         brne  .-10       ;  0x6c
44
76:  15 e3         ldi  r17, 0x35  ; 53
45
78:  ac ee         ldi  r26, 0xEC  ; 236
46
7a:  b9 e1         ldi  r27, 0x19  ; 25
47
7c:  01 c0         rjmp  .+2        ;  0x80
48
7e:  1d 92         st  X+, r1
49
80:  a6 36         cpi  r26, 0x66  ; 102
50
82:  b1 07         cpc  r27, r17
51
84:  e1 f7         brne  .-8        ;  0x7e
52
86:  0e 94 49 00   call  0x92  ;  0x92
53
8a:  0c 94 13 1a   jmp  0x3426  ;  0x3426
54
8e:  0c 94 00 00   jmp  0  ;  0x0
55
92:  8f ef         ldi  r24, 0xFF  ; 255
56
94:  81 b9         out  0x01, r24  ; 1
57
96:  82 b9         out  0x02, r24  ; 2
58
98:  80 e0         ldi  r24, 0x00  ; 0
59
9a:  90 e0         ldi  r25, 0x00  ; 0
60
9c:  08 95         ret
61
9e:  08 95         ret
62
a0:  80 e0         ldi  r24, 0x00  ; 0
63
a2:  90 e0         ldi  r25, 0x00  ; 0

das funktionierende Programm, welches nur LEDs ein-/ausschaltet
1
netio_klein.hex:     file format ihex
2
3
Disassembly of section .sec1:
4
5
00000000 <.sec1>:
6
0:  0c 94 2a 00   jmp  0x54  ;  0x54
7
4:  0c 94 47 00   jmp  0x8e  ;  0x8e
8
8:  0c 94 47 00   jmp  0x8e  ;  0x8e
9
c:  0c 94 47 00   jmp  0x8e  ;  0x8e
10
10:  0c 94 47 00   jmp  0x8e  ;  0x8e
11
14:  0c 94 47 00   jmp  0x8e  ;  0x8e
12
18:  0c 94 47 00   jmp  0x8e  ;  0x8e
13
1c:  0c 94 47 00   jmp  0x8e  ;  0x8e
14
20:  0c 94 47 00   jmp  0x8e  ;  0x8e
15
24:  0c 94 47 00   jmp  0x8e  ;  0x8e
16
28:  0c 94 47 00   jmp  0x8e  ;  0x8e
17
2c:  0c 94 47 00   jmp  0x8e  ;  0x8e
18
30:  0c 94 47 00   jmp  0x8e  ;  0x8e
19
34:  0c 94 47 00   jmp  0x8e  ;  0x8e
20
38:  0c 94 47 00   jmp  0x8e  ;  0x8e
21
3c:  0c 94 47 00   jmp  0x8e  ;  0x8e
22
40:  0c 94 47 00   jmp  0x8e  ;  0x8e
23
44:  0c 94 47 00   jmp  0x8e  ;  0x8e
24
48:  0c 94 47 00   jmp  0x8e  ;  0x8e
25
4c:  0c 94 47 00   jmp  0x8e  ;  0x8e
26
50:  0c 94 47 00   jmp  0x8e  ;  0x8e
27
54:  11 24         eor  r1, r1
28
56:  1f be         out  0x3f, r1  ; 63
29
58:  cf e5         ldi  r28, 0x5F  ; 95
30
5a:  d8 e0         ldi  r29, 0x08  ; 8
31
5c:  de bf         out  0x3e, r29  ; 62
32
5e:  cd bf         out  0x3d, r28  ; 61
33
60:  10 e0         ldi  r17, 0x00  ; 0
34
62:  a0 e6         ldi  r26, 0x60  ; 96
35
64:  b0 e0         ldi  r27, 0x00  ; 0
36
66:  e2 ea         ldi  r30, 0xA2  ; 162
37
68:  f0 e0         ldi  r31, 0x00  ; 0
38
6a:  02 c0         rjmp  .+4        ;  0x70
39
6c:  05 90         lpm  r0, Z+
40
6e:  0d 92         st  X+, r0
41
70:  a0 36         cpi  r26, 0x60  ; 96
42
72:  b1 07         cpc  r27, r17
43
74:  d9 f7         brne  .-10       ;  0x6c
44
76:  10 e0         ldi  r17, 0x00  ; 0
45
78:  a0 e6         ldi  r26, 0x60  ; 96
46
7a:  b0 e0         ldi  r27, 0x00  ; 0
47
7c:  01 c0         rjmp  .+2        ;  0x80
48
7e:  1d 92         st  X+, r1
49
80:  a0 36         cpi  r26, 0x60  ; 96
50
82:  b1 07         cpc  r27, r17
51
84:  e1 f7         brne  .-8        ;  0x7e
52
86:  0e 94 49 00   call  0x92  ;  0x92
53
8a:  0c 94 4f 00   jmp  0x9e  ;  0x9e
54
8e:  0c 94 00 00   jmp  0  ;  0x0
55
92:  8f ef         ldi  r24, 0xFF  ; 255
56
94:  81 b9         out  0x01, r24  ; 1
57
96:  82 b9         out  0x02, r24  ; 2
58
98:  80 e0         ldi  r24, 0x00  ; 0
59
9a:  90 e0         ldi  r25, 0x00  ; 0
60
9c:  08 95         ret
61
9e:  f8 94         cli
62
a0:  ff cf         rjmp  .-2        ;  0xa0

Interessant sind dabei nun die Zeilen 0x60, 0x66, 0x68, 0x70, 0x76, 
0x78, 0x7a, 0x80, 0x8a

Diese sind unterschiedlich. Dort werden irgendwelche Register gesetzt. 
Einmal meist mit 0. Und einmal mit irgendwelche Werten. Woher kommen 
die?

Das sind doch einfach nur die Arbeitsregister, oder?

Gruß

von schmidti (Gast)


Lesenswert?

Was ich vergaß dazu zu sagen, wenn ich die Register mit den Werten aus 
dem laufenden Programm fülle, dann geht auch das andere Programm. Also 
muss ich nun nur noch heruasfinden, wieso diese Register so gesetzt 
werden.

Hat noch jemand eine Idee?

von schmidti (Gast)


Lesenswert?

Interessant sind wohl diese Zeilen, mir ist leider nur nicht ganz klar, 
was die machen.
1
7e:  1d 92         st  X+, r1
2
80:  a6 36         cpi  r26, 0x66  ; 102
3
82:  b1 07         cpc  r27, r17
4
84:  e1 f7         brne  .-8        ;  0x7e

Also - wenn ich das recht verstehe schreibt er den Inhalt von r1 in die 
Adresse von X, erhöht das X um 1 und vergleich dann X mit 0x66 und r17 
(0x35 steht da glaube ich drin) und geht weiter, wenn das passt.

Nun stellt sich mir nur die Frage, warum erreicht er da nie ein Ende. 
Jedenfalls AVR-Studio, womit ich das simuliere nicht. Er zählt X hoch 
und fängt irgendwann von vorne an, so habe ich das gefühl.

Hat hier noch irgendjemand einen Vorschlag. Und wenn - auch warum der 
gcc mir so ein komisches Konstrukt erzeugt?

Gruß

von nowayback (Gast)


Lesenswert?

Weißt Du schon, an was es gelegen hat?
Ich habe den selben Fehler mit einem Atmega32 auf dem Pollin AVR NET 
I/O-Board mit der Firmware von Ulrich Radig.
Auch ich programmiere mit Code::Blocks.
Teils entscheiden nur kleine und unwichtige Details später im Code 
darüber, ob der Atmega startet oder schon gleich am Anfang in der ersten 
Zeile daran scheitert, eine LED anzuschalten.
Ich habe auch testweise einen Atmega644 gekauft und eingebaut, aber der 
ist selbst mit den Codes, die der Atmega32 geschluckt hat, nicht 
angesprungen.

von mash3010 (Gast)


Lesenswert?

Hallo,

bin neu hier im Forum. Bin mit Microprocessorprogrammierung (u.a. 68000) 
auch beruflich quasi aufgewachsen.

Ich habe ein ähnliches Problem, wie hier im Thread beschrieben wurde.

Der ATmega32 ist für mich Neuland. Ich habe die Pollin AVR-Net-IO 
aufgebaut, die auch funktioniert. Selbst der Ethersex-Webserver läuft 
ohne Probleme. Jetzt habe ich einen TCP-IP-Stack in C aus dem Netz mit 
selbstgeschriebenen C++ Code gelinkt, was auch erstmal funktionierte. 
Dann habe ich einige C++-Routinen zu einer Klasse hinzugefügt. Jetzt 
startet der ATmega nicht mehr. Wenn ich die Funktionen leere, also nur 
den Rumpf über lasse, startet er wieder. Die hinzugefügten Funktionen 
werden beim Start aber gar nicht aufgerufen, werden bei der späteren 
Programmablauf benötigt. Es sieht so aus, als wenn irgendein 
Speicherbereich überläuft. Mach ich das Programm länger gehts nicht, 
mache ich es wieder kürzer, klappt es. Die .map-Datei sagt mir auch 
nichts.

Der Programmbereich ist nur zur Hälfte belegt. Der RAM-Bereich fast 
leer.

Weiß jemand Rat? Scheinbar bin ich kein Einzelfall.

Gruß,
Michael/SH

von Klaus W. (mfgkw)


Lesenswert?

Mein Rat: neuen Thread aufmachen und Programm zeigen.
Mit vernünftiger Beschreibung, was du vorhast.

von mash3010 (Gast)


Lesenswert?

Hallo Klaus,

ok, einen eigenen Thread kann ich anlegen. Es ging mir hier eher darum, 
ob und wie die Probleme hier gelöst wurden. Vielleicht hilft mit das 
weiter. Der letzte Beitrag ist schon ein halbes Jahr alt, da sollte sich 
doch was getan haben.

von Klaus W. (mfgkw)


Lesenswert?

Sorry, dann habe ich dich falsch verstanden.

Dein Problem sieht aber auch etwas anders aus.
Je nachdem, was du in C++ hinzufügst, kann z.B. schnell  der
Stack alle sein. Das wäre dann ein reines Problem in deinem
Programm.

von Rolf P. (rolfp)


Lesenswert?

schmidti schrieb:
> 54:  11 24         eor  r1, r1
> 56:  1f be         out  0x3f, r1  ; 63

r1 und SREG werden geloescht

> 58:  cf e5         ldi  r28, 0x5F  ; 95
> 5a:  d8 e0         ldi  r29, 0x08  ; 8
> 5c:  de bf         out  0x3e, r29  ; 62
> 5e:  cd bf         out  0x3d, r28  ; 61

Stackpointer wird auf Y=0x085F also Ende des RAMs gesetzt

> 60:  19 e1         ldi  r17, 0x19  ; 25
> 62:  a0 e6         ldi  r26, 0x60  ; 96
> 64:  b0 e0         ldi  r27, 0x00  ; 0

X wird auf 0x0060 gesetzt, also vermutlich Start des RAMs
(benutzt du einen ATmega32, dann passt es)

> 66:  ea e2         ldi  r30, 0x2A  ; 42
> 68:  f4 e3         ldi  r31, 0x34  ; 52

Z wird auf 0x342A gesetzt

> 6a:  02 c0         rjmp  .+4        ;  0x70
> 6c:  05 90         lpm  r0, Z+
> 6e:  0d 92         st  X+, r0
> 70:  ac 3e         cpi  r26, 0xEC  ; 236
> 72:  b1 07         cpc  r27, r17
> 74:  d9 f7         brne  .-10       ;  0x6c

Es wird vom Flash beginnend bei 0x342A ins RAM kopiert.
Und zwar wird solange kopiert bis im RAM 0x19EC erreicht ist.
Hoppla: das RAM geht doch nur bis 0x085F !!

> 76:  15 e3         ldi  r17, 0x35  ; 53
> 78:  ac ee         ldi  r26, 0xEC  ; 236
> 7a:  b9 e1         ldi  r27, 0x19  ; 25
> 7c:  01 c0         rjmp  .+2        ;  0x80
> 7e:  1d 92         st  X+, r1
> 80:  a6 36         cpi  r26, 0x66  ; 102
> 82:  b1 07         cpc  r27, r17
> 84:  e1 f7         brne  .-8        ;  0x7e

Hier wird ein RAM-Bereich geloescht. Beginnend mit 0x19EC und
bis 0x3566

> 86:  0e 94 49 00   call  0x92  ;  0x92
> 8a:  0c 94 13 1a   jmp  0x3426  ;  0x3426

Vermutlich: TWI initialisieren und Sprung zum Hauptprogramm.

> 8e:  0c 94 00 00   jmp  0  ;  0x0
> 92:  8f ef         ldi  r24, 0xFF  ; 255
> 94:  81 b9         out  0x01, r24  ; 1
> 96:  82 b9         out  0x02, r24  ; 2
> 98:  80 e0         ldi  r24, 0x00  ; 0
> 9a:  90 e0         ldi  r25, 0x00  ; 0
> 9c:  08 95         ret
> 9e:  08 95         ret
> a0:  80 e0         ldi  r24, 0x00  ; 0
> a2:  90 e0         ldi  r25, 0x00  ; 0

Das ueberlaufende RAM wird also wohl das Problem sein.

Rolf

von Michael F. (mash3010)


Lesenswert?

Die Methoden werden gar nicht beim Start aufgerufen, benötigen also 
keinen Stack. Das ist ja gerade so seltsam. Es scheint sich nur um mehr 
Programmcode zu handeln, der dazu führt, dass der Controller nicht mehr 
startet. Wenn ich die Methoden leere, also nur den Rumpf über lasse, 
funktioniert es ja. Wie schon geschrieben, die Methoden werden beim 
Start nicht aufgerufen. Es läuft nur eine Timer, für eine Portausgabe 
und der TCP-IP-Stack. Ist alles ok, kann ich das Board anpingen. 
Vergrößere ich den Programmcode, läuft der Ping ins leere. Die Methoden 
werden erst aufgerufen, wenn IP-Pakete an für einen bestimmten Port 
empfangen werden und das passiert nach dem Reset nicht.

von Rolf P. (rolfp)


Lesenswert?

M. Franz schrieb:
> Die Methoden werden gar nicht beim Start aufgerufen, benötigen also
> keinen Stack. Das ist ja gerade so seltsam. Es scheint sich nur um mehr

Ausser den Stack ueberschreiben gibt es aber noch andere Nebeneffekte 
wenn man ueber das RAM-Ende hinaus schreibt.
Also beim ATmega8 geht das RAM bis 0x45F. Im Bereich 0 bis 0x1F sind die 
Register r0 bis r31. Da fuer die Adresse 0x45F nur 11 Bits benoetigt 
werden, werden die andern Bits ignoriert. Somit entspricht die Adresse 
0x811 (also 0x800+17) gerade wieder dem Register r17.
Um keinen Quatsch zu erzaehlen habe ich gerade mal ein entsprechendes
kleines Testprogramm gemacht:
1
     clr r1
2
     ldi XL, low(RAM_START)
3
     ldi XH, high(RAM_START)
4
     ldi r17, high(0x800+18)
5
     mov r18, r17
6
L1:  cp r17, r18    ; muesste immer gleich sein
7
     brne test2    ; Fehler--> synchrones Blinken
8
     st X+, r1
9
     cpi XL, low(0x800+18)
10
     cpc XH, r17
11
     brne L1      ; gesamtes RAM loeschen
12
     rjmp test1    ; allos ok --> rotierendes Blinken
Wie erwartet laeuft es mit 0x800+17 noch durch, und bei 0x800+18 wird 
r17 veraendert. Haette ich den Test auf unveraendertes r17 nicht drin 
wuerde die Schlaufe ewig laufen. Genau das passiert wohl auch beim 
Beispielprogramm von Schmidti.

Auch wenn die Variablen welche zu viel Speicher belegen erst spaeter 
kommen: der Compiler wird diese Variablen schon vor dem Hauptprogramm 
initialisieren. Auch Construkturen in C++ Klassen koennen schon bevor 
main() gestartet wird ausgefuehrt werden.

Rolf

von Michael F. (mash3010)


Lesenswert?

Der Hinweis mit dem eingeschränktem RAM-Bereich war der richtige Tipp. 
Nachdem ich ein paar Texte in den Programmspeicher verlegt habe, 
funktioniert es erstmal. Die Texte benötigen aber nur höchstens 100 
Bytes. Den eigentlichen 'Speicherfresser' habe ich wohl noch nicht 
gefunden.

Allerdings habe ich noch einen anderen Fehler, den ich noch finden muss.

Trotzdem erstmal vielen Dank für die Hilfe.

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.