Forum: Compiler & IDEs externen RAM testen


von Josef K. (josefk)


Angehängte Dateien:

Lesenswert?

Hallo zusammen.

Ich verusche gerade meinen externen 32k Ram Riegel an meinem AT90CAN128 
zu testen.
(Daten zu dem AT90CAN128 im Anhang!)

Als Tesfunktion nutze ich folgendes:
1
uint32_t *padresse;
2
uint32_t adresse;
3
uint32_t value32;
4
char cstring[5];
5
for(adresse=0x1100; adresse < 0x808fff; adresse=adresse+4)
6
{
7
  padresse = adresse;
8
  *padresse = adresse;
9
      
10
  //Leitwert
11
  value32 = adresse;
12
  rs232_putc((int)(value32>>24));
13
  rs232_putc((int)(value32>>16));
14
  rs232_putc((int)(value32>>8));
15
  rs232_putc((int)(value32));
16
  rs232_putc('\n');
17
  //Wert
18
  value32 = *padresse;
19
  rs232_putc((int)(value32>>24));
20
  rs232_putc((int)(value32>>16));
21
  rs232_putc((int)(value32>>8));
22
  rs232_putc((int)(value32));
23
  rs232_putc('\n');
24
  //Adresse
25
  value32= padresse;
26
  rs232_putc((int)(value32>>24));
27
  rs232_putc((int)(value32>>16));
28
  rs232_putc((int)(value32>>8));
29
  rs232_putc((int)(value32));
30
  rs232_putc('\n');
31
32
  rs232_putc('\n');
33
    }
Das ganze schaue ich mir dann im Hex-Modus meines Terminalprogrammes an. 
Was komisch ist, dass ich ab 0x8000 nur noch Müll zurück bekomme.

Mein RAM habe ich mit der xram.s
1
;; begin xram.S
2
;; Aktivierung des externen Memeory-Interfaces
3
#include <avr/io.h>
4
5
 .section .init1,"ax",@progbits
6
7
;;      entspricht XMCRA = ((1<<SRL2) | (1<<SRW11) | (1<<SRW10) | (1<<SRE));  
8
9
 ldi r16,_BV(SRE) | _BV(SRW10) | _BV(SRW11) | _BV(SRL2)
10
 sts XMCRA,r16
11
 
12
13
;; end xram.S
, welche im makefile eingebunden wurde, und mit
1
# 32 KB of external RAM, starting after internal RAM (ATmega128!),
2
# used for variables (.data/.bss) and heap (malloc()).
3
EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x808fff
(hoffentlich) eingebunden.


Warum geht das Ram nicht?
Warum genau ab 0x8000?
Was bedeutet Tdata und defsym?

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


Lesenswert?

Deine Endadresse in der Schleife von 0x808fff ist Kokolorus, auch die
Benutzung eines 32-bit int dafür.  Der RAM beim AVR benutzt 16-bit-
Adressen.

Deine Initialisierungsanweisung segmentiert den externen Speicher in
zwei Bereiche, wobei du den < 0x8000 mit 2 wait states betreibst, den
ab 0x8000 aber ohne wait states.

von Michael U. (amiga)


Lesenswert?

Hallo,

32k sind 0x0000...0x7FFF.
Ab 0x8000 beginnen die 2. 32k, da ist aber kein Ram mehr.

Falls A15 nicht ausgewertet wird, wird von 0x8000...0xFFFF der Ram 
genauso angesprochen wie im unteren 32k-Bereich (ist also gespiegelt).

Der Bereich bis zum Ende des internen Ram wird für den externen nur 
ausgeblendet, der wird nicht hinten rangehangen. Ausnahme ist: wenn A15 
nicht  dekodiert wird, ist der externe Rambereich von 0x0000 bis Ende 
interner Ram unter 0x8000... zu erreichen und damit benutzbar.

Wie das in C programmtechnisch aussieht weiß ich nicht, nur ASM...

Gruß aus Berlin
Michael

von Josef K. (josefk)


Lesenswert?

Jörg Wunsch wrote:
> Deine Endadresse in der Schleife von 0x808fff ist Kokolorus, auch die
> Benutzung eines 32-bit int dafür.  Der RAM beim AVR benutzt 16-bit-
> Adressen.
>
> Deine Initialisierungsanweisung segmentiert den externen Speicher in
> zwei Bereiche, wobei du den < 0x8000 mit 2 wait states betreibst, den
> ab 0x8000 aber ohne wait states.
Achso. Ich ging davon aus, dass das passt. Ist nur "abgeschaut". 
Schlecht anscheinend :)

Wie funkltioniert das dann? Wenn ich 32k ansprechen will, dann bräuchte 
ich einen Adressbereich von 0x0000 bis 0x7D00. Da mein interner Ram bei 
0x1100 aufhört, muss ich also den externen Ram dort anhängen. Damit 
hätte dieser einen Adressbereich von 0x1100 bis 0x8E00.  (????)
Also das ist meine Logik. Stimmt das?

Was müsste ich dann in EXTMEMOPTS eintragen?

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


Lesenswert?

Warum sprichst du den externen RAM denn nicht von 0x8000...0xFFFF an?
Bist du irgendwie darauf angewiesen, dass er nahtlos hinter dem
internen RAM liegt?

Ansonsten kannst du natürlich immer noch A15 ignorieren (das kann
man dann sogar als normales IO-Pin schalten).  Dann sprechen die
Adressen 0x1100 bis 0x7FFF den externen RAM auf 0x1100 bis 0x7FFF
an, während die Adressen 0x8000 bis 0x90FF den externen RAM auf
0x0000 bis 0x10FF ansprechen.  (Die Adressen 0x9100 bis 0xFFFF würden
dann nochmal den Bereich 0x1100 bis 0x7FFF erreichen.)

Für die Initialisierung ist es besser, sich nochmal das Datenblatt
zur Hand zu nehmen, statt irgendwo irgendwelchen Code abzugucken.
Welches Timing dein RAM braucht, weißt sowieso nur du.

von Josef K. (josefk)


Lesenswert?

Tut mir leid wenn ich mich da ein bißchen blöd anstelle.
ICh möchte lediglich, dass mein µC und mein Linker wissen, dass da noch 
32k dran hängen und diesen dann auch eigenständig nutzen.
Ich habe ein V62C518256 32kx8 Ram.
http://www.datasheetcatalog.org/datasheet/mosel/V62C518256.pdf

Ich habe außerdem zu EXTMEMOPTS noch nichts nützliches googeln können.

... und ich habe noch immer keine Ahnung wie das im makefile 
funktioniert.

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


Lesenswert?

EXTMEMOPTS kannst du genauso gut durch FOO oder BAR ersetzen, wenn
du alle Vorkommen dieses Strings in deinem Makefile ersetzt.  Das
ist einfach nur ein Name, der dann beim Zusammenbauen der Optionen
für den C-Compiler (und über diesen für den Linker) intern im Makefile
benutzt wird.

Leute, manchmal sollte man sich mit den Tools halt auch ein wenig
vertraut machen.  Automatismen für die Erzeugung von Makefiles
funktionieren halt für die Standardfälle, aber wenn man dann mit der
Hand dran schraubt, sollte man schon verstanden haben, was “make”
damit so anstellt.  Eigentlich ist “make” bezüglich des Makefiles
weiter nichts als ein Textprozessor.

Welche Optionen du dem Compiler/Linker sinnvoll mitgeben kannst,
steht in der avr-libc-Doku:

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_ext_ram

(Bitte auch den Link verfolgen, vor allem den zu malloc().)

Dem Datenblatt deines RAMs kann ich allerdings nicht entnehmen, mit
welchen Bauteilen und an welche Pins du ihn angeschlossen hast (auch:
wie schnell bspw. dein Latch ist), noch ist mir klar, welche der
beiden Geschwindigkeitsversionen du hast noch wie schnell dein AVR
getaktet wird.  Davon hängt aber ab, ob (und wie viele) wait states
du ggf. brauchst.

Bitte bemühe dich mal, dir die Timings selbst zu erschließen und
lass dir nicht alles vorkauen.  Das Datenblatt hat dafür Diagramme,
und das Datenblatt deines RAMs hat auch welche.  Falls du nicht gerade
den Ausgang für A15 mit in der Dekodierung hast und den RAM bei
gesetztem A15 (also Adressen >= 0x8000) nicht ansprichst, dann sollte
es schon irgendwie ein Hinweis sein, dass dein initialer Code für
zwei wait states funktioniert, für null wait states aber offenbar
nicht.

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.