Ich meine mal gelesen zu haben, das es bei den Atmel 8-Bit Prozessoren bzw. vielleicht nur bei einigen Modellen, Register gibt, die man benutzen kann um dort Werte abzulegen. Ich meine jetzt natürlich nicht die Register R0 bis R31. Die sind klar. Ich glaube es waren auch nicht die unbenutzten I/O-Register, zu denen das Datenblatt sagt, das sie niemals geschrieben werden dürfen. Hat jemand mal sowas gelesen und weiss noch wo und was dort genau steht? Ich habe das Problem, das ich einen 16-Bit Wert ablegen muss, der zur Laufzeit effizient benutzbar sein soll. EEPROM oder RAM kann ich definitiv dafür nicht benutzen. EEPROM ist zu langsam. Und RAM geht in dem Zusammenhang nicht, weil ich gerade einen Zeiger speichern will, der in das RAM zeigt. Das würde sich in den Schwanz beissen, da ich ja die Adresse des Zeigers in das RAM, der im RAM abgelegt ist ja wiederum kennen müsste. Lege ich also den im RAM ab, müsste ich wenigstens dessen Adresse kennen usw. Klar? Wäre wirklich sehr nett, wenn da jemand einen Tip hätte.
Na klar legst Du den ins RAM, aber eben an eine fixe Adresse und dann kannst du überall ins RAM damit hinzeigen. Nur auf sich selbst macht das keinen Sinn, geht aber auch
Hi ATMega 1280/1281 besitzen z.B. GPIOR0..2 als allg. nutzbare Register in IO-Bereich. Was hindert dich im RAM feste Speicherstellen für den Zeiger zu benutzen? Angaben zum Controller und Programmiersprache wären sehr hilfreich. MfG Spess
1 | .dseg |
2 | ZEIGER: |
3 | .byte 1 |
4 | .cseg |
5 | |
6 | |
7 | add |
8 | subb |
9 | |
10 | LDS TMP, ZEIGER ;Pointer dirket laden |
11 | |
12 | cp |
13 | brne |
14 | |
15 | |
16 | STS ZEIGER, TMP ; Pointer wieder zurückspeichern |
@W.
>Na klar legst Du den ins RAM, aber eben an eine fixe Adresse
Gerade das will ich eben nicht. Im allgemeinen würde ich das natürlich
so machen.
@Läubi
Dein Code ist schon klar (ist ja der normale Weg), aber dann liegt ja
der Zeiger im RAM. Und das will ich ja nicht.
Ich schrieb: Und RAM geht in dem Zusammenhang nicht, weil ich gerade
einen Zeiger speichern will, der in das RAM zeigt.
Das ist, wie mir Eure Antworten zeigen nur die halbe Begründung.
Es geht darum, das sämtliche im RAM abgelegten Werte verschieblich
sein sollen. Mein ominöser Zeiger soll auf den ersten dieser Werte
zeigen, von dem aus dann auf alle weiteren zugegriffen wird.
D.h. ich kenne keine absolute Adresse in dem RAM.
Das erstemal lade ich diese Adresse vom EEPROM, aber da ich den Zeiger
sehr oft brauche wäre es ineffizient, den jedesmal aus dem EEPROM zu
laden.
Das mit den GPIO ist eine Lösung, aber leider nur für einige (sogar
ziemlich viele) Modelle. Leider aber z.B. nicht für den 162er.
Hat noch jemand eine Idee?
Die vom Timer 1 z.B. .... kann man hier auch im Tut. nachlesen mfg.
@Ulli K.
>Die vom Timer 1
Geht leider nicht, da die Timer benutzt werden. Auch die andere
Peripherie wird benutzt.
Ich würde die Startadresse immer so wählen, dass der Zeiger immer noch vorne dran paßt. Dann spricht auch nichts dagegen, diesen Zeiger aus dem EEPROM zu laden und ins RAM zu legen, wenn alle anderen Werte dahinter abgelegt werden. Gruß Matthias
@ Matthias
Ich bin nicht ganz sicher ob ich Dich verstehe.
>Ich würde die Startadresse immer so wählen...
Das würde heissen, das die Startaddresse nicht beliebig sein kann,
weil ja immer wenigsten Platz für den Zeiger sein muss.
Egal ob vorne, hinten oder mittendrin.
Das aber geht nicht, bzw. ist eine Einschränkung die ich nicht will.
Der Zeiger soll garnicht RAM liegen. Der gesamte Bereich muss
verfügbar bleiben.
>Das ist, wie mir Eure Antworten zeigen nur die halbe Begründung. >Es geht darum, das sämtliche im RAM abgelegten Werte verschieblich >sein sollen. Mein ominöser Zeiger soll auf den ersten dieser Werte >zeigen, von dem aus dann auf alle weiteren zugegriffen wird. >D.h. ich kenne keine absolute Adresse in dem RAM. Das klingt nach dynamischen Listen mit dynamischen Längen. Ich mache das dann so, dass ich der Liste eine Referenz voranstelle. Beispielsweise besteht deine Liste aus x-Elementen mit mit verschiedenen Längen.
1 | Liste1: x1[0..L1] |
2 | Liste2: x2[0..L2] |
3 | Liste3: x3[0..L3] |
4 | ...
|
5 | Liste9: x9[0..L9] (letzte Liste. Max 9 stück möglich) |
Dann lege ich eine Struktur mit folgendem Inhalt an:
1 | - Anzahl max Listen |
2 | - Start Liste1 |
3 | - Start Lsite2 |
4 | - Start Liste3 |
5 | - ... |
Also für das Beispiel sieht das dann so aus:
1 | 9,&x1,&x2,&x3,...,&x9 |
Diese Referenz musst du natürlich so speichern, dass du weißt, wo diese Referenz beginnt.
Hmm...gibt es einen bestimmten Grund, dass dein gesamtes RAM verschiebbar sein muss? Wenn nicht, dann könntest du am Anfang einen nicht-verschiebbaren Bereich definieren, in den du dann eben diesen Wert speicherst. Ansonsten solltest du darüber nachdenken, dein Konzept dahingehend zu ändern, dass eben ein nicht-verschiebbarer Bereich am Anfang irgendwie möglich wird.
Hi >Der Zeiger soll gar nicht RAM liegen. Der gesamte Bereich muss verfügbar >bleiben. Und wo bleibt dein Stack? Evtl. den Stack nicht am RAMEND initialisieren, sondern ein paar Bytes darunter. Die freien Speicherplätze oberhalb des Stacks benutzen. MfG Spess
@ Matthias >Das klingt nach dynamischen Listen mit dynamischen Längen. Mit Listen hat das nichts zu tun. Aber selbst wenn, dann wäre es so, als wenn der Beginn der beschreibenden Struktur verschieblich sein muss. @ mr.chip >Hmm...gibt es einen bestimmten Grund, dass dein gesamtes RAM verschiebbar sein muss? Ja, den gibt es. @ Spess53 >Und wo bleibt dein Stack? Der wird an einer Stelle relativ zu dem fraglichen Zeiger angelegt. Ich möchte bitte nochmal auf die Ausgangsfrage zurückkommen: Hat vielleicht noch jemand eine Idee, die sich auf die Frage nach einem Register bezieht?
Vielleicht solltest du erstmal erklären, was du vorhast. Da kommen dann vielleicht Antworten die dir weiterhelfen. Sonst wirst du nicht mehr erwarten können, als du schon gehört hast...
@ Matthias
>Vielleicht solltest du erstmal erklären, was du vorhast.
Ich will einen Zeiger aus dem EEPROM lesen und in einem Register oder
Ähnliches, das aber kein GPIO sein darf (weil das einige Modelle nicht
können), ablegen. Hingegen will ich den Zeiger nicht im RAM an einer
festen (zur Assemble-Zeit bekannten) Adresse ablegen. Sämtliche
Peripherie muss weiter benutzbar bleiben.
Und warum tut es keine normale (Pointer)Variable? Die wird zwar im (internen) RAM abgelegt, aber, mein Gott, zwei Bytes...
dann ordne dem Zeiger ein/zwei feste Register zu. Ich verstehe zwar auch nicht wozu das Ganze eigentlich gut sein soll und sehe keinen konkreten Anwendungszweck bei dem das Sinn macht. >@ Matthias >>Vielleicht solltest du erstmal erklären, was du vorhast. Deine Antwort beantwortet nicht die Frage. Fürwas benötigst du den ganzen Aufwand ? Die Frage läuft darauf hinaus das man öfters ein Brett vorm Kopf hat und sich in eine viel zu komplizierte Lösung eingeschossen hat ohne das Offensichtliche dabei zu sehen. Ergo: erkläre dein gesamtes Vorhaben im kompletten Kontext. Gruß Hagen
> aber, mein Gott, zwei Bytes...
Sehe ich auch so. Pack den Zeiger doch unter den Stack, der ist ja eh
variabel groß.
Wenn Du dann Dein gesamtes RAM adressieren musst, dann adressierst Du
halt den Stack mit und Deinen Zeiger auch. Richtig Sinn macht das aber
nicht.
Es ist schwer das im Text 'rüberzubringen, aber mit allem schuldigen Respekt und entsprechender Höflichkeit: Ich bin ja dankbar dafür, dass Ihr Euch Alternativen überlegt. Aber bedenkt bitte und seid versichert, dass ich mir selbst genau überlegt habe, welche Frage ich stelle. Bitte geht einfach von der Ausgangsfrage aus. Wozu ich das dann brauche ist eine ganz andere Frage, die ich (immer noch höflich und respektvoll gesagt) hier nicht diskutieren möchte.
>Bitte geht einfach von der Ausgangsfrage aus. Wozu ich das dann brauche >ist eine ganz andere Frage, die ich (immer noch höflich und respektvoll >gesagt) hier nicht diskutieren möchte. Wir wollen deine Gedanken auch nicht in Frage stellen, sondern einfach wissen was du vorhast. Sonst können wir dir keine sinnvollen Antworten dazu geben, weil dann mehr geraten bzw in Blaue hinein geantwortet werden muss. Es geht auch nicht darum, das wir hier (auf Teufel komm raus) Alternativen suchen wollen, sondern wir verstehen einfach nicht, was das soll und wozu das nötig ist. Demzufolge werden wir auch keine weiteren Antworten geben können. Also zwei Möglichkeiten: 1) Du sagst nicht was du (konzeptionell) vorhast, und gibst dich mit den Antworten zufrieden. 2) Du erzählt, was du konzeptionell vorhast (musst ja das Projekt nicht verraten), und dann können wir das nachvollziehen und Lösungsvorschläge bringen.... PS: Ich habe auch schon Beiträge verfasst, in denen ich Hilfe benötigt habe. Dort habe ich auch erklärt, was ich vorhabe, ohne zu "verraten" was ich genau bauen/konstruieren will...
>>Der Zeiger soll garnicht RAM liegen. Der gesamte Bereich muss >>verfügbar bleiben. >>ist eine ganz andere Frage, die ich (immer noch höflich und respektvoll >>gesagt) hier nicht diskutieren möchte. Registersucher, Kein Mensch will Dir hier in die Karten gucken, oder geistiges Eigentum klauen, keine Sorge! Aber den GESAMTEN RAM zu okkupieren geht eben nicht (wie mehrfach gesagt wurde), weil Du dann keinen Platz für den Stack mehr hast. Und 2-Bytes oberhalb des Stack für deine Zwecke fix zu reservieren ist eine sinnvolle Antwort auf Deine Frage. Tu gedanklich doch einfach so, als wäre Dein Stack eben 2Byte grösser, wo soll da das Problem sein? Wenn Du mit einem Anliegen kommst, das in den Augen der meisten erfahrenen Programmierer erstmal absurd erscheint, dann musst Du schon gestatten, dass nach dem Hintergrund gefragt wird. Jochen Müller
.equ mein_pointer_hi = high(RAMEND) .equ mein_pointer_lo = low(RAMEND) .equ mein_stackanfang_hi = high(RAMEND-2) .equ mein_stackanfang_lo = low(RAMEND-2) So in der Art. Dein Pointer steht dann sicher an einer fixen Adresse und der Stack wächst nach unten. Effektiv ist Der Stack dann eben 1 Word grösser. Jochen Müller
Andreas schrieb: >klingt nach betriebsystem. Na, das wäre z.B eine Möglichkeit. @ Jochen .equ geht nicht, da dann der Pointer an einer festen Stelle liegt. >weil Du dann keinen Platz für den Stack mehr hast Stack ist vorhanden. Er liegt nur eben nicht an einer festen Stelle.
Andreas W. wrote:
> klingt nach betriebsystem.
Dann ist es allerdings völlig unverständlich, warum die Variablen des
Betriebssystems nicht an konstanten Adressen liegen dürfen. Ich behaupte
mal, bei Windows ist das so.
Peter
Warum behältst du den blöden Zeiger nicht einfach in XH:XL, wenn du ihn nirgends abspeichern kannst? Ansonsten: Wie schon zehnmal gesagt: Denk dir, die letzten beiden Bytes deines RAMs seien kaputt/nicht existent/was auch immer und leg den Zeiger dadrinne ab. Die restliche Programmlogik tut dann so, als obs diese beiden Adressen garnicht gäbe.
@ All Also die Antworten die ich hier lese haben ja wirklih nichts mit Frage im ersten Post zu tun. Da muss ich dem Poster schon recht geben. Und was er damit anfangen will ist auch egal. Weil es nämlich definitv ausser den R0-R31, den GPIO und den Kontrollregistern für die UARTS und Timers usw. keine Möglichkeit gibt irgendwo noch was zu speichern. Die reserved Register können auch nicht benutzt werden. Also vergiss es.
Thomas Mahn wrote: > Weil es nämlich definitv ausser > den R0-R31, den GPIO und den Kontrollregistern für die UARTS und Timers > usw. keine Möglichkeit gibt irgendwo noch was zu speichern. Das ist uns allen ja schon lange klar. > Also vergiss es. Nun man wollte eben über diese Antwort hinaus behilflich sein. Aber wenn die Hilfe nicht erwünscht ist, dann muß es bei dem: "Also vergiss es." bleiben und gut is. Peter
@peter nicht deswegen, sondern alles wird benutzt und ram muss dynamisch sein. deswegen.
Es geht dir nur darum, den gesamten verwendeten Speicher zu "verschieben", oder? Verwende einfach den Stackpointer dafür, dann kann dir der Compiler auch noch alle Arbeit abnehmen. Also: Programm einfach komplett ohne Globale Variablen schreiben, alles auf den Stack. Vor dem Programmstart Stackpointer entsprechend initialisieren, und alle verwendeten Adressen sind dann relativ zu dem. Und die ganze Adressberechnung im Hintergrund macht der Compiler.
1) Größere µC habe als Zeiger auf GOT (global offset table) etc ein eigenes GPR, dass dafür dient und von der Applikation nicht verwendbar ist. 2) Ich vermute mal es geht um Atmal AVR (Atmel hat auch 8051). Du kannst den Wert per Bootloader ins Flash schreiben und per LPM effizienter drauf zugreifen als auf EEPROM. 3) Ich verstehe immer noch nicht, warum das Ding nicht im internen RAM an einer fixen Adresse stehen kann. Im internen RAM kann man bei AVR doch eh nix drehen, was Startadresse etc. angeht. Wenn es ein Memory-Management sein soll, kämen die anderen Daten eh in ne andere Section.
Registersucher, Ich mache trotzdem nochnmal eine Anlauf, weil es trotz längerem Erwägen einfach schlichtweg nicht einleuchtet was Du an den bisherigen Ideen zu bemängeln hast. Ich argumentiere mal anders herum: Du kaufst einen AVR für Dein Projekt und der hat z.B. 8192 Byte SRAM zu bieten. So. Dafür entwirfst Du nun Dein Projekt. Ok. Wenn der AVR nun aber werkseitig nur 8190 statt 8192 Byte SRAM gehabt hätte, dann hätte also Dein ganzes Projekt nicht funktioniert? Und wäre auch niemals zum klappen zu bringen, nur wegen dieser 2 Byte??? Sorry, das kann einfach niemand glauben. Was hindert Dich denn nun KONKRET daran, einfach zu zu tun, als hätte der AVR eben nur 2-Byte weniger SRAM als im Datenblatt stehen? Viele Leute haben sich hier die Zeit genommen, für DICH Vorschläge zu machen, die hätten eine nachvollziehbare Antwort auf diese BERECHTIGTE Frage absolut verdient! Kein Mensch möchte sich gerne veralbern lassen! Und DU bist nun mit einer venünftigen Erklärung am Zug! Jochen Müller
Wenn im Datenblatt kein Speicher für solche Zwecke ausgewiesen ist, dann geht sowas eben nicht. Abgesehen davon sind die I/O-Register auch so etwas ähnliches, wie RAM - auch wieder mit einer festen Adresse, aber das willst Du ja nicht. Und mit "illegalen Speicherstellen" (analog zu den "illegalen Opcodes" bei manchen µP) kannst Du auch nix anfangen - die könnten bei einer überarbeiteten Release des µC plötzlich wieder weg sein. Mir fällt nur eine Antwort ein: Dein völlig konfuses Konzept ist auf einem AVR nicht realisierbar.
Vielleicht soll die Software auch auf uCs mit mehr RAM laufen ohne neu kompiliert zu werden? Wie auch immer. Wenn ich es richtig verstanden habe, will der Fragensteller den Pointer nicht im Flash ablegen, weil der Zugriff zu lange dauert, oder? Wieviele Takte spart man bei einem Zugriff auf den RAM?
@ Jochen
>was Du an den bisherigen Ideen zu bemängeln hast
1. Sie beziehen sich nicht auf die ursprüngliche Frage
2. Sie setzen voraus das ich in meinem Programm eine feste Adresse für
irgendwas habe.
Da sich die Fragen darauf fokussieren, was ich denn gegen nur zwei Byte
im RAM habe, möchte ich noch folgendes erläutern: Die Anzahl von Bytes
ist hier gar nicht entscheidend. Es könnten auch 10 sein und das gäbe
kein Problem. Das Problem ist vielmehr, das überhaupt eine
Speicherstelle fest kodiert im Programm vorhanden ist.
Wie sicherlich einsichtig ist, würde das sofort gehen, wenn ich den
fraglichen Zeiger in zwei der Register R0 bis R31 halten könnte. Dann
bräuchte es auch keine im RAM feststehende Adresse.
Das Problem ist nun, das ich bereits alle Register verwende. Ich kann
zwar, wenn es darauf ankommt, mal kurz ein Registerpaar auf dem Stack
ablegen, aber ich kann es nicht dauernd dort halten, weil ich öfter den
eigentlichen Inhalt von R0 bis R31 brauche als diesen Zeiger.
>>Wie sicherlich einsichtig ist, würde das sofort gehen, wenn ich den >>fraglichen Zeiger in zwei der Register R0 bis R31 halten könnte. Dann >>bräuchte es auch keine im RAM feststehende Adresse. Ich kapiere es einfach nicht... Die Register haben DOCH AUCH FESTE Adressen. Warum soll es also in Registern gehen, an festen SRAM-Adressen aber nicht? Jochen Müller
Registersucher wrote: > Das Problem ist nun, das ich bereits alle Register verwende. Ich kann > zwar, wenn es darauf ankommt, mal kurz ein Registerpaar auf dem Stack > ablegen, aber ich kann es nicht dauernd dort halten, weil ich öfter den > eigentlichen Inhalt von R0 bis R31 brauche als diesen Zeiger. Dein Programm verwendet also einen Stack. Und wie initialisierst du den, wenn in deinem Programm keine fest kodierten Speicherstellen vorhanden sein dürfen?
@ Jochen >...an festen SRAM-Adressen aber nicht? Das liegt an der Forderung an das Projekt. Es soll keine festen Adressen geben. Sie müssen verschieblich sein, ohne das das Programm neu assembliert wird, indem man die fraglichen Adressen im EEPROM ablegt. >Register haben DOCH AUCH FESTE Adressen Mag sein, aber das Projekt verlangt ja auch nicht das Register verschoben werden können. Stell Dir doch mal folgendes Szenario vor: Ein Bereich im RAM soll beliebig verschoben werden können. Er enthält irgendwelche Werte. Du lädst also aus dem EEPROM dessen Adresse im RAM. Die Werte in dem Bereich addressierst Du über einen Offset der fest im Programm kodiert ist, zu dem Du dann noch die Anfangsadresse addierst. Du kannst natürlich diesen Offset auch in dem RAM, in dem verschieblichen Bereich speichern. Aber sobald Du die Adresse nicht mehr in einem der CPU-Register hast, weisst Du nicht mehr wo Du zugreifen musst.
@ Stefan
>Dein Programm verwendet also einen Stack. Und wie initialisierst du den
Indem ich die Stack-Startadresse aus dem EEPROM lese und dann in das
Stackpointeregister schreibe.
Aus dieser Erklärung entnehme ich, das du KEINERLEI Variablen (außer der r0..r31) verwendest? Bzw verwenden DARFST/MUSST/KANNST... Sehe ich das richtig?
>>Du kannst natürlich diesen Offset auch in dem RAM, in dem >>verschieblichen Bereich speichern. Aber sobald Du die Adresse nicht mehr >>in einem der CPU-Register hast, weisst Du nicht mehr wo Du zugreifen >>musst. Du sollst deinen Pointer ja auch in 2 RESERVIERTEN BYTES SRAM halten, DIE NICHT VERSCHOBEN WERDEN. Du stellst Dich einfach dumm, und TUST SO, als hättest Du nicht 32 Register, sondern 34. Die beiden zusätzlichen liegen eben einfach im SRAM an einer IMMER FESTEN STELLE. Lediglich die Befehle zum Zugriff lauten etwas anders, also LDS/STS anstatt LDI etc. DU BASTELST DIR EINFACH ZUSÄTZLICHE REGISTER, das ist der ganze Trick. Dem Rest der Software LÜGST DU EINFACH VOR, den nichtverschieblichen SRAM-Bereich (wo dein Pointer steht) GÄBE ES SCHLICHTWEG NICHT. Jochen Müller
@ Matthias >Aus dieser Erklärung entnehme ich, das du KEINERLEI Variablen (außer der >r0..r31) verwendest? >Sehe ich das richtig? Nein, nicht ganz. Die Variablen die ich verwende sollen in meinem Programm als Offset zu dem fraglichen Zeiger kodiert sein.
@ Jochen >Du sollst deinen Pointer ja auch in >2 RESERVIERTEN BYTES SRAM halten, DIE NICHT VERSCHOBEN WERDEN. Das habe ich schon verstanden. Aber das widerspricht eben der Forderung, das alles RAM frei konfigurierbar ist. Das wäre es nicht, wenn es auch nur eine fest kodierte Adresse gäbe. Weil dann dieser Bereich wo der Zeiger steht nicht verwendet werden dürfte.
>Die Variablen die ich verwende sollen
Und wo und wie werden die abgelegt?
@ Matthias
>Und wo und wie werden die abgelegt?
Bitte verzeih', aber was an:
"Die Variablen die ich verwende sollen in meinem
Programm als Offset zu dem fraglichen Zeiger kodiert sein."
war unklar?
Sie werden im RAM per STS/LDS benutzt.
>>nur eine fest kodierte Adresse gäbe. Weil dann dieser Bereich wo der >>Zeiger steht nicht verwendet werden dürfte. Du hast aber etwas weiter oben selbst gesagt, es käme nicht darauf an ob nun ein paar Byte weniger SRAM verfügbar sind oder nicht. Warum stört es dann, wenn 2 Bytes SRAM nicht verwendet werden dürfen? Geht das eigentlich um eine praktische Anwendung, oder ist das eher ein theoretischen Konzept einer Architektur? Nur dann wären Deine Einschränkungen nämlich überhaupt einsehbar. Jochen Müller
Hi >Das Problem ist nun, das ich bereits alle Register verwende. Ich kann... Mal ehrlich, selbst bei großen Programmen ist es bei mir noch nicht vorgekommen, daß ich alle Register benötigt habe. AVRs sind mit 32 Registern mehr als üppig ausgestattet. Also wenn sich da nicht 2 für diesen Zweck finden lassen, solltest du vielleicht mal deinen Programmierstil überprüfen. MfG Spess
@ Jochen >>>nur eine fest kodierte Adresse gäbe. Weil dann dieser Bereich wo der >>>Zeiger steht nicht verwendet werden dürfte. >Du hast aber etwas weiter oben selbst gesagt, es käme nicht darauf an ob >nun ein paar Byte weniger SRAM verfügbar sind oder nicht. Warum stört es >dann, wenn 2 Bytes SRAM nicht verwendet werden dürfen? Nun gut. Ich hätte präziser formulieren sollen: "Weil dann irgendein Bereich, nämlich der wo Zeiger steht, nicht verwendet werden dürfte."
@ Jochen
>Geht das eigentlich um eine praktische Anwendung
Ja.
da will wohl einer so ne Art Kopierschutz entwickeln... ...das wird nix! aber man kann ja mal die Adressbereiche durchprobieren. ev. gibts ja noch verborgene Register. Die haben aber sicher seiteneffekte... Also nix was man nutzen könnte.
Was ist mit den EIND RAMPZ Registern im IO-Space? Solange Du kein externes RAM verwendets und eicalls vermeidest, sind die doch ungenutzt. Jochen Müller
Mensch, lager den Zeiger doch auf einen externen RAM-Baustein aus!
Da du offenbar jede Resource jedes Microcontrollers der AVR Serie entweder bereits anderweitig verwendet hast oder weil nicht auf allem Modellen verfügbar nicht verwenden darfst, dann suchst du also nach einer Resource, die noch nie jemand verwendet hat und die daher höchstwahrscheinlich niemand kennt. Also: Hol dir ein FPGA deiner Wahl, baue die darin den gewünschten AVR Controller auf und füge die fehlende Resource hinzu. Oder stelle fest, dass, wenn alle Resourcen bereits verwendet oder per Vorgabe unverwendbar sind, per Definition keine mehr übrig sein können.
Jochen Müller wrote: > EIND > RAMPZ Gibt es beim '162 m.W. auch nicht.
Es hat leider niemand meine Frage beantwortet. Rein aus Interesse: Um ca. wieviele Takte ist der Zugriff auf den SRAM schneller als auf den Flash?
@ Jochen
>Was ist mit den EIND RAMPZ Registern im IO-Space?
Die werden leider gebraucht. Und RAMPX und RAMPY auch, falls vorhanden.
> Das liegt an der Forderung an das Projekt Mich dünkt, hier geht's um ziemlichen Hack... das eigentliche Problem scheint die Konzeption des Projekts zu sein. > Hingegen will ich den Zeiger nicht im RAM an einer > festen (zur Assemble-Zeit bekannten) Adresse ablegen. Adressen werden doch in der Regel erst zur Linkzeit vergeben, also muss nicht neu assembliert werden. Und wer konstante Adressen in seinem Programm verwendet -- ausser natürlich für SFR-Bereich etc -- ist selber schuld. Hier kann es sich doch nur um Tasks in einem OS handeln oder um einen dynamischen Lader etc. Die dyn. Module sind ram-offsettable, aber das bedeutet doch nicht, dass das auf den Loader/OS zutreffen muss. Wenn es dem Projekt gefällt, dann gehören die 2 Bytes eben per Definition nicht zum RAM; sondern nenn den Bereich Hasenboppes. Der Bereich ist ja auch nicht frei (random) zugreifbar im Sinne der Anwendung. Du hast immer noch die Möglichkeit über nen Bootloader zu schreiben. Das dauert einmal beim Schreiben. Lesen geht ähnlich effizient wie aus dem RAM, aber eben nur indirekt. Und wenn das nicht geht, musst eben in den sauren Apfel beissen und immer wieder aus dem EEPROM lesen.
Registersucher wrote:
> Die werden leider gebraucht. Und RAMPX und RAMPY auch, falls vorhanden.
Wenn ich jetzt ein I/O-Register der '162 (oder welchem Modell auch
immer) nach dem anderen so aufzähle: Meinst du es bleibt eines übrig,
bei dem du nicht ebendiese Antwort lieferst?
Wenn ich damit recht habe, suchst du etwas was nicht existent oder
zumindest nicht dokumentiert ist. Wenn ich damit nicht recht habe,
kannst du diese Prozedur genausogut selber durchführen.
@ Maxim >Mensch, lager den Zeiger doch auf einen externen RAM-Baustein aus! Das selbe Problem. Falls externes RAM verfügbar ist, sollen darin doch keine festen Adressen verwendet werden. >Es hat leider niemand meine Frage beantwortet. Rein aus Interesse: Um >ca. wieviele Takte ist der Zugriff auf den SRAM schneller als auf den >Flash? Ein LPM dauert 3 Zyklen gegenüber 2 Zyklen für ein LDS.
Registersucher wrote:
> Ein LPM dauert 3 Zyklen gegenüber 2 Zyklen für ein LDS.
...und ist damit zu langsam?
Registersucher wrote: > @ Matthias > >>Und wo und wie werden die abgelegt? > > Bitte verzeih', aber was an: > "Die Variablen die ich verwende sollen in meinem > Programm als Offset zu dem fraglichen Zeiger kodiert sein." > > war unklar? > > Sie werden im RAM per STS/LDS benutzt. Das passt aber nicht ins Konzept, denn die Zugriffsadressen von STS/LDS lassen sich nicht verschieben, deren Zugriffsadresse ist im Programmcode notiert, ist also fest. ...
Naja, sind immerhin 50% mehr. Dürfte aber wohl nur bei extrem intensiver Speichernutzung eine Rolle spielen.
@ Andreas >Wenn ich jetzt ein I/O-Register der '162 (oder welchem Modell auch >immer) nach dem anderen so aufzähle: Meinst du es bleibt eines übrig, >bei dem du nicht ebendiese Antwort lieferst? Es werden auch sämtliche Peripheriekontrollregister gebraucht. Die Frage ist jedenfalls ernst gemeint. Das sollte auch auf möglichst vielen Modellen gehen. Zumindest auf denen, die mehr als 8k Flash haben.
Auf das Risiko hin, mich zu wiederholen, mal den Kern der Sache zusammengefasst: -a- Alles was sämtliche Modelle der AVRs haben ist bereits verwendet und kommt folglich nicht in Frage. -b- Alles was nicht sämtliche Modelle der AVRs darf genau deshalb nicht verwendet werden. -c- Die einzige noch nicht explizit ausgeschlossene Resource, das ROM, ist zu langsam. => Das Problem ist unlösbar.
Ich glaube da versucht uns jemand mächtig auf die Arme zu nehmen....
@ Hannes >Das passt aber nicht ins Konzept, denn die Zugriffsadressen von STS/LDS >lassen sich nicht verschieben, deren Zugriffsadresse ist im Programmcode >notiert, ist also fest. Ja. Tut mir leid. Ein Flüchtigkeitsfehler. Muss natürlich ST/LD heissen.
@ Andreas >-a- Alles was sämtliche Modelle der AVRs haben ist bereits verwendet und >kommt folglich nicht in Frage. Das ist ja gerade die Frage, ob schon alle Möglichkeiten genutzt sind. Auch auf die Gefahr hin, mich zu wiederholen: 1. Peripherie wird schon verwendet. 2. R0 bis R31 wird schon verwendet. >-b- Alles was nicht sämtliche Modelle der AVRs darf genau deshalb nicht >verwendet werden. Das würde ich in dieser Schärfe nicht bestätigen. GPIORX ist schon eine gute Lösung, wenn auch ein wenig langsam, weil die erst umgeladen werden müssen, damit sie als Argument für ST/LD taugen. Aber auf denen die kein GPIORX haben muesste halt ne andere Lösung her. >-c- Die einzige noch nicht explizit ausgeschlossene Resource, das ROM, >ist zu langsam. Falls Du FLASH oder EEPROM meinst: Ja. >=> Das Problem ist unlösbar. OK. Das ist also Deine Antwort. Gibts noch andere Meinungen?
Simon K. wrote:
> Ich glaube da versucht uns jemand mächtig auf die Arme zu nehmen....
Und das mit großem Erfolg, möchte man meinen.
Hi schließe mich lippy an. Letzte Frage: Wie kann man so etwas essentielles bei der Programmkonzeption vergessen? MfG Spess
@ Thomas & Simon >> Ich glaube da versucht uns jemand mächtig auf die Arme zu nehmen.... >Und das mit großem Erfolg, möchte man meinen. Ich versichere, das die Frage ernst gemeint ist. Kein Scherz. Kein doppelter Boden. Bitte glaubt mir das.
Registersucher wrote: > Ich versichere, das die Frage ernst gemeint ist. Kein Scherz. Kein > doppelter Boden. Bitte glaubt mir das. Dann hat vielleicht jemand dich gehörig auf den Arm genommen ;-)
Soll das eigentlich ein Pentium-II Emulator für den Atmel-Mega-8 werden? Sags ehrlich! Jochen Müller
Mal ne doffe Frage aber wenn du eh das EEProm verwendest, warum liest du dann nicht den wert daraus? Lesen aus dem EEProm dauert doch auch nur 2 Takte (Readbefehl + in) Oder nutz den EEPromAdresspointer als "hilfsregister". Oder erlaub keine Unterprogrammaufrufe und nutz den Stackpointer ;)
@ Spess53
>Wie kann man so etwas essentielles bei der Programmkonzeption vergessen?
Das frage ich mich auch. Aber der Kunde ist halt König. Ich hätte mir
das auch lieber erspart.
Ach ja: Eine Resource, die zwar schon erwähnt wurde, aber wohl nicht als Lösung: Der Stack-Pointer. Ok, CALL/RETURN kannst du dann knicken und Modelle bis 256 Bytes RAM auch, aber ansonsten erfüllt der alle Forderungen. ;-)
>>Aber der Kunde ist halt König. Ich hätte mir >>das auch lieber erspart. Ich betrachte meine Kunden ehrlich gesagt eher als Partner und nicht als Monarchen, alleine schon wegen der Sinnhaftigkeit der Kommunikation... Aber dennoch: Wenn der Kunde auf einmal verlangt, man solle die Schwerkraft mal eben für das Projekt abschalten... ...dann ist der Kunde kein König, sondern ein Idiot. Jochen Müller
@ Jochen >Soll das eigentlich ein Pentium-II Emulator für den Atmel-Mega-8 werden? >Sags ehrlich! Da hast Du mich doch glatt zum Lachen gebracht. ;-) @ Läubi Das würde halt jedesmal 10 Zyklen brauchen (2 Bytes) und da der Wert doch oft gebraucht wird, geht das ganz schön auf die Geschwindigkeit. Stackpointer wird gebraucht weil Unterprogramme vorhanden. EEProm Register werden gebraucht. Falls das jemand fragen will: Die Flash Lese/Schreibregister auch.
Jochen Müller wrote: > Wenn der Kunde auf einmal verlangt, man solle die Schwerkraft mal eben > für das Projekt abschalten... Verglichen mit diesem Problem erscheint mit das geradezu trivial. Denn Lösungen dafür sind hinlänglich bekannt und werden routinemässig genutzt.
Registersucher wrote:
> Stackpointer wird gebraucht weil Unterprogramme vorhanden.
Die kann man auch anders realisieren.
Hi Wer ist der Programmierer? Du oder der Kunde? Wer legt die Registerbelegung fest? .... Mf Spess
>>Ach ja: Eine Resource, die zwar schon erwähnt wurde, aber wohl nicht als >>Lösung: Der Stack-Pointer. Ok, CALL/RETURN kannst du dann knicken und Aber ohne Scheiss: Möglich wäre das grundsätzlich schon. Er könnte sich eine Art privaten Stack für rücksprungadressen bauen, und dann über indirekte calls arbeiten. kostet aber einigen overhead, und er zählt doch eh schon die takte.... der private-stackpointer liegt dann natürlich im relationalen teil des sram und muss erst mit der basisadr. behaftet werden... mir wird übel... Jochen Müller
Auf die Gefahr hin, mich unbeliebt zu machen: Bei den 8051ern hast du intern als RAM zur Verfügung: - 128Byte direkt adressierbar (vergleichbar mit R0 bis R31, nur mehr) - 128Byte indirekt adressierbar (können mit bes. Befehlen wie R0 bis R31 genutzt werden) Zusätzlich hast du bis zu 64kByte ext. RAM (meist aber schon ext.RAM im Chip mit drin). Die Pointer für den ext. RAM liegen nicht wie beim AVR in den int. Registern R0 bis R31, sondern extra. Es gibt Derivate mit bis zu 8 Pointern. Wie wäre es damit? Das sollte dein Problem doch lösen, oder? Du hast genügend RAM für deine festen Variablen (wie du die in R0 bis R31 hast) und zusäztlich noch 8 Pointer für deinen dynamischen RAM, ohne dass du Speicherstellen im ext. RAM "verschleuderst" oder int. RAM verlierst.
@ Spess53 >Wer legt die Registerbelegung fest? Ich. Aber der Kunde legt fest, das das der Speicher frei konfigurierbar sein soll. @ Andreas >Die kann man auch anders realisieren. Das wäre im Prinzip eine Möglichkeit. PUSH/POP ist aber so eine der am häufigsten ausgeführten Operationen in meinem Programm. Das würde wahnsinnig auf die Geschwindigkeit gehen.
Warum soll der Speicher eigentlich "frei konfigurierbar" sein? Der Speicher liegt doch im AVR immer an einer bestimmten Stelle und verschiebt sich doch nicht zwischendurch.. Oder gibts da drauf auch keine Antwort?
Frage einfach Deinen Kunden, wo Du Deine zwei Bytes speichern sollst.
Hi >Wer legt die Registerbelegung fest? >Ich. Aber der .... Dann hast du den Fehler gemacht. Lies mal meinen vorletzten Beitrag. MfG Spess
Wenn der Kunde wirklich so einen, mal deutlich auf den Punkt gebracht, Blödsinn verlangt, wird das vermutlich nicht der letze Ärger sein, den du mit ihm hast.
@ MC >Auf die Gefahr hin, mich unbeliebt zu machen:... Machst Du nicht. >Bei den 8051ern ... Nein. Es muss der AVR sein. @ Simon >Warum soll der Speicher eigentlich "frei konfigurierbar" sein? Es ist halt nicht vorhersehbar welches Layout und welche Grösse die Speicherbereiche im Einsatz dann tatsächlich haben müssen. Mal ist es so, mal ist es anders. Mal braucht man mehr Stack. Mal für den einen Datenbereich weniger. Mal für den anderen Datenbereich mehr. Mal mehr RX-Buffer und weniger TX, mal umgekehrt. @Spess53 >Dann hast du den Fehler gemacht. Wer hat danach gefragt?
@All Wir entfernen uns nur immer mehr von der eigentlichen Frage.
Hi
>Wir entfernen uns nur immer mehr von der eigentlichen Frage.
Nein. Im Gegenteil. Wofür brauchst du 32 Register? Welche
Programmiersprache benutzt du eigentlich?
MfG Spess
Regsucher, Ich will dir wirklich nicht zu nahe treten, aber bist du sicher dass du reif genug bist für so ein projekt. Das was du da zuletzt geschildert hast ist EINE VÖLLIG NORMALE anforderung, aber KEIN MENSCH macht dafür so einen zirkus! Der Stack wächst von oben nach unten, Deine datenbereiche von unten nach oben, so wird das GRUNDSÄTZLICH GEMACHT. Stack und Daten können sich -bei richtiger auslegung- der controller nicht in die quere kommen, und um deine datenbreiche unterzubringen (egal wie gross die jeweils sind) muss der controller eh gross genug ausgelegt werden und entsprechende reserven haben. EBEN WEIL die datenfeldgrössen nicht 100% feststehen.- und dann kommt es auf 2-byte oberhalb des stack NICHT MEHR AN!! GERADE WEIL du eh immer genug speicher einplanen musst, WEIL JA die datengrössen veränderlich sein sollen! Ausserdem hat deine letzte erklärung GARNICHTS mit verschieblichen speichern im sinne von relozierbarkeit zu tun, sondern es geht EINFACH NUR um eine intelligente und dynamische speicheraufteilung. DAS IST GANZ ETWAS ANDERES!!! War das ganz hier ein witz? mir scheint ernsthaft, du hast dein pflichtenheft teilweise FALSCH INTERPRETIERT! Jochen Müller
>>Wir entfernen uns nur immer mehr von der eigentlichen Frage. >Ich meine mal gelesen zu haben, das es bei den Atmel 8-Bit Prozessoren >bzw. vielleicht nur bei einigen Modellen, Register gibt, die man >benutzen kann um dort Werte abzulegen. Von dieser vermutlich. Davon hat hier scheinbar noch niemand gehört. Und es sind hier eine Menge erfahrener AVR User unterwegs.
Konkret wird das SO gemacht, ist ein URALTER hut! SRAM-AUFBAU: höchste SRAM-ADRESSE ---- pointer auf datenbereich-1 pointer auf datenbereich-2 pointer auf datenbereich-3 stack .. .. .. .. .. datenbereich-1 datenbereich-1 datenbereich-1 datenbereich-1 datenbereich-2 datenbereich-2 datenbereich-2 datenbereich-3 datenbereich-3 datenbereich-3 ---- kleinste SRAM-Adresse Wenn während der Laufzeit sich Datenbereich-Grössen ändern, wird - der dateninhalt umgeschaufelt - der/die pointer geändert - fertig Das ist ein simples Problem, eigentlich nichtmal ein Problem, sondern Programmier-Alltag, wozu jetzt die ganze Aufregung und anfängliche Verschleierung? Jochen Müller
Das RAM des AVRs wird ja linear addressiert, beginnend mit 0x60, weil darunter die IO-Register liegen. Also hast du auch so nicht dein ganzes RAM zur Verfügung, sondern erst ab 0x60. Jetzt denkst du dir halt, dass die IO-Register zwei Bytes mehr brauchen und das RAM erst ab 0x62 beginnt. Selbst bei einem furchtbaren Konzept könnte man dies wohl noch einplanen.
Es gibt ja genug Teilnehmer hier. Wenn jeder ein Bit auftreibt -- oder auch nur ein halbes, sind genug Leute hier --, dann haben wir rucki-zucki die erforderlichen 16 Bits zusammen! Ich fang mal an: Das T-Bit im SREG. Wird nicht gebraucht. Rede einfach mal mit Deinem Kunden. Dass Kunden unsinnige Sachen verlangen ist nicht unüblich und in Ordnung. Es gehört aber zur Kundenpflege dazu, nicht zu allem JA und AMEN zu sagen sondern die Kunden gut zu beraten. Ansonsten tust Du nämlich weder Dir noch Deiner Firma noch dem Kunden nen Gefallen. Ob N Bytes frei konfigurierbar sind oder N-2 ist doch Wurscht. Da fällt mit ein... es gibt da noch die Adressen 0x0000 bis 0x001f, die weder zum SFR-Bereich noch zum RAM gehören. Nimm doch einfach welche davon. (Die erfolgreichsten Hackerangriffe gibt's bekanntlich auf IP 127.0.0.1)
@ Johann >Da fällt mit ein... es gibt da noch die Adressen 0x0000 bis 0x001f, die >weder zum SFR-Bereich noch zum RAM gehören. Nimm doch einfach welche >davon. Das hört sich interessant an. Aber war das nicht so, das man damit die Register R0 bis R31 schreibt und liest?
unmögliches erledigen wir sofort, Wunder dauern etwas länger:-) Ich habe mir nicht alles durchgelesen, aber das ist schon etwas abstrus. Nimms mir nicht übel - aber alle Lösungen, die funktionieren, lehnst du ab. Auf unmögliche Lösungen wirst du lange warten müssen.
Hi
>Das RAM des AVRs wird ja linear addressiert, beginnend mit 0x60, weil....
Nein. Das RAM beginnt ab Adresse 0 (r0..r31), dann kommen die
IO-Register und danach das eigentliche RAM.
MfG Spess
mr.chip wrote: > Das RAM des AVRs wird ja linear addressiert, beginnend mit 0x60, weil > darunter die IO-Register liegen. Also hast du auch so nicht dein ganzes > RAM zur Verfügung, sondern erst ab 0x60. Jetzt denkst du dir halt, dass > die IO-Register zwei Bytes mehr brauchen und das RAM erst ab 0x62 > beginnt. Selbst bei einem furchtbaren Konzept könnte man dies wohl noch > einplanen. Fängt der (freie) SRAM-Bereich der AVRs eigentlich grundsätzlich immer bei 0x60 an? Ich meine nur, weil sich ja z.B. schon die Länge der Interrupttabellen von Atmega88 und Atmega16 in der Länge unterscheiden und auch nicht jeder Atmega gleich viele I/O-Ports hat. Also wenn das sowieso bei jedem AVR anders ist, dann spielt es ja wohl überhaupt keine Rolle mehr, ob man von der "Zeropage" (C64 anyone?), noch zwei weitere Bytes für einen Pointer abzwackt.
Albrecht H. wrote: > Fängt der (freie) SRAM-Bereich der AVRs eigentlich grundsätzlich immer > bei 0x60 an? Nein. > Ich meine nur, weil sich ja z.B. schon die Länge der Interrupttabellen > von Atmega88 und Atmega16 in der Länge unterscheiden und auch nicht > jeder Atmega gleich viele I/O-Ports hat. Die Vectab steht im Flash.
Albrecht H. wrote: > Fängt der (freie) SRAM-Bereich der AVRs eigentlich grundsätzlich immer > bei 0x60 an? Nein, bei vielen neueren AVRs beginnt der SRAM erst bei Adresse 256, weil es davor noch 192 Bytes "Extended-I/O" gibt. Im Einzelfall das Datenblatt fragen. > Ich meine nur, weil sich ja z.B. schon die Länge der Interrupttabellen > von Atmega88 und Atmega16 in der Länge unterscheiden Die Interrupt-Sprungtabelle liegt im Flash und hat nix mit dem RAM zu tun. Es sind dank Harvard-Architektur verschiedene Speicher. > und auch nicht > jeder Atmega gleich viele I/O-Ports hat. Also wenn das sowieso bei jedem > AVR anders ist, dann spielt es ja wohl überhaupt keine Rolle mehr, ob > man von der "Zeropage" (C64 anyone?), noch zwei weitere Bytes für einen > Pointer abzwackt. Zeropage gibt es beim AVR nicht, dafür 32 Register, 64 I/Os, bei einigen AVRs 192 Bytes Extended-I/O und dann etwas SRAM... ...
Hannes Lux wrote: > Albrecht H. wrote: >> Fängt der (freie) SRAM-Bereich der AVRs eigentlich grundsätzlich immer >> bei 0x60 an? > > Nein, bei vielen neueren AVRs beginnt der SRAM erst bei Adresse 256, > weil es davor noch 192 Bytes "Extended-I/O" gibt. Also für die AVRs mit den ganz vielen Pins ...? > Im Einzelfall das > Datenblatt fragen. > >> Ich meine nur, weil sich ja z.B. schon die Länge der Interrupttabellen >> von Atmega88 und Atmega16 in der Länge unterscheiden > > Die Interrupt-Sprungtabelle liegt im Flash und hat nix mit dem RAM zu > tun. Es sind dank Harvard-Architektur verschiedene Speicher. Ok, ich gestehe, ich hab die Interruptvektoren gerade trotz Kenntnis der Harvard-Architektur, tatsächlich kurz vor meinem geistigen Auge im SRAM stehen sehen. Eigentlich waren es genau diese Unterschiede in den Interrupttabellen, die mich als AVR-Neuling erst vor ein paar Wochen zur Erkenntnis gebracht haben, dass die einzelnen AVR-Typen sich doch erheblich unterscheiden. Weswegen es dann auch etwas unsinnig erscheinen mag, verzweifelt nach zwei freien Bytes und einer möglichst für alle AVRs einheitlichen Lösung zu suchen, (also einer Einheitlichkeit die es schon technisch bedingt innerhalb der Mega-AVR Familie gar nicht gibt). > >> und auch nicht >> jeder Atmega gleich viele I/O-Ports hat. Also wenn das sowieso bei jedem >> AVR anders ist, dann spielt es ja wohl überhaupt keine Rolle mehr, ob >> man von der "Zeropage" (C64 anyone?), noch zwei weitere Bytes für einen >> Pointer abzwackt. > > Zeropage gibt es beim AVR nicht, Lang lebe die Zeropage! > dafür 32 Register, 64 I/Os, bei einigen > AVRs 192 Bytes Extended-I/O > >und dann etwas SRAM... na also > > ... War da nicht irgendwas mit der "Zeropage" auf den AVRs, stimmt man kann aus der Interrupttabelle keinen "Long"-jump verwenden um zur Interruptroutine zu springen, aber da das auf den AVRs weder etwas mit C64 Zeropageadressierung noch, wie du bereits erwähntest, nicht im entferntesten mit dem AVR-SRAM zu tun hat ... falsche Baustelle.
@registersuchender ist doch ganz einfach, du legst reserfierst dir doch 2 byte RAM und zwar dynamisch. und nicht gleich meckern, nach deinen Konzept geht es tatsache. Du hast doch im EEPROM einen pointer für die Stackinitialisierung. mit diesen Pointer musst du halt auf deinen RAM-Pointer zeigen und den Stack um 2.Byte verschieben. Wenn du jetzt das ganze zur laufzeit ändern möchtest ohne daten zu verlieren musst du etwas mehr aufwand treiben, aber das ist eh relativ aufwändig ob nun mit oder ohne pointer. in diesen Fall musst du halt den pointer in die Register legen. @Maxim S. Ja es ist gleichschnell.
Aber er weiß doch (da der Stackpointer irgenwo liegt) nicht wo der Stack "anfängt".
Albrecht H. wrote: > Also für die AVRs mit den ganz vielen Pins ...? Nein, mit der Pinanzahl hat das nichts zu tun. Der Maga48 (DIL28) ist schon so, der Mega16/32 (DIL40) aber nicht. Einfach im Datenblatt nachschaun und nicht voreilig versuchen zu Verallgemeinern. > Ok, ich gestehe, ich hab die Interruptvektoren gerade trotz Kenntnis der > Harvard-Architektur, tatsächlich kurz vor meinem geistigen Auge im SRAM > stehen sehen. Soll vorkommen, ist kein Problem. Auch ich hatte betreffs AVRs gelegendlich Irrtümer. > Eigentlich waren es genau diese Unterschiede in den > Interrupttabellen, die mich als AVR-Neuling erst vor ein paar Wochen zur > Erkenntnis gebracht haben, dass die einzelnen AVR-Typen sich doch > erheblich unterscheiden. Der "Kern" ist immer gleich, abgesehen davon, dass einige kein HW-Mul haben und einige ältere kein Increment beim LPM. Ja, auch beim SPM gibt es Unterschiede, aber nicht Jeder nutzt grundsätzlich Bootloader. Die großen Unterschiede kommen durch die unterschiedliche Ausstattung mit interner Peripherie (bei eigentlich gleichem Kern). Wenn mehr Timer-Features vorhanden sind, braucht man auch mehr I/O-Register. Und es sieht so aus, als ob die Grenze $100 zum Standard werden wird. Das soll mir aber Wurscht sein, ich schreibe keine Universalprogramme, sondern spezielle Programme für einen speziellen Typ (mit geöffnetem Datenblatt als Referenz). > Weswegen es dann auch etwas unsinnig erscheinen > mag, verzweifelt nach zwei freien Bytes und einer möglichst für alle > AVRs einheitlichen Lösung zu suchen, Mache ich ja gar nicht. > (also einer Einheitlichkeit die es > schon technisch bedingt innerhalb der Mega-AVR Familie gar nicht gibt). Ich werde aber auch nicht versuchen, das Ansinnen von "Registersuchender" zu bewerten. Vielleicht weiß er ja was über AVRs, was ich noch nicht weiß. Ob es Unsinn ist, wird sich mit der Zeit herausstellen. Ich werde dann aber nicht zu den Lachern gehören. > Lang lebe die Zeropage! Ja, 6502 (7501/8501) war nicht schlecht, kenne ich vom Plus/4. Habe aber bestimmt 12 Jahre nichts mehr damit gemacht. Jedes Ding hat seine Zeit, die Zeiten sind aber vorbei. > War da nicht irgendwas mit der "Zeropage" auf den AVRs, stimmt man kann > aus der Interrupttabelle keinen "Long"-jump verwenden um zur > Interruptroutine zu springen, Kann sein, dass Du da was verwechselst. Der Begriff "Long-Jump" lässt darauf schließen, dass Du den Adressabstand der Interrupt-Vektoren meinst. Bei kleinen AVRs (bis 8 kiB Flash, also 4 K Adressraum) reicht ein rjmp (Reichweite +/- 2 K) zum Sprung in die ISR, deshalb ist für jeden Vektor 1 Word (2 Bytes) reserviert. Ab 16 KiB Flash muss dafür ein jmp verwendet werden, der 32 Bit braucht, demnach sind die Vektoren 2 Words (32 Bit) groß. Im Gegensatz zum 6502 steht am Interrupt-Vektor bereits der Sprungbefehl (der die Zieladresse enthält) und nicht nur die Zieladresse des Sprungs. > aber da das auf den AVRs weder etwas mit > C64 Zeropageadressierung noch, wie du bereits erwähntest, nicht im > entferntesten mit dem AVR-SRAM zu tun hat ... Jou, hat es nicht... falsche Baustelle. Soll vorkommen, kein Grund, sich zu erschießen (mit'm Strick, da wo das Wasser am tiefsten ist...). Ein 6502 mit integrierten 64K SRAM, Timern, Schnittstellen, Video- und Sound-Baugruppen, SD-Interface und 256 KiB Flash für BASIC 3.5 und Anwenderprogramme wäre zwar auch nicht zu verachten, aber man kann nicht alles haben. Inzwischen gefällt mir AVR-ASM aber auch besser als 6502-ASM. ...
@läubi klar weiß er das, er initialisiert ihn doch anhand eines im EEProm stehenden Wertes. Steht irgendwo in den konfusen Beiträgen oben.
Habe ich deine Aussage irgendwo oben im Thread richtig in Erinnerung, das du bezüglich GPIOR zumindest keine grundsätzlichen Bedenken hattest? GPIOR ist wohl das, was auf deine Frage am ehesten passt, es ist weder im Ram, noch im Register-Satz, noch für irgendeine Peripherie benutzt. Ich verwende GPIO gerne als extra-Frag Register, weil man damit noch sbi/cbi und sbic sbis machen kann. Und sag jetzt bitte nicht das IO-Zugriff zu langsam wäre. Was dein eigentliches Problem wohl eher zu sein scheint ist die von oben auferlegte Aufgabenstellung, die entweder von dir falsch verstanden/interpretiert ist, oder aufgrund sich ausschließenden Anforderungen logisch schlicht unmöglich zu erfüllen ist. Welchen Spielraum hast du überhaupt als Entwickler, laut der Aufgabenstellung? Wenn dir z.B. r0-r31 zur Verfügung steht, alles andere aber für die Anwendung frei bleiben muss, hast du hier die Möglichkeit, innerhalb deines Entwicklerspielraums zu optimieren, und eins der r0-31 einzusparen. Also welches von deinen zahlreichen Einschränkungen beruht auf deiner eigenen (ggf. optimierbaren) Lösung, und welches ist "hart", also Schwarz auf Weiß im "Pflichtenheft" formuliert? Notfalls muss man halt die Aufgabenstellung revidieren, oder Kompromisse eingehen, z.b. das irgendeines der IO-Register halt nicht benutzt wird/werdenmuss/mit höchster wahrhscheinlichkeit man immer auch ohne auskommen kann. Einfallen täte mir da die Output-Compare-Register, von denen es z.b. zwei gibt (A/B), wen man nur eine OC-Unit braucht... Darüberhinaus spricht kein praktischer Grund dagegen, einen winzigen Teil des SRAMs für dein OS abzuzweigen, wie hier zahlreich vorgeschlagen. Es spricht offenbar nur deine Interpretation dieser merkwürdigen Aufgabenstellung dagegen. Da Stack verwendet wird, muss man immer etwas Spielraum lassen. Ob der nun 2 Byte größer ist oder nicht fällt kaum ins Gewicht. Man muss auch nicht jede Aufgabe die von oben kommt als Gottesgebot ungefragt annehmen, wenn sich diese als nicht erfüllbar herausstellt hast du wohl nur die zwei Möglichkeiten A) Aufgeben oder B) nochmal über die Aufgabenstellung zu diskutieren (Entweder du hast sie zu hart interpretiert, oder der Aufgabensteller lässt sich auf einen Kompromiss ein)
>>Warum soll der Speicher eigentlich "frei konfigurierbar" sein? > Es ist halt nicht vorhersehbar welches Layout und welche Grösse die > Speicherbereiche im Einsatz dann tatsächlich haben müssen. Mal ist es > so, mal ist es anders. Mal braucht man mehr Stack. Mal für den einen > Datenbereich weniger. Mal für den anderen Datenbereich mehr. Mal mehr > RX-Buffer und weniger TX, mal umgekehrt. Hah! Hab ich doch richtig geraten. Das Programm soll auf uCs mit unterschiedlichem Speicherausbau laufen. In diesem Fall geht es ja nicht, dass man den Pointer auf RAMEND legt, weil ein anderer uC einen anderen RAMEND hat. Dafür müsste das Programm neu kompiliert werden. Ist es möglich, dass das Programm zur laufzeit erkennt, auf welchem uC es läuft? Ansonsten könnte man eine Routine bauen, die nach dem Reset die Speichergröße erkennt und den Zeiger auf die letzten zwei Byte im RAM über dem Stack legt. Oder die Software bietet eine Option, mit der man die Speichergröße manuell einstellen kan (DIP-Schalter oder so). Oder du verwendest den Flash-Speicher für den Zeiger und nimmst eine höher getaktete Version des Megas, sofern der Kunde nichts dagegen hat ...
Moritz E. wrote: > Habe ich deine Aussage irgendwo oben im Thread richtig in Erinnerung, > das du bezüglich GPIOR zumindest keine grundsätzlichen Bedenken hattest? > GPIOR ist wohl das, was auf deine Frage am ehesten passt, es ist weder > im Ram, noch im Register-Satz, noch für irgendeine Peripherie benutzt. > Ich verwende GPIO gerne als extra-Frag Register, weil man damit noch > sbi/cbi und sbic sbis machen kann. Und sag jetzt bitte nicht das > IO-Zugriff zu langsam wäre. Das mit den GPIOR ist oben schon erledigt worden, weil nur eine Handvoll AVRs die überhaupt haben (der weiter oben erwähnte Mega162 hat z.B. kein GPIOR), das ganze aber offensichtlich auf praktisch jedem AVR laufen soll.
Hannes Lux wrote: > jede Menge wissenswertes ... ;-) >... > >> War da nicht irgendwas mit der "Zeropage" auf den AVRs, stimmt man kann >> aus der Interrupttabelle keinen "Long"-jump verwenden um zur >> Interruptroutine zu springen, > > Kann sein, dass Du da was verwechselst. Der Begriff "Long-Jump" lässt > darauf schließen, dass Du den Adressabstand der Interrupt-Vektoren > meinst. Bei kleinen AVRs (bis 8 kiB Flash, also 4 K Adressraum) reicht > ein rjmp (Reichweite +/- 2 K) zum Sprung in die ISR, deshalb ist für > jeden Vektor 1 Word (2 Bytes) reserviert. Ja so steht es auch im Datenblatt, wobei ich jetzt gerade mal auf dem mega88 (von weit weg) einen rjmp zu $1f00 probiert habe, das macht er nicht, (Relative branch out of reach), wie ist das denn nun, sind die Sprungziele als Words oder als Bytes organisiert? Eigentlich schon als Bytes, denn von 3 hintereinander liegenden NOPs kann ich jedes einzelne NOP als rjmp-Sprungziel angeben, ...? > Ab 16 KiB Flash muss dafür ein > jmp verwendet werden, der 32 Bit braucht, demnach sind die Vektoren 2 > Words (32 Bit) groß. Also jetzt z.B. beim Atmega16 mit 16KB Flash? Aber da sind laut Datenblatt zwischen zwei Interruptvektoren doch auch nur 2 Bytes Platz oder hab ich da was übersehen? > Im Gegensatz zum 6502 steht am Interrupt-Vektor > bereits der Sprungbefehl (der die Zieladresse enthält) und nicht nur die > Zieladresse des Sprungs. > >> aber da das auf den AVRs weder etwas mit >> C64 Zeropageadressierung noch, wie du bereits erwähntest, nicht im >> entferntesten mit dem AVR-SRAM zu tun hat ... > > Jou, hat es nicht... > > falsche Baustelle. > > Soll vorkommen, kein Grund, sich zu erschießen (mit'm Strick, da wo das > Wasser am tiefsten ist...). > Na ja, peinlich ist es schon ein bisschen, nicht unbedingt das Unwissen, mehr die eigene Arroganz, wenn man meint nach mehreren Jahren Programmierpraxis auf dem PCs ALLES zu wissen, zumal die AVRs ja sooo viel kleiner sind wie ein Pentium ... > Ein 6502 mit integrierten 64K SRAM, Timern, Schnittstellen, Video- und > Sound-Baugruppen, SD-Interface und 256 KiB Flash für BASIC 3.5 und > Anwenderprogramme wäre zwar auch nicht zu verachten, aber man kann nicht > alles haben. Da gabs doch mal bei Pearl für 20 EUR diesen C64-"Joystick" mit eingebautem "Singlechip-C64", mit TV-Ausgang und ca. 30 Spielen auf ROM. >Inzwischen gefällt mir AVR-ASM aber auch besser als > 6502-ASM. > > ...
Maxim S. wrote: > Hah! Hab ich doch richtig geraten. Das Programm soll auf uCs mit > unterschiedlichem Speicherausbau laufen. > In diesem Fall geht es ja nicht, dass man den Pointer auf RAMEND legt, > weil ein anderer uC einen anderen RAMEND hat. Dafür müsste das Programm > neu kompiliert werden. Dann verstehe ich aber immer noch nicht seine Bedenken, Rambereiche zu benutzen, die selbst auf dem minimalsystem vorhanden wären, z.b. RAM START, oder RAMEND der kleinsten möglichen variante mit SRAM. Wenn er den Stack so und so per EEPROM Zeiger umschiebt muss er auch irgendwie einen Zeiger beim Reset bekommen, und den selben Zeiger kann er neben Stack auch für seine Systemdaten verwenden? Aber wenn er wirklich sowas vorhat hätte man sich 70% der Raterei sparen können wenn er mal endlich rausrücken würde mit näheren Infos zum Kontext
Albrecht H. wrote: > Ja so steht es auch im Datenblatt, wobei ich jetzt gerade mal auf dem > mega88 (von weit weg) einen rjmp zu $1f00 probiert habe, das macht er > nicht, (Relative branch out of reach), wie ist das denn nun, sind die > Sprungziele als Words oder als Bytes organisiert? Eigentlich schon als > Bytes, denn von 3 hintereinander liegenden NOPs kann ich jedes einzelne > NOP als rjmp-Sprungziel angeben, ...? Adressen im CSEG als Word, auch ein NOP ist 16 bit, demnach müsstest du mit $0F80 erfolg haben, wobei dort 2er-Komplement erwartet wird..
Moritz E. wrote: > Albrecht H. wrote: > >> ... >> Bytes, denn von 3 hintereinander liegenden NOPs kann ich jedes einzelne >> NOP als rjmp-Sprungziel angeben, ...? > > Adressen im CSEG als Word, auch ein NOP ist 16 bit, demnach müsstest du > mit $0F80 erfolg haben, wobei dort 2er-Komplement erwartet wird.. Ach du meine Güte, die sind ja ALLE -> min. 16-bit Opcode, jetzt wirds Tag, da programmiert man einmal nicht mehr mit Lochkarten und schon übersieht man sowas!
Albrecht H. wrote: > Also jetzt z.B. beim Atmega16 mit 16KB Flash? Aber da sind laut > Datenblatt zwischen zwei Interruptvektoren doch auch nur 2 Bytes Platz > oder hab ich da was übersehen? Ja, hast Du. Vergleiche mit einem kleineren AVR. Beachte, dass die Adressen im Flash wordweise sind. Achja, RJMP geht vorwärts und rückwärts, wenn es über das Speicherende (als Ring gesehen) hinaus gehen soll, dann muss man das im AVR-Studio einstellen. Habe es gerade nicht vor mir, musst halt selber mal suchen. > Da gabs doch mal bei Pearl für 20 EUR diesen C64-"Joystick" mit > eingebautem "Singlechip-C64", mit TV-Ausgang und ca. 30 Spielen auf ROM. Möglich, hat mich aber nicht interessiert, bin kein Gamer, hatte deshalb auch keinen C64 sondern den Plus/4. Und den habe ich auch drastisch erweitert. Ehe Du weitere Fragen in diesem Thread (in dem es eigentlich um Anderes geht, wir also nur stören) stellst, lies und vergleiche die Datenblätter, lies und verstehe das Tutorial, lies und verstehe den Befehlssatz, lies auch in der Hilfe zum AVR-Studio. ...
Maxim S. wrote: >>>Warum soll der Speicher eigentlich "frei konfigurierbar" sein? >> Es ist halt nicht vorhersehbar welches Layout und welche Grösse die >> Speicherbereiche im Einsatz dann tatsächlich haben müssen. Mal ist es >> so, mal ist es anders. Mal braucht man mehr Stack. Mal für den einen >> Datenbereich weniger. Mal für den anderen Datenbereich mehr. Mal mehr >> RX-Buffer und weniger TX, mal umgekehrt. > > Hah! Hab ich doch richtig geraten. Das Programm soll auf uCs mit > unterschiedlichem Speicherausbau laufen. Sieht wohl so aus ja.. Ich weiß nicht was das werden soll, schließlich haben AVRs, die einen verschiedenen Speicherausbau haben auch nicht zwangsläufig den gleichen Umfang an Peripherie, Instruction Set und zudem kann es sein, dass die symbolischen Namen für Register (wie TCCR1A) dann auf die völlig falsche Adresse zeigen. Hast du dir diesbezüglich schon was ausgedacht? Oder verwendest du nur bestimmte AVRs, die garantiert nur Differenzen in der Speichergröße haben? Warum nicht einfach für jeden Chip neu kompilieren? RAMEND ist zur Kompilierzeit ja ausreichend um das Speicherlayout zu "erstellen".
Simon K. wrote: > Warum nicht einfach für jeden Chip neu kompilieren? RAMEND ist zur > Kompilierzeit ja ausreichend um das Speicherlayout zu "erstellen". Es wäre mir neu, daß AVR-Programme ohne neu compilieren auf nem anderen Typ laufen. Selbst ATmega8 und ATmega88 sind sich zwar ähnlich aber im Binärcode völlig inkompatibel. ATmega16 und ATmega164 auch usw. Ohne für den richtigen Typ zu compilieren läuft bei den AVRs garnichts! Und daher kann es nie den Fall geben, daß RAMEND nicht bekannt ist. Peter
/offtopic Ich glaube, das ist ein neuer Rekord: 119 Beiträge in weniger als 24 Stunden! /offtopic
Hannes Lux wrote: > Albrecht H. wrote: >> Also jetzt z.B. beim Atmega16 mit 16KB Flash? Aber da sind laut >> Datenblatt zwischen zwei Interruptvektoren doch auch nur 2 Bytes Platz >> oder hab ich da was übersehen? > > Ja, hast Du. Vergleiche mit einem kleineren AVR. Beachte, dass die > Adressen im Flash wordweise sind. Schon gemerkt. > > Achja, RJMP geht vorwärts und rückwärts, wenn es über das Speicherende > (als Ring gesehen) hinaus gehen soll, dann muss man das im AVR-Studio > einstellen. Habe es gerade nicht vor mir, musst halt selber mal suchen. Yep. > >> Da gabs doch mal bei Pearl für 20 EUR diesen C64-"Joystick" mit >> eingebautem "Singlechip-C64", mit TV-Ausgang und ca. 30 Spielen auf ROM. > > Möglich, hat mich aber nicht interessiert, bin kein Gamer, hatte deshalb > auch keinen C64 sondern den Plus/4. Und den habe ich auch drastisch > erweitert. Kein Problem, die Betonung lag auch mehr auf "Singlechip mit Peripherie" als auf Spiele. > > Ehe Du weitere Fragen in diesem Thread (in dem es eigentlich um Anderes > geht, wir also nur stören) stellst, Schon klar, schon klar, ist ja auch alles geklärt soweit, die ATmegas sind 8-Bitter deren Opcodes immer min. 16 Bits lang sind, (sogar die NOPs), weshalb auch die Word-weise Adressierung Sinn macht. Wenn man mit einer gewissen Vorstellung von 8-Bittern, (basierend auf 6502, Z80, 8051), an die 8-Bit AVRs rangeht kann man halt schon mal in so eine "Falle" tappen. Ist jetzt aber bei mir angekommen, gespeichert und wird sicher nicht mehr das Thema weiterer Kommentare von mir sein, es sei denn, ich kann mal jemand anderem damit helfen, der das ebenfalls übersehen hat. Ok, das war jetzt eben ein kleiner Exkurs der das Ursprungsthema verlassen hat, kommt vor, sorry. Aber anfangs gings mir ja nur um die Unterschiede zwischen den einzelnen AVR-Typen, (also die, die sogar mir als AVR-Neuling sofort aufgefallen sind), und es deswegen möglicherweise überhaupt keinen Sinn macht, nach dem mysteriösen 33.ten Register zu suchen, weil man das "Problem" sowieso auf jedem AVR anders lösen müsste, bzw. stattdessen auch gleich zu einer der vielen vorgeschlagenen Standardlösungen greifen und irgendwo aus dem SRAM, (z.B. ganz am Anfang), zwei Bytes abzwacken kann. > lies und vergleiche die > Datenblätter, lies und verstehe das Tutorial, lies und verstehe den > Befehlssatz, lies auch in der Hilfe zum AVR-Studio. > > ... Sag das bitte nicht immer, ich bin ein echter Datenblatt-Fan, manchmal braucht es eben solche kleinen Schlüsselerlebnisse, damit man Datenblätter die man sich schon ein Dutzend mal durchgesehen hat und glaubt sie verstanden zu haben, noch einmal aus einem anderen Blickwinkel etwas genauer betrachtet.
Ich erlaube mir noch einmal an die Ausgangsfrage zu erinnern und die bisherigen Lösungen zusammenzufassen: Gibt es, mit Ausnahme der Peripheriekontrollregister und der Register R0 bis R31 eine Möglichkeit CPU intern einen 16-Bit bzw. zwei 8-Bit Werte zu speichern? Bisherige Antworten: 1. Nein, gibt es nicht 2. GPIORX Ich weise auch höflich darauf hin, das die Ausgangsfrage die nach einer Information ist. Nicht, wie mir viele Antworten voraussetzen scheinen, die Frage nach einem Rat wie denn vorzugehen ist, wenn es nur die Antwort 1. gibt. Wenn Ihr gestattet, würde ich Euch gerne eine Kritik über Eure Beiträge hier und einen Rat geben. Dies frage ich vor allem Spess53, Matthias Kölling und Jochen Müller.
Erwartest du ehrlich jetzt noch eine neue Antwort? Hier wurden schon so gut wie alle Möglichkeiten durchgesprochen. Angenommen, es würde ein Hinweis auf deine Frage im Datenblatt stehen, dann wäre hier schon eine Antwort gefallen. Da eine eventuelle Lösung also nicht im Datenblatt steht, kannst du dir nie sicher sein, dass diese Lösung in späteren Revisionen der Controller auch noch funktioniert. Also selbst wenn es funktionieren würde, hättest du keine volle Flexibilität - die dein Kunde ja offensichtlich so hoch schätzt.
Registersucher, Ein Problem löst man dadurch, dass man versucht dessen Ursache und dessen Wesen zu ergründen. Nicht durch stochern im Nebel. Genau aus diesem Grund wollten hier soviele Leute die Hintergründe zu Deiner Frage erfahren. Das ist übliche und sinnvolle Methodik. Wärst Du bei Deinem Kunden ebenso vorgegangen, hättest Du vielleicht das Problem garnicht, Deine bisherigen Info-Häppchen zu den Hintergründen rechtfertigen jedenfalls Deine angedachte Programm-Architektur auf keinen Fall. Das musst Dir Dir halt schon anhören, wenn Du öffentlich fragst... Jochen Müller
@reistersuch Woher weist du wo du den Stack initialisieren musst?
>Ein Problem löst man dadurch, dass man versucht dessen Ursache und >dessen Wesen zu ergründen. >Nicht durch stochern im Nebel. >Genau aus diesem Grund wollten hier soviele Leute die Hintergründe zu >Deiner Frage erfahren. Das ist übliche und sinnvolle Methodik. Ich würde behaupten das dies die einzig gangbare Methodik bei der Umsetzung einer Problemstellung ist. Das ist ja der Grund warum ich Programmierer geworden bin, weil man zwar konkrete Probleme per HW/SW zu lösen versucht aber dabei eben die Gründe warum es ein Problem ist/gibt viel weitgefasster analysieren muß. Ohne diese Arbeit, bei der man die Umweltbedingungen umfassender analysiert, wäre Programmierung ziemlich langweilig. Das was Registersuchender macht halte ich für grund verkehrt, und eigentlich auch für Zeitverschwendung darauf zu antworten. In der normalen Praxis versucht man durch Festlegungen von wichtigen Parametern die Software die entwickelt wird stabli und wartbar lauffähig zu bekommen. Jede Forderung im Pflichtenheft die logisch gegen die ausgewählten Instrumente (Compiler, Physik, Mathematik, Hardware) verstößt kann nicht logisch in Sofwtare umgesetzt werden. Die Forderung nach "abstrakter Universal-Flexibilität" indem man beliebigst den SRAM ausnutzen kann widerspricht der Programmierpraxis auf AVRs, aus abstrakten unlogischen Forderungen baut man auch nur auf abstrakten, unlogischen AVRs eine abstrakt unlogische Software. Man baut in eine normalerweise stark zielorientierte und relativ einfach gestrickte Software für den AVR ein Feature ein (alles dynamisch im SRAM verschiebbar) das kontraproduktiv ist, für diese ausgewählten Mittel. Dieses Faeture wird aus dem Projekt ein unwartbares, bzw. ohne zusätzliche Vorteile wartbares, und instabiles, fehleranfälliges System machen. Wemm dann müsstes du jetzt auf die Suche nach einer besser geeigneten Plattform für das Projekt gehen, zb. auf CPUs für PC mit richtig fetten Betriebsystemen mit virtuellem Memorymanagement wird man mit dynamischer Relokation der Speicherresourcen konfrontiert. Nur das dort zwei wichtige Bedingungen erfüllt sind, die HW unterstützt es und hat Power und das zu lösende Problem, Multitasking und quasiparallele Bedienung von Software wird benötigt. Oder in kurz: eine dynamische Relokation des SRAMs auf AVRs ist unsinnig und praxisfern da man sowieso für jeden weiteren AVR Typ die Software erneut anpassen und recompilieren muß. Die einzige Außnahme ist es das uns wichtige Informationen über das eigentliche Projekt fehlen und daher immer eine Fehlinterpretation unsererseits stattfindet. Die Antworter hier versuchen also nicht nur auf eine konkrete Frage zu antworten, sondern sie versuchen dir, Registersuchender, auch beizubiegen das es unter Umständen auch viel bessere Lösungen, die sich in der Praxis bewährt haben, zu verklickern. Dazu benötigt man aber Informationen die wir nicht haben. Und das machen sie weil sie verstanden haben das nicht nur die Lösung eines Problemes mit irgendeiner Lösung wichtig ist sondern ein Problem nur dann korrekt gelösst ist wenn man es mit der bestmöglich angepassten Lösung angeht. Gruß Hagen
@ Jochen Müller Ich habe Dich nicht aufgefordert mich zu kritisieren und ich habe Dich höflich gefragt habe ob Du Kritik von mir hören willst. Soll ich nun annehmen das Du nicht in der Lage bist zu verstehen oder nicht willens? Und, egal welche Annahme nun zutrifft: Soll ich nun, angesichts dessen, weiter annehmen das Du in der Lage bist mein Problem zu lösen? Am Anfang stand klar und deutlich die Frage nach einer Information. Nicht die Bitte um die Lösung eines Problems. Wo steht, das ich jemanden auffordere mein Problem zu lösen? Soll ich nun annehmen das Du nicht in der Lage warst den Unterschied zu erkennen oder nicht willens? Und soll ich das wiederrum als Hinweis auf Deine Fähigkeit annehmen Text zu verstehen oder nicht? Und soll ich nun, wiederrum angesichts dessen, annehmen das Du in der Lage bist mein Problem zu lösen? Du hast hier meine Fähigkeiten in Frage gestellt, obwohl ich Dich dazu nicht aufgefordert habe. Mich sogar mit groß geschriebenen Worten angeschrieen. Abgesehen von der Unhöflichkeit die darin liegt, was soll ich nun annehmen? Das ich Deine Eigenliebe verletzt habe, weil ich partout Deine Benühungen mein Problem zu lösen nicht anerkennen wollte oder das Du, indem Du mich kritisiert hast, verdecken wolltest das Du die eigentliche Frage nicht beantworten kannst, aber doch Aufmerksamkeit wolltest, die ich Dir verweigert habe, indem ich Deine Lösungen als nicht akzeptabel kennzeichnete? Nur eins weiss ich sicher: Meine Frage hast Du nicht beantwortet.
Hagen Re wrote: > Oder in kurz: eine dynamische Relokation des SRAMs auf AVRs ist unsinnig > und praxisfern da man sowieso für jeden weiteren AVR Typ die Software > erneut anpassen und recompilieren muß. Die einzige Außnahme ist es das > uns wichtige Informationen über das eigentliche Projekt fehlen und daher > immer eine Fehlinterpretation unsererseits stattfindet. Punkt aus Schluss. Thread beendet.
Simon K. wrote: > > Punkt aus Schluss. Thread beendet. Warum? Jeder blamiert sich eben so gut er kann. MfG, der Trollige
1.) die in neueren AVRs vorhandenen GPIOR benutzen 2.) Prozessorregister wie XH:XL global reservieren und dort deinen Zeiger rein 3.) bischen, 2 bytes SRAM abknapsen und statisch global reservieren für deinen zeiger 4.) ein transparentes Latch an 2 Ports des AVRs anschließen und dort deinen Zeiger abspeichern, über die 2 Ports hast du Zugriff auf dieses Latch 5.) externen Speicher benutzen, oder besser noch, externen Speihcer mit externen SPeihcer mit externen Speicher in dem schlußendlich dein zeiger steht 6.) SPH:SPL als zeiger mißbrauchen, statt nur als Stackpointer zu benutzen diesen so umbauen das dieser dein Relokationzeiger darstellt, somit inklusive Stackmanagement und als Quintessenz darfst du deinen eigenen Compiler bauen der deine Sonderregeln auch umsetzt Verbleiben die Probleme: 1.) die Software muß auf jeden AVR Typ denoch zugechnitten werden 2.) die Problematik des Stacks ist noch zu lösen, dieser muß an igendeiner Stelle, und diese sollte am besten sehr frühzeitig im Programmablauf stehen, mit festen nicht reallozierbaren Addressen gefüllt werden Gruß Hagen PS: Neugier ist eine der besten Eigenschaften der Menschen, und auch eine der Eigenschaften die am leichtesten von jedem Menschen nachvollziehbar sein sollte. Ein Programmierer ist ein Problemlöser, er sollte die Eigenschaft haben das er das Lösen eine Problemes als intgeressant und befriedigend an sieht. Du stösst hier also im Thread auf exakt solche Menschen die diese beiden Eigenschaften besitzen.
@ Hagen & Simon
>> Oder in kurz: eine dynamische Relokation des SRAMs auf AVRs ist unsinnig
Setzt Ihr die allgemeingültigen Maßstäbe was sinnvoll ist und was nicht?
Im übrigen, wiegesagt, habe ich nicht um Rat gefragt. Sondern nach einer
Information.
Kennt Ihr den Unterschied?
>Und, egal welche Annahme nun zutrifft: Soll ich nun, angesichts dessen, >weiter annehmen das Du in der Lage bist mein Problem zu lösen? ich glaube dass könne etliche hier! aber nicht so, so nicht :-) Fred
ich habe den thread nicht komplett gelesen, aber ich denke ich habe die
antwort für das problem ohne der schon oft geforderten hintergrundinfos:
42
@registersucher:
Registersucher wrote:
> Aber der Kunde ist halt König.
manchmal muss man dem kunden verklickern, dass etwas nicht in der form
möglich ist, wie er es sich einbildet...
lol, du verhältst dich echt lächerlich! Kommst hier mit so einem Schwachsinn an, lehnst alle Informationen ab die du geboten bekommst, wiederholst immer wieder die Frage nach einer nicht existenten Information und beschimpfst die Leute dafür dass sie versuchen dir zu helfen. Ich glaube, du solltest die Finger vom Programmieren lassen.
> Kennt Ihr den Unterschied? Sicher doch. Besser ist es du kaufst dir par Bücher die sind nicht neugierieg, haben nicht das Bedürfniss nach der Suche von Lösungen weil es ihnen Spaß macht. Dein Fehler ist Unhöflichkeit. Keiner möchte dich im ersten Moment hier auslachen oder fertig machen, die meisten versuchen sich in DEIN (ja ich schreie mal) Problem reinzudenken und eine Lösung vorzuschlagen. >Setzt Ihr die allgemeingültigen Maßstäbe was sinnvoll ist und was nicht? Korrekt das machen wir und es ist sinnvoll. Wir nehmen allgemeingültige Maßstäbe, quasi Standardprogramme in unseren Hirnen die durch langjähige Erfahrungen bei der Entwicklung mit AVRs so entstanden sind, aus Büchern angelesen, aus anderer Software abgeschaut oder einfach hier im Forum diskutiert wurden und benutzen sie als Mittel um einen Zweck zu erfüllen. Nämlich deine Frage zu beantworten. Gruß Hagen
Registersucher, Kein Mensch hat Dich angeschrien, GROSS geschrieben bedeutet für mich nur die Betonung wichtiger Teile. Dass Dein problem so wie Du es fragtest nicht lösbar ist, müsste Dir schon vor mindestens 50 Beiträgen klar geworden seion. Solange Du aber keine klaren Hintergünde nennst, und auch berechtigte Einwände ignorierst (nicht nur von mir, sondern zahlreichen Schreibern) hilft das nicht weiter. ALSO: 1) Möglicherweise ist Dein Problem mit einem gänzlich anderen Ansatz lösbar. 2) Für DEINEN Ansatz sieht hier niemand eine Lösung. 3) Viele Wege führen nach Rom, man darf die nur nicht einfach ingnorieren. 4) Ein Problem ist NUR DANN lösbar, wenn man die kompletten Hintergründe kennt. Ich bin sicher, dass, wenn Du Du unter einem neuen Trhread das Problem mal mit allen Hintergründen schilderst, auch eine Lösung gefunden wird. Und das ist nichts persönliches, das sind GANZ berechtigte Einwände, wie ich sie auch bei jedem Kundengespräch aufgebracht hätte. Jochen Müller
Naja. Ich glaub', ich lass Euch allein mit Euren Gewissheiten. Die müssen Euch sehr viel Trost geben.
ich habe einen funktionierenden hinweis gegeben. wenn du es nicht nehmen möchtest pech gehabt.
>Naja. Ich glaub', ich lass Euch allein mit Euren Gewissheiten. >Die müssen Euch sehr viel Trost geben. Wetten das der noch mal ne Frage hat! Fred
Fangfrage im Pflichtenheft, Auftraggeber erwartet das der Programmierer auf die Unsinnigkeit der Aufgabe hinweist ;)
Hallo Registersuchender! Du hast bei der letzten Zusammenfassung einen Post übersehen, der garnicht schlecht aussieht. Witer oben kam nämlich die Idee das ganze anders herum zu lösen: Wenn Du keinen festen Register-Satz hast und alles dynamisieren musst, dann dynamisiere doch auch den 'Register-Satz'. Um das Fazit aus dem Post zu wiederholen: Lege einen Pointer auf die RAM-Adresse des 'Register-Satz' im FLASH ab und danach legst Du den eigentlichen Pointer ins FLASH dazu. Beim Start lädst DU also zuerst einen Pointer auf den 'Register-Satz' und danach seinen Inhalt. Ich kann mir nicht vorstellen, dass Du die dynamischen Codes ohne ein gewisses Framework, also Software, präparierst und auf den Controller überträgst. Es muss bei der Übertragung ja klar sein, welche Code-Teile wo hin sollen und wie viel RAM sie benötigen. Damit hat das Framework auch die Information den Pointer dynmisch irgendwo unter zu bringen und seinen Startwert zu berechnen. Letzteres, also das Berechnen des Startwertes für das dynmische RAM, muss Du ja ohnehin schon machen. Da das (hoffentlich) in Bezug auf genutzten und vorhandenen Speicher bezug nimmt, sollte auch ein Platz für die Speicherung des nun dynmisierten 'Register-Satz' möglich sein. Damit bist Du nur beim Reset auf zwei FLASH/EEPROM Reads angewiesen und kannst zur Laufzeit mit 'Full-Speed' auf den Pointer und seinen Inhalt zugreifen. Das Muster erlaubt es zudem, auch zur Laufzeit den Pointer zu verschieben, also alles ganz gemäß Deinem Konzept. Sollte der Kunde also den Wunsch hegen, zur Laufzeit Datenbereiche zu verschieben, kann Dein Kernel den Pointer in relokieren. Baut der Kunde neue Software mit einem anderen Speicher-Layout, dann sorgt Dein Framework für die automatisch passende Verlagerung des Pointers. Damit hättest Du das Lastenheft erfüllt und bist kompatibel zu allen AVR. Denn Deine Ursprüngliche Fragestellung ist schon ein Paradoxon, Du wünschst eine Kompatibilität zu möglichst allen AVR, fragst aber nach Registern, die eventuell nur teilweise in einigen Modellen existieren. Da waren die weit gestreuten Antworten vorprogrammiert. Gruß, Ulrich
naja aber wo ist der Vorteil ? Das was er jetzt per Hand machen möchte macht der Compiler automatisch und vollständig transparent. Und da man eh in der AVR-Szene die Software für andere AVrs immer neu kompilieren muß stellt sich die Frage nach dem Sinn des Unterfangens. Besonders auch in Bezug darauf das zu 99.99% aller Fälle bei AVR Software keine Relokation der SRAM Daten notwendig ist, bzw. sogar unerwünscht ist. Die wenigsten Projekte benutzen gar einen dynamischen Heap und das wäre die Vorstufe für ein komplett dynamisch relokierbares Memory Management. Gruß Hagen
Es gibt folgende Sorten von Kunden: 1) Der, der den Controller als BlackBox ansieht, der das-und-das machen soll. DEM IST ES PIEP-EGAL WO WELCHE DATENBEREICHE LIEGEN. 2) Der Kunde mit exakten Background. MIT DEM KANN MAN DAS PROBLEM GANZ OFFEN BEREDEN UND AUF UNMÖGLICHKEITEN HINWEISEN, OHNE MURREN. 3) Der Kunde der nicht weiss was er will, Luftschlösser baut, und aus Unsicherheit unmögliche Dinge erwartet, weil er schlicht Angst hat irgendwelche Weichen falsch zu stellen. DIESEN TYPEN NIMMT MAN AN DIE HAND, SCHULT IHN UND DER KUNDE GEWINNT VERTRAUEN UND LÄSST AM ENDE DEN PROGRAMMIERER MACHEN. Ich gehe davon aus, das dem Registersucher einfach die Erfahrung fehlt, mit diesen Kundentypen entsprechend umzugehen. Da ist ja auch keine Schande, ging mir vor 20Jahren ebenso. Aber die zahlreichen helfenden Hände hier für dumm verkaufen zu wollen und als unfähig zu bezeichnen, nur weil sie ohne Hintergründe keine Lösung nennen können, das geht definitiv nicht! Jochen Müller
Leute, Leute, woher nehmt ihr bloss dermassen viel Freizeit?!?
Nur gut das ich sie nicht hatte. Puh was ein harter Kanten (Quadratur des Kreises in euklidscher Ebene) ich kan seine frust verstehen. aber seine Beschwerden sollte er an Atmel richten, die Haben sein 16 Bitregister einfach nicht im Plan, weil sie es für überflüssig hielten neben einer vielzahl von univerasal und spezialregistern eines für nichtvorhergesehen und Anwendungen in alle Chipvarianten zu brutzeln. Und noch dazu auf das ohnehin spärlich vorhandene RAM. Als alter Zzweckentfremder kann ich nur sagen: " Bevor ich etwas zweckentfremde analysire ich dessen Möglichkeiten." Ein Weg findet sich dann fast immer. Aber ein Problem welches nur aus Unbestimmbarkeiten besteht seiner selbst. ;-)))
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.