Forum: Mikrocontroller und Digitale Elektronik PIC24 "Not enough RAM for all variables"?


von Matthias B. (pegasi)


Lesenswert?

Hallo,

ich nutze einen PIC24HJ128GP306. Dieser besitzt 16KB RAM. Als Compiler 
verwende ich den CCS C PCD.

Vorweg möchte ich gleich anmerken, dass ich keinen externen Speicher 
verwenden kann.
Mein Ziel ist es, eine Tabelle mit 7000 16bit Integer-Werten im RAM zu 
hinterlegen. Das Datenvolumen beträgt damit 14KB. Die restlichen 
Variablen belegen kaum mehr als 100 Byte. Versuche ich das Programm zu 
kompilieren, gibt der Compiler die Fehlermeldung "Not enough RAM for all 
variables" zurück. Verkleinere ich die Tabelle auf 3000 Einträge, so 
wird das Programm anstandslos kompiliert mit einer RAM-Belegung von 37%. 
Rechnet man diesen Wert auf 7000 Einträge hoch, so dürfte maximal 87% 
des RAMs belegt sein. Auch eine Unterteilung der Tabelle in 14 kleine 
Tabellen mit je 500 Einträgen, führt zum gleichen Compilerabbruch.

Benutzt man den Project-Wizard des Compilers, kann dort eine Option zur 
Verwendung von 16bit-Pointern für volle RAM-Addressierung ausgewählt 
werden. Leider bringt auch dieser Punkt nichts.

Was mache ich falsch?

Besten Dank für die Hilfe schonmal,
Matthias

von Christian J. (elektroniker68)


Lesenswert?

Hallo,

is ja klar, in einem Stück kriegst Du das nicht unter, weil das RAM 
bankweise abgelegt ist. Da kann der Compiler auch nichts für. Far 
pointer könnten etwas bringen.

von (prx) A. K. (prx)


Lesenswert?

PIC24 (entspricht dsPIC30 ohne "ds") adressiert linear, nicht banked. 
Das mit 16bit Adressen bezieht sich auf statische d.h. direkt 
adressierte Daten, da die Architektur nur 4KB direkt adressieren kann. 
Hier nicht relevant.

von Master S. (snowman)


Lesenswert?

wenn es dir möglich ist den C30 von Microchip zu verwenden, dann 
verlasse CCS, denn der ist bekannt, dass er verbugt ist.
für die PIC16Fxxx ist ja CSS ganz nett als C-compiler aber für alle 
anderen, würde ich den kostenlosen des chip-herstellers nehmen.

von Matthias B. (pegasi)


Lesenswert?

Danke schon mal für die schnelle Hilfe.

Ich hab jetzt mal 70 Tabellen mit je 100 Einträgen erzeugt mit dem 
selben Ergebnis.
Nun habe ich schrittweise die Tabellen auskommentiert. Bei 
Tabellennummer 40 hat der Compiler dann kompiliert. Das entspricht (laut 
Kompiler genau 50% RAM-Belegung). Sobald ich 41 Tabellen kompilieren 
will, gibts eine Abbruch. Kann jemand damit was anfangen?

von Severino R. (severino)


Lesenswert?

Matthias B. wrote:

> Kann jemand damit was anfangen?

Am ehesten der Hersteller des Compilers. Hat der kein Forum oder FAQ 
oder tech. Support?

von Andi (Gast)


Lesenswert?

Bist du sicher, dass nicht 32bit integer erzeugt werden? Das würde 
erklären weshalb du nur halb so viele variablen unterbringen kannst.

von Gerhard (Gast)


Lesenswert?

Hi

MPLAB hat auch einen Bug (oder ist es: it's a feature not a bug ?) Die 
RAM-Auslastung zeigt nur global definiertes RAM an, rechnet weder lokal 
verwendetes noch RAM, das z.B. von Bibliotheks-Funktionen verwendet 
wird. Ausserdem dürfte der PIC24, wie der dsPIC30 den Stack im RAM 
haben, der also auch von deinen 16k abzuziehen ist.

Gerhard

von Benedikt K. (benedikt)


Lesenswert?

Gerhard wrote:
> Die
> RAM-Auslastung zeigt nur global definiertes RAM an, rechnet weder lokal
> verwendetes noch RAM,

Das ist bei C Compilern so üblich, mir ist zumindest keiner bekannt der 
das anzeigt.

von Matthias B. (pegasi)


Lesenswert?

Danke für die vielen Antworten. Leider bekomme ich das System nicht zum 
Laufen. Ich habe die Tabelle in 7 x 1000 Tabelleneinträge unterteilt.

Der RAM teilt sich wie folgt auf:
Addresse 0x0000 - 0x07FF SFR Space (Special Function Register Space)
Addresse 0x0800 - 0x3FFF X Data RAM
Addresse 0x4000 - 0x4800 DMA RAM (wird als normaler Data RAM benutzt)

Compiliere ich meinen Code gibts die bekannte Fehlermeldung "Not enough 
RAM for all variables". Ein Blick in die .sym Datei sagt mir folgendes:

804-FD3 MAIN.tab1
FD4-17A3 MAIN.tab2
17A4-1F73 MAIN.tab3
1F80-1FFF Stack
2000-27CF MAIN.tab4
27D0-2F9F MAIN.tab5
2FA0-376F MAIN.tab6
3770-3F3F MAIN.tab7

jedes tab-Feld besitzt 2000 Einträge (also 16bit pro Eintrag). Der Stack 
befindet sich im RAM, aber alle tab-Felder sollten in den Speicher 
passen.
Compilierung bricht trotzdem ab.

Nun habe ich mein Projekt nochmal neu mit dem Wizard erstellt. Auf 
einmal Compiliert PIC den identischen Code. Allerdings will jetzt der 
PIC nicht mehr richtig. Start --> nichts passiert (keine LEDs leuchten, 
usw.).
Nur wenn ich in die ISR einen einzigen Funktionsaufruf anstelle des 
gleichen Codes packe, macht der PIC wieder was er soll. Schön langsam 
kommt's mir vor, als wäre es Zufall ob der Code Compiliert und dann auch 
funktioniert.

Hier die ISR mit der es nicht funktioniert hat:
1
#int_CNI                              //Interrupt für Schalter
2
void  CN_PIN_C14_isr(void) 
3
{
4
    static int8 a = 0;
5
    disable_interrupts(INTR_CN_PIN|PIN_C14);
6
    delay_ms(125);
7
    if (a == 0) {
8
        output_high(PIN_D3);
9
        a = 1;
10
    }
11
    else {
12
        output_low(PIN_D3);
13
        a = 0;
14
    }
15
    enable_interrupts(INTR_CN_PIN|PIN_C14);
16
}

Und hier die ISR mit der der PIC so arbeitet wie gewünscht:
1
int schalter(int a) {
2
    delay_ms(125);
3
    if (a == 0) {
4
        output_high(PIN_D3);
5
        a = 1;
6
    }
7
    else {
8
        output_low(PIN_D3);
9
        a = 0;
10
    }
11
    return a;
12
}
13
14
15
#int_CNI                              //Interrupt für Motorstart
16
void  CN_PIN_C14_isr(void) 
17
{
18
    static int8 a = 0;
19
    disable_interrupts(INTR_CN_PIN|PIN_C14);
20
    a = schalter(a);
21
    enable_interrupts(INTR_CN_PIN|PIN_C14);
22
}

gleicher Code, aber PIC läuft. Hat einer ne Erklärung für dieses 
Phänomen?
Das einzige was ich mir vorstellen kann ist (beim Blick in die .sym):

funktionierender Code:

802     CN_PIN_C14_isr.a
804-FD3 MAIN.tab1
FD4-17A3 MAIN.tab2
17A4-1F73 MAIN.tab3
1F80-1FFF Stack
2000-27CF MAIN.tab4
27D0-2F9F MAIN.tab5
2FA0-376F MAIN.tab6
3770-3F3F MAIN.tab7
3FC2-3FC3 schalter.a

nicht funktionierender Code:

802     CN_PIN_C14_isr.a
804-FD3 MAIN.tab1
FD4-17A3 MAIN.tab2
17A4-1F73 MAIN.tab3
1F80-1FFF Stack
2000-27CF MAIN.tab4
27D0-2F9F MAIN.tab5
2FA0-376F MAIN.tab6
3770-3F3F MAIN.tab7

dass der Interrupt vor den Bereich der Tabellen im RAM gepackt wird und 
bei der ISR ohne Funktionsaufruf dann Teile zu weit, in den bereits 
durch die Tabellen alloziierten Teil des RAMs, geschoben werden. Auf 
jeden Fall sehr seltsam. Vom Hersteller des Compilers habe ich auf meine 
Anfrage leider noch keine Antwort erhalten

von Gerhard (Gast)


Lesenswert?

Hi

keine Ahnung, wo das Problem ist. Aber vielleicht solltest du doch mal 
den C30 von Microchip testen. Ich hab schon ein paar Projekte mit dem 
dsPIC30 gemacht und keine Probleme von dieser Art gehabt. Zumindest 
keine, die sich nicht klären liessen. Wenn du mit dem C30 arbeitest, 
hast du ausserdem den Vorteil, dir Hilfe beim Microchip-Forum holen zu 
können, wenn dir hier keiner helfen kann.
Der Umstieg ist vielleicht nicht ganz einfach, ist aber langfristig 
sicher der bessere Weg.

Gerhard

von Matthias B. (pegasi)


Lesenswert?

Gerhard wrote:
> Hi
>
> keine Ahnung, wo das Problem ist. Aber vielleicht solltest du doch mal
> den C30 von Microchip testen. Ich hab schon ein paar Projekte mit dem
> dsPIC30 gemacht und keine Probleme von dieser Art gehabt. Zumindest
> keine, die sich nicht klären liessen. Wenn du mit dem C30 arbeitest,
> hast du ausserdem den Vorteil, dir Hilfe beim Microchip-Forum holen zu
> können, wenn dir hier keiner helfen kann.
> Der Umstieg ist vielleicht nicht ganz einfach, ist aber langfristig
> sicher der bessere Weg.
>
> Gerhard


Danke für den Tip, aber der PIC24 ist für meine Diplomarbeit und ich bin 
mir nicht sicher, ob ich später nochmal mit PICs arbeiten werde.

von Franko P. (sgssn)


Lesenswert?

Hi

dann versuchs doch mal da:
http://www.ccsinfo.com/forum/

vielleicht kann dir dort geholfen werden....

Gerhard

von Matthias B. (Gast)


Lesenswert?

Danke für die Info.
Hab ich schon. Leider mit mäßigem Erfolg. Mittlerweile macht die Kiste 
aber immer mehr, was sie soll. Ganz bugfrei ist eben weder ein Compiler 
noch ne Hardware, ohne jetzt behaupten zu wollen dass mein Problem von 
einem Bug herrührt ;)

von Matthias B. (pegasi)


Lesenswert?

So, nun hab ich die Lösung:

mit
1
#BUILD(STACK=0x0802:0x881)

kann man den Stack im RAM so nach vorne verschieben, dass die Tabelle 
als ganzes danach in den RAM passt.

Problem gelöst.

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.