Forum: Mikrocontroller und Digitale Elektronik Speicherbereich reservieren?


von Thomas O. (Gast)


Lesenswert?

Hallo,

kann mir das jemand kurz erklären?
sts     $60,hexl                ;low byte speichern

wo wird das ganze gespeichert? Im Datenblatt steht Store in Date Space
ist damit das SRAM gemeint? Wenn ja kann es mir passieren das diese
Speicherstelle durch irgendetwas überschrieben wird z.b. Stapel? Würde
das gerne irgendwie verhindern, läßt sich da ein bestimmter Bereich
reservieren.

Der Hintergrund des ganzen ist folgender ich möchte eine Spannung über
 den ADC einlesen und 8 Werte fortlaufend speichern um z.b. eine
Mittelwertbildung zu machen. Aber 8 Register zu verwenden wäre mir
dafür zu schade.

Läßt sich dieser Wert auch irgendwie erhöhen damit ich beim 2ten
Druchgang $61 habe? Oder kann  man da irgendwie mit den Pointern
arbeiten.

Wäre klasse wenn mir hier jemadn helfen könnte, da ich mich mit der
Adressierung in den einzelnen Speicherbereichen garnicht auskenne und
das Datenblatt hilft mir hier auch nicht besonderst weiter.

von dave (Gast)


Lesenswert?

als assembler-programmierer kannst du nur mit .dseg bereiche etwas
freihalten, jedoch ist das ein nichtiger schutz im richtigen
programm..
man muss halt aufpassen, was man tut

zu dem hochzählen: richtig pointer
du lädst die adresse des ersten bytes (im sram, also wos erste hin
soll) und dann einfach für jedes einmal in x+ speichern.. speichern und
automatisches erhöhen des pointers.

ldi xl, low(0x60)
ldi xh, high(0x60)

in r16, adch      ; läd das byte
st x+, r16        ; speichert es ins sram und erhöht anschließend

lesen geht genau so:
ld r16, x+        ; lesen und erhöhen

weiter gibt es den pre-dec, also erst verkleinern und dann erst was
machen:

ldi xl, low(0x60+8)
ldi xh, high(0x60+8)
ld r16, -x

wie du es machst ist dir überalassen... manchmal ist es sinnvoll erst
alles mit x+ hochzuspeichern und dann nacher mit -x runter holen ==>
keine neue adresse in x laden, verdreht dafür

dave

von Thomas O. (Gast)


Lesenswert?

Hallo,

vielen dank für deine Hilfe. Das wird mir schon etwas weiterhelfen.

von ...HanneS... (Gast)


Lesenswert?

Thomas: Derin Freund ist die Befehlsreferenz im AVR-Studio, dort werden
die Befehle, die du im Datenblatt in der Auflistung findest, recht
ausführlich erklärt.

von Thomas O. (Gast)


Lesenswert?

Hallo,

was sowas gibts direkt im AVR-Studio? Ich habe immer das Instruction
Set Datenblatt geöffnet. Wo soll das genau sein?

von Tobi (Gast)


Lesenswert?

cursor über befehl und F1

von Thomas O. (Gast)


Lesenswert?

Hallo,

danke, wieder was gelernt.

von ...HanneS... (Gast)


Lesenswert?

Oder zum Schmökern:
Help, AVR tools user guide, AVR assembler
Da findest du auch die Erklärung der Direktiven...

Ist aber eigentlich traurig, dass du noch nicht soweit vorgedrungen
bist...

...HanneS...

von Thomas O. (Gast)


Lesenswert?

nochmal kurz zu dem Thema.
bei einem ATTiny26 wir am Anfang ja der Stackpointer initialisiert.

init:    ;Stackpointer initialisieren
ldi temp, RAMEND
out SP, temp

RAMEND steht in der tn26def.inc mit dem Wert $DF drin. Da der ATTiny26
ja 128Byte SRAM hat sollte ja DF für 128 stehen mein Win-Taschenrechner
macht komischerweise dezimal 223 drauß.

wäre es hier möglich statt RAMEND($DF) nur 112 zu übergeben somit hätte
ich doch 16Bytes die nicht durch den Stack verwendet werden können und
dadurch einen abgesicherten Bereich darstellen, da ich 100%
sicherstellen will das diese Stellen nicht überschrieben werden auch
wenn mal für eine Interruptroutine nicht gepopt und gepusht wurde.

von Rolf Magnus (Gast)


Lesenswert?

> RAMEND steht in der tn26def.inc mit dem Wert $DF drin. Da der
> ATTiny26 ja 128Byte SRAM hat sollte ja DF für 128 stehen

Nein. Vor dem RAM kommen noch die ganzen Register. Steht alles im
Datenblatt:

"The lower 224 Data Memory locations address the Register File, the
 I/O Memory and the internal data SRAM. The first 96 locations
 address the Register File and I/O Memory, and the next 128
 locations address the internal data SRAM."

> mein Win-Taschenrechner macht komischerweise dezimal 223 drauß.

Klar. 13 * 16 + 15 = 223

> wäre es hier möglich statt RAMEND($DF) nur 112 zu übergeben

Dann hättest du aber nur 16 bytes für den Stack übrig, da das RAM erst
an Adresse 96 anfängt.

> somit hätte ich doch 16Bytes die nicht durch den Stack verwendet
> werden können und dadurch einen abgesicherten Bereich darstellen,
> da ich 100% sicherstellen will das diese Stellen nicht
> überschrieben werden auch wenn mal für eine Interruptroutine nicht
> gepopt und gepusht wurde.

Dir ist aber schon klar, daß dein Programm dann trotzdem nicht
funktionieren wird? Schließlich hast du damit auch nicht mehr Platz für
den Stack und überschreibst dann statt deiner Variablen dann halt die
I/O-Register, angefangen mit den Flags und (viel spaßiger) dem Stack
Pointer.

von Thomas O. (Gast)


Lesenswert?

Hallo,

nach deiner Erklärung müsste ich einfach statt 223 207 als RAMEND
setzen so das die letzen 16Bytes des RAMs wegfallen un das sollte den
Programmablauf, zudem der sehr einfach gestrickt ist nicht stören.

von Rolf Magnus (Gast)


Lesenswert?

Nicht als RAMEND, aber als Wert für SPL. Das Ende des RAM verschiebt
sich ja nicht.
Ich wage nur zu bezweifeln, daß das für die Robustheit deines Programms
wirklich was bringt, da:

a) wie gesagt, der Stack pointer eins der ersten Register ist, die
überschrieben werden, und dann zeigt der nachher sonstwo hin (z.B. auf
deine "geschützten" Variablen), und

b) wenn du mal ein push vergisst oder ein pop zuviel hast, läuft der
Stack Pointer auch munter nach oben, in den Bereich, für den du
eigentlich "100% sicherstellen" wolltest, daß er nie überschrieben
wird, und

c) weil es eh Wurscht ist, was im RAM steht, wenn dein Programm
amokläuft, einfriert oder andere typische Verhaltensmuster an den Tag
legt, die durch ungleiches push/pop so autfreten können.

von Thomas O. (Gast)


Lesenswert?

Hallo,

der Tiny26 kennt ja kein SPL und SPH sondern nur SP und damit stelle
ich doch den Bereich ein welcher für den Stackpointer zur Verfügung
steht.

Ein Stapelüberlauf wäre natürlich umbedingt zu vermeiden. Aber das
weglassen der push/pop Befehlen am Anfang/Ende einer Interruptroutine
würde hier überhaupt keine Probleme verursachen, weil hiervon doch nur
Register betroffen wären.

Pop und Push war jetzt vielleicht ein blödes Beispiel. Aber ich müsste
halt ein paar Sachen ablegen können und möchte dazu nciht das EEPROM
nutzen, weil es erstens sehr lange dauert und nach einer gewissen
Anzahl von Schreibzugriffen hinüber gehen wird.

von Hannes L. (hannes)


Lesenswert?

Im Prinzip ist das machbar.
Es schützt dich aber nicht vor Programmierfehlern
(Stack-über/unterlauf).

Trotzdem solltest du dir mal den Daten-Adressraum genauer ansehen, SRAM
beginnt nämlich (wie oben schon gesagt) nicht bei $00 sondern erst
hinter dem I/O-Bereich. Und das ist je nach Controller bei $60 oder
$100. Vor dem SRAM kommen also die 32 Register und die 64 I/O-Adressen
und evtl. noch die Extended-I/O-Adressen. Die Adressbereiche werden
aber in den Datenblättern anschaulich erklärt (Klötzchengrafik).

...

von Rolf Magnus (Gast)


Lesenswert?

> der Tiny26 kennt ja kein SPL und SPH sondern nur SP und damit

Ja, ist aber im Prinzip das gleiche.

> stelle ich doch den Bereich ein welcher für den Stackpointer zur
> Verfügung steht.

Du stellst damit den initialen Wert für den Stackpointer ein. Einen
Bereich legst du damit nicht fest. Bei jedem push wird der Stackpointer
um eins verringert, bei jedem pop um eins erhöht. Wenn du also irgendwo
ein pop hast, zu dem kein push existiert, läuft dein Stackpointer
munter nach oben, Richtung RAMEND, und deine Variablen werden
überschrieben.

> Ein Stapelüberlauf wäre natürlich umbedingt zu vermeiden.

Genau. Wenn dir das klar ist, wozu willst du dann den Stackpointer auf
16 byte vor RAMEND initialisieren? Das hilft überhapt nicht gegen einen
Überlauf.

> Pop und Push war jetzt vielleicht ein blödes Beispiel. Aber ich
> müsste halt ein paar Sachen ablegen können und möchte dazu nciht
> das EEPROM nutzen, weil es erstens sehr lange dauert und nach
> einer gewissen Anzahl von Schreibzugriffen hinüber gehen wird.

Ja, und wo ist nun das Problem? Dafür legst du einfach Variablen an,
und zwar am Anfang vom RAM.

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.