Forum: Compiler & IDEs Dualport Ram


von reflexx (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Dirk H. (dirk_h63)


Lesenswert?

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;
....

von Christian O. (reflexx)


Lesenswert?

@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.

von Dirk H. (dirk_h63)


Lesenswert?

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,....

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dirk H. schrieb:
> char *ptr;

"volatile" nicht vergessen.

"uint8_t" ist sinnvoller als "char".

von Christian O. (reflexx)


Lesenswert?

Ok hab ich verstanden,ich probiers aus.

Danke für deine Hilfe.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

@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.

von Dirk H. (dirk_h63)


Lesenswert?

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?

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.