mikrocontroller.net

Forum: Compiler & IDEs Stackpointer aus Versehen hinter RAM-Ende, geht trotzdem?


Autor: Jörg H. (idc-dragon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe gerade einen Fehler gefunden, der den Bootloader von bereits im 
Einsatz befindlichen Geräte betrifft:
Aus Versehen habe ich beim Mega8 den Stackpointer falsch gesetzt 
(Abfrage im Makefile falsch).

Dazu sagen sollte ich noch das ich aus Platzgründen "-mtiny-stack" 
verwende, der erzeugte Code also nur das Lowbyte des Stackpointers 
verändert. Um die dann noch möglichen 256 (oder 255?) Byte Stack nutzen 
zu können wollte ich den Stack auf 256-Byte Alignment abrunden, mit 
"--defsym=__stack=0x8003ff". (Das Ram geht sonst bis 0x45f. Danke an 
Jörg Wunsch für den Tipp seinerzeit. :-)

Stattdessen ist es "--defsym=__stack=0x8004ff" geworden, diese 
Definition galt eigentlich dem Mega88/Mega168.
Mir ist bisher kein Fehlverhalten der Geräte aufgefallen, der Bootloader 
scheint zu funktionieren. Wie passiert denn da ggf. ein Wraparound, wo 
landet das nun, wieviel Stack habe ich so, muß ich mir Sorgen machen?

PS: Wie kommt es eigentlich zu dieser ulkigen Speicherdefinition mit der 
8 in 0x8003ff?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Hohensohn wrote:

> PS: Wie kommt es eigentlich zu dieser ulkigen Speicherdefinition mit der
> 8 in 0x8003ff?

GCC und die binutils können nur mit einem einzigen Adressraum arbeiten, 
AVR hingegen hat deren drei. Also tut man so, als ob sich Flash, EEPROM 
und RAM ein einem einzigen grossen Adressraum befinden.

Autor: John Small (linux_80)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

der M8 hat 11 Bit für den Stackpointer, wenn in den Bits 11-15 was 
steht, wird es ihm egal sein, und einfach an die Stelle schreiben die 
der Wert von Bit0-10 entspricht.
Was über die 16 Bit hinausgeht wird dann sowieso verschluckt.

Mega88/Mega168 haben auch nicht mehr RAM als der Mega8 (fängt aber 
weiter hinten an) ;-).

Mit 11 Bit kann man aber trotzdem mehr Speicher adressieren als der M8 
usw. haben, ich weiss nicht wo man da landet, evtl. wird das auch 
gespiegelt, und liegt dann irgendwo anders im SRAM !?

Hast Du auch mal geschaut was nach dem compilieren draus wird (*.lss) ?

Autor: Jörg H. (idc-dragon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine Frage läuft also drauf hinaus, was die Adressierung beim Mega8 
jenseits von 0x45f macht. Ist kein "klassischer" Wrap an glatter 
Binärgrenze, wo die signifikanten Bits wrappen. Irgendein Speicher 
scheint drunter zu liegen, sonst würde mein Programm ja sofort in den 
Wald laufen.

Das .lss File ist unspektakulär, der Startup-Code schreibt halt die 
falsche Adresse in die Stackpointer-Hardwareregister. Vom korrekten Code 
unterscheidet sich das Hexfile nur in einem einzigen Byte, x4 statt x3, 
so hatte ich es auch erst bemerkt. Die Codegenerierung ist ja davon 
unbeeindruckt.

@Andreas: steht das irgendwo, wie die 3 Adressräume gemappt sind?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Adressen mit denen GCC arbeitet, stehen im MEMORY Abschnitt des 
entsprechenden Linkerskripts (avr/lib/ldscripts).

Darum brauchst du dich aber nicht zu kümmern. OK. Vielleicht beim 
Debuggen wird es interessant.

Du gibst im Quelltext an, wo die Adresse liegt bzw. greifst mit 
speziellen Funktionen darauf zu. Bei RAM ist kein Schlüsselword nötig. 
Bei Flash-ROM kommt PROGMEN zum Einsatz und bei EEPROM EEMEM.

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Jörg H. (idc-dragon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auflösung:

Ich habe ein Testprogramm geschrieben um rauszufinden, wie denn der 
Speicher hinter dem Ende wrapped.
Bei 0x45F ist wie gesagt das RAM zuende. Der Bereich danach 0x460 bis 
0x4FF wird auf 0x060 bis 0x0FF abgebildet. Mein falscher Stack wächst 
also nun von 0x0FF abwärts.
Zufällig ist dort der eher hintere Teil eines großzügigen 
Eingangspuffers. Der ist 256 Byte groß, nutze ich nicht aus, aber war 
einfacher da ich einen uint8-Index dorthinein nicht bereichsüberprüfen 
muß.
Wegen dieses im Normalfall ungenutzten Buffers und des eher geringen 
Stackbedarfs läuft also das Programm. Ist natürlich nicht schön, eine 
lange Message würde es zum Absturz bringen.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Hohensohn wrote:
> Ist natürlich nicht schön, eine
> lange Message würde es zum Absturz bringen.

"nicht schön"?!? ;)

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.