Hallo zusammen,
bei einem aktuellen Projekt habe ich etwas Probleme, und ich hoffe hier
kann mir jemand einen Tip geben, oder mich ein wenig erleuchten.
Ein kleiner Steuercomputer (ASIC) legt Daten in einem Dualportram ab,
auf das ich wie auf ein externes SRam zugreifen möchte. (8 Bit Datenbus
+ Adressleitung und latch)
Das Dualportram ist 4KB gross.
Ich verwende einen Atmega 2561, um auf das externe Dualportram
zuzugreifen.
Als Software AVR-Studio4. (gcc)
Nun dachte ich mir es wäre doch schön, wenn ich durch den externen Daten
und
Adressbus vom Atmega so tun kann, als liegt das Dualportram als
Erweiterung
hinter dem internen SRAM.
Da ich noch nie mit externem Ram gearbeitet habe, nun die Frage, wie
kann ich in c expliziet auf eine Speicherstelle zugreifen, die im
externen Ram liegt?
Also z.B auf das erste Byte des Dualportram
Der Speicheraufbau sollte ja so aussehen wie im Bild.
Bin über jede Hilfe Dankbar.
reflexx schrieb:> Hallo zusammen,> bei einem aktuellen Projekt habe ich etwas Probleme, und ich hoffe hier> kann mir jemand einen Tip geben, oder mich ein wenig erleuchten.>>> Ein kleiner Steuercomputer (ASIC) legt Daten in einem Dualportram ab,> auf das ich wie auf ein externes SRam zugreifen möchte. (8 Bit Datenbus> + Adressleitung und latch)> Das Dualportram ist 4KB gross.>> Ich verwende einen Atmega 2561, um auf das externe Dualportram> zuzugreifen.> Als Software AVR-Studio4. (gcc)> Nun dachte ich mir es wäre doch schön, wenn ich durch den externen Daten> und> Adressbus vom Atmega so tun kann, als liegt das Dualportram als> Erweiterung> hinter dem internen SRAM.>> Da ich noch nie mit externem Ram gearbeitet habe, nun die Frage, wie> kann ich in c expliziet auf eine Speicherstelle zugreifen, die im> externen Ram liegt?>> Also z.B auf das erste Byte des Dualportram>> Der Speicheraufbau sollte ja so aussehen wie im Bild.>> Bin über jede Hilfe Dankbar.
Punkt 1.
Lege ihn nicht direkt dahinter, du hast nur gigantische Probleme mit der
Adressdekodierung. Einfacher du legst das DualRam ab 0x8000, dann nimmst
du /A15 als /CS. und deine Dekodierung ist fertig.
In C kannst du einen Zeiger darauf zeigen lassen. z.B:
char *ptr;
{
ptr = 0x8000;
....
@Dirk
Danke für die schnelle Antwort.
Habe ich dich richtig verstanden?
Der tatsächliche Physikalische Adressraum zwischen 0x2000 und 0x7fff ist
also gar nicht vorhanden.
Bei Zugriff auf 0x8000 wird A15 high, der dann den cs für das
Dualportram "aktiviert".
Dann kann ich über den Pointer von
0x8000 bis 0x9000 auf die 4K des Dualportrams zugreifen.
Nein,
du hast den gesamten bereich ab 0x21ff zur Verfügung.
Nur musst du deinem RAM sagen, wann es sich angesprochen fühlen soll.
Also ein ChipSelect (CS).
Das machst du so, das du Adressleitungen benutzt um das auszukodiren.
Das CS ist normalerweise ein /CS, einige RAMS haben auch ein CS.
->Datenblatt.
Wenn du nun dein RAM ab 0x2200 - 0x31ff legen willst must du eine
Kodierer bauen, der genau bei diesen Adressen ein Low liefert. Nicht
ganz einfach.
Du kannst zwar auch sagen, das er im Bereich von 0x0000-0x7fff (A15=0)
ein
CS erstellt.
D.h. dein Ram wird immer dann angesprochen wenn du innerhalb der dieses
Bereiches zugreifst angesprochen. Das DP wir also einfach mehrfach in
diesem Bereich gespiegelt. (A0-A11) legst du ja ans RAM direkt an
(kannst du auch pinswapen) nur A12-A14 werden nicht benutzt und sind
also "dont care"
Aber die Frage ist dann, was passiert bei einem zugriff auf das interene
RAM. Bei den meisten µC wird dann trotzdem ein Zugriff das Externe RAM
beim Schrieben erzeugt. Deshalb meine Empfehlung A15 invertieren und als
CS benutzten,
Dann hast du das DP-RAM ab 0x8000,0x9000,0xA000,0xB000,....
Jörg Wunsch schrieb:> Dirk H. schrieb:>> char *ptr;>> "volatile" nicht vergessen.>> "uint8_t" ist sinnvoller als "char".volatile gebügt i.d.R nicht, um gegen Dual Ported RAM zu
synchronisieren: Die größte Einheit, die atomar gelesen werden kann,
bleibt ein Byte!
Ebenso ist es nicht möglich, konsistent Operationen auszuführen wie
ptr[0] |= 5;
ptr[0]++;
es sei denn, der µC bietet entsprechende Primitive, wie etwa ATxmega
mitLAC, LAT, LAS, XCH. In diesem Fall muß man das jedoch händisch
codieren, da normaler C-Code diese Befehle nicht verwendet.
@Johann L. (gjlayde) Benutzerseite
>volatile gebügt i.d.R nicht, um gegen Dual Ported RAM zu>synchronisieren: Die größte Einheit, die atomar gelesen werden kann,>bleibt ein Byte!
Sicher, aber das Ganze ist ja sowieso etwas anders.
Wahrscheinlich schreibt der ASIC alle par ms den Dual Port RAM voll,
generiert einen Interrupt und der AVR liest arauf die Daten. Alles
einfach, alles one way, alles zeitlich starr. Echte Verriegeung und
atomarer Zugriff sind hier wahrscheinlich nicht nötig.
Volatile ist wichtig (hatte ich vergessen),
der µC weiß ja nicht wann das DPRam sich geändert hat, dadurch das da
irgendetwas auf ein anderen Leitung klappert, ändert sich ja für ihn
nichts.
Falsch kann es jedenfalls nicht sein!!
Du könnetest ja z.B. ein Byte nutzen um zu signalisieren, das da was
neues ist. und dann?