Hallo!
Ich habe gestern mal avr-gcc 4.9.2 (von packages.ubuntu.com für xenial,
inklusive avr-libc und binutils-avr) ausprobiert und das
Beispielprogramm aus dem AVR-GCC-Tutorial (mit dem Makefile von dort)
für den Attiny841 übersetzt.
In main.lss habe ich folgendes entdeckt:
1
...
2
...
3
3a: 08 c0 rjmp .+16 ; 0x4c <__bad_interrupt>
4
5
0000003c <__ctors_end>:
6
3c: 11 24 eor r1, r1
7
3e: 1f be out 0x3f, r1 ; 63
8
40: cf ef ldi r28, 0xFF ; 255
9
42: d2 e0 ldi r29, 0x02 ; 2
10
44: de bf out 0x3e, r29 ; 62
11
46: cd bf out 0x3d, r28 ; 61
12
48: 02 d0 rcall .+4 ; 0x4e <main>
13
4a: 06 c0 rjmp .+12 ; 0x58 <_exit>
14
15
0000004c <__bad_interrupt>:
16
4c: d9 cf rjmp .-78 ; 0x0 <__vectors>
17
18
0000004e <main>:
19
...
20
...
Wie man sieht, wird der Stackpointer mit RAMEND initialisiert. (40–46)
Aber warum? Das ist doch sinnlos, da der Attiny841 SP sowiesor mit
RAMEND initialisiert.
Wenn ich „volatile uint8_t blabla;“ und „blabla++“ dazuschreibe, wird
die Variable tatsächlich aus dem SRAM geladen, jedoch nicht etwa von
hinter dem Stack. Scheinbar beginnt der Stack also immer bei RAMEND.
Kann man auf diese unnütze Initialisierung verzichten?
Gruß, Tuxpilot
P. S.: Natürlich ist diese Frage nicht so wichtig, ich wundere mich
nur...
Tuxpilot schrieb:> Kann man auf diese unnütze Initialisierung verzichten?
Natürlich. Aber eben nur bei den Targets, bei denen sie wirklich unnütz
ist. Tiny841 ist so eins, andere sind's nicht. Vor allem ältere
natürlich, die das einfach noch nicht in Hardware eingebaut haben. Z.B.
Mega8, 16, 32, 1280, 2560 und sicher auch ein ganze Menge älterer Tinys,
ganz sicher z.B. der (wegen seiner UART) recht häufig verwendete 2313.
Letzte Sicherheit, ob der Stackpointer bereits durch die Hardware
sinnvoll initialisiert wird, liefert (natürlich) das Datenblatt des
Target...
Im Übrigen sollte man nicht vergessen, dass diese hardwaremäßige
Initialisierung des SP auch nur bei einem Hardware-Reset passiert.
Manchmal ist es aber z.B. durchaus nützlich, nur eine Art "Soft-Reset"
auszuführen, also einen unbedingten Sprung zum Reset-Vektor. Bootloader
sind ein typische Anwendung dafür, zumindest die, die von kompetenten
Leuten so geschrieben wurden, dass sie ordentlich hinter sich aufräumen,
bevor sie die geladene App anspringen. Bei denen gehört dann natürlich
auch zum Job, den SP neu zu initialisieren, wenn sie sich nicht darauf
verlassen können, dass die App oder deren Runtime-Umgebung das tut. Ich
hoffe, du schreibst auch deine Bootloader selbst und kompetent...
Tuxpilot schrieb:> Aber warum? Das ist doch sinnlos, da der Attiny841 SP sowiesor mit> RAMEND initialisiert.
Die ersten AVRs (AT90Sxxx) hatten das noch nicht, nach dem Reset zeigte
SP auf 0x0000. Auch wenn die schon ewig keiner mehr verwendet, blieb das
SP setzen im AVR-GCC drin. Wie auch die unglückliche Verwendung von
R0,R1.
c-hater schrieb:> Ich> hoffe, du schreibst auch deine Bootloader selbst und kompetent...
Ach so, macht Sinn. An Bootloader habe ich noch nicht gedacht.
Nee, ich schreibe keine Bootloader. Wenn ich den auf den AVR
programmieren kann, dann kann ich auch gleich das fertige Programm
nehmen...
Dann hör ich jetzt auf mich zu wundern, danke für die Auskunft.
Wenn mir mal wieder 8000mB fehlen, kann ich das ja noch wegmachen.*
* mB = millibyte ;)
> Wie man sieht, wird der Stackpointer mit RAMEND initialisiert. (40–46)
Nicht wirklich, SP wird mit dem Wert des Symbols __stack initialisiert,
das per default auf RAMEND sitzt.
Grund 1: Wenn also SP auf einen anderen Wert initilisiert werden soll,
dann geht das z.B. ohne Neucompilierung per
1
avr-gcc ... -Wl,--defsym,__stack=0x200
> Aber warum? Das ist doch sinnlos, da der Attiny841 SP sowiesor mit> RAMEND initialisiert.
Grund 2: Es gibt Leute, die per "goto 0" einen "Neustart" des µC
veranstalten, z.B. von einem Bootloader zur Anwendung springen.
> Kann man auf diese unnütze Initialisierung verzichten?
Wenn du sie nicht brauchst, ja. Du kannst dir deinen eigenen
Startup-Code klöppeln und verwenden; allerdings braucht's dazu mehr als
-nostartfiles weil ein Teil des Startup-Codes traditionell aus der
libgcc stammt.