Forum: Mikrocontroller und Digitale Elektronik xdata ram und externe Hardware


von Helmut Z. (heli69)


Lesenswert?

Hallo

Ich arbeite mit einem SAB80c535 mit 32kB externem RAM und habe auch noch 
Hardware wie ein Display, EEProm und einen Taktgeberbaustein in diesem 
Adressbereich.
Die Hardware lässt sich auch problemlos ansprechen ...
(Beispiel: #define OUT2 (*(volatile char xdata*)(0x1800)))
Je größer mein Programm wurde, umso instabiler wurde es auch. Ich habe 
nun die Vermutung, dass der C-Compiler (mm = large) die xdata Variablen 
in die gleichen Bereiche legt, in der auch meine Hardware sitzt.
In der Adressdekodierung beginnt mein externes RAM ab 0x8000. Dies habe 
ich dem RIDE Compiler auch eingstellt. Meine Hardware sitzt darunter 
0x0000-0x7FFF.
Trotzdem schmiert mein Programm ab und zu ab, wenn ich etwas auf mein 
Display schreibe.
Ebenso muss ich z.B. den Controler 5x starten, bis das Programm 
einwandfrei startet (oftmals sind nur wirre Zeichen am Display 
sichtbar). Irgenwann gehts dann, und dann läuft auch das Programm 
richtig.

Ebenso komisch funktioniert auch die Speicherreservierung mittels 
malloc.
Wenn ich mehrmals Speicher reservieren will, zeigt z.B der 2. oder 3. 
Pointer wieder in den Bereich des ersten ?! Als ob es dem Compiler egal 
ist ...

Gibt es irgendwas, was ich bei der Benutzung eines externen RAMS noch 
nicht weiß. Ich habe schon sehr viele Foren gelesen, aber noch keine 
Lösung gefunden.
Vielleicht kann mir jemand helfen, der ebenfalls einen RIDE Compiler 
benutzt und das Problem möglicherweise schon kennt.

Vielen Dank
Heli

von Matthias K. (matthiask)


Lesenswert?

Helmut Ziegler schrieb:
> In der Adressdekodierung beginnt mein externes RAM ab 0x8000. Dies habe
> ich dem RIDE Compiler auch eingstellt. Meine Hardware sitzt darunter
> 0x0000-0x7FFF.

Daran sollte sich der Linker auch halten. Schau mal in das Map-File des 
Linkers, auf welchen Adressen die XDATA-Variablen letztlich liegen.

Meist sind es andere Fehler, die zu derartigen Verhalten führen, wie 
Stack-Probleme, Array-Überläufe, falsche Pointer oder Zugriffsfehler auf 
die im XDATA gemappte Hardware. Oft auch falsche Einstellungen im 
Startup zur Initialisierung der Speicherbereiche.

Damals waren noch Hardware-Emulatoren, wie Hitex Teletest C51 üblich. 
Damit konnte man sowas gut eingrenzen. Hast Du wahrscheinlich nicht.

Mit dem Large-Modell habe ich bei den 8051ern nie gerne gearbeitet. Gab 
oft ähnliche Probleme. Small-Modell geht nicht?

(RIDE kenne ich nicht im Detail, deshalb alles nur prinzipiell.)

von Peter D. (peda)


Lesenswert?

Matthias K. schrieb:
> Mit dem Large-Modell habe ich bei den 8051ern nie gerne gearbeitet.

Ich benutze es grundsätzlich nicht, es erzeugt nur sehr großen und 
langsamen Code.

Das Modell sagt ja nur aus, wo die Variablen als default liegen.
Im small Modell kann man große Variablenfelder als xdata deklarieren, 
alle default Variablen bleiben dann schnell.

Malloc habe ich auch noch nie verwendet. Hast Du denn wirklich 
Variablen, deren Größe zur Compilezeit noch nicht bekannt ist?
Für die Benutzung von Malloc muß man bestimmt erstmal festlegen, wo der 
Variablen-Stack und wo der Malloc-Stack liegt.


Peter

von Reinhard Kern (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Für die Benutzung von Malloc muß man bestimmt erstmal festlegen, wo der
> Variablen-Stack und wo der Malloc-Stack liegt.

Hallo,

bei den meisten mir bekannten Modellen liegt der logische RAM-Bereich 
(also deklarierte Variablen, in dem Fall XDATA) am Beginn des 
physikalischen RAMs, direkt darauf folgt der Heap, von dem sich malloc 
bedient und der dabei nach oben wächst. Der Stack dagegen startet am 
oberen Ende des physikalischen Speichers und wächst nach unten - treffen 
sich Heap und Stack, kracht es. Man kann das aber zur Laufzeit 
überwachen lassen, das nützt aber i.A. nur wenig, denn wenn eine 
dynamische Variable nicht alloziert werden kann, ist das Programm 
sowieso irgendwie gescheitert.

Der Linker gibt die Adressbereiche aus, schaltet man MAP-Datei ein, 
bekommt man auch die Einzeladressen.

Gruss Reinhard

von Petrov (Gast)


Lesenswert?

Ich verwende zwar den MICRO-C51 Compiler, der hat aber auch Probleme 
wenn der XDATA  Bereich nicht bei 0X0000 beginnt.

Seit ich immer ein Dummy Array der Grösse 0X8000 als erstes anlege
funktionierts immer.

Gruß Peter

von Helmut Z. (heli69)


Lesenswert?

Vielen Dank erstmal für die promten Antworten.
Ich muss das ganze natürlich erst einmal verstehen (bin kein Profi). Mit 
dem Linker Map File habe ich nocht gar nichts zu tun gehabt. Ich hab 
jetzt mal reingeschaut -> viel Bahnhof =)
Den Malloc brauche ich deshalb, weil ich Daten von der seriellen 
Schnittstelle bekomme, die ich dann in Strukturen ablege. Ich habe da 
einen Pointer der auf ein Array von Strukturen zeigt. Und diesen 
Speicher kann ich erst reservieren, wenn ich weiß wieviel Strukturen es 
werden.

Ich werde jetzt mal ein paar Tips weiterverfolgen und mich gelegentlich 
wieder melden.

Lg.
Heli

von Helmut Z. (heli69)


Lesenswert?

Hallo

Vielen Dank nochmal für die Antworten. Ich habe dadurch neue Foren im 
Internet (und damit auch die Lösung) gefunden.

Mein Problem war, dass malloc am Controler seinen Bereich zuerst 
initialisiert und reserviert haben will. Dies geschieht bei RIDE mit der 
Function mempool_init(). Hierbei definiert man den Bereich, aus dem sich 
malloc dann bedient.

Seitdem laufen meine Programme stabil und alle Probleme (auch die nach 
dem Einschalten) sind weg. =) =)

Hier das Beispiel:

xdata unsigned char malloc_mempool[4000];

void main( void)
{
  short ret=0;

  mempool_init( (dynamic_allocator_struct allocmem*) malloc_mempool, 
sizeof(malloc_mempool) );

... u.s.w.

Lg.
Heli

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.