Forum: Mikrocontroller und Digitale Elektronik can't generate code for this expression / XC8 Mplab X


von Sven W. (ulminpoika)


Lesenswert?

Hallo wertes Forum,

Ich komme nicht um folgende Compiler-Meldung rum. Ich programmiere einen 
PIC18F4520 mit MPLAB X 1.90 und XC8 V1.20.

:: advisory: Employing 18F4520 errata work-arounds:
:: advisory:  * Corrupted fast interrupt shadow registers
:: warning: Omniscient Code Generation not available in Free mode
Main.c:180: error: can't generate code for this expression
(908) exit status = 1
make[2]: *** [dist/default/production/ComFaker.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
make[2]: Leaving directory `C:/MPLAB/ComFaker.X'
make[1]: Leaving directory `C:/MPLAB/ComFaker.X'

Hier Ausshnitte aus dem Quellcode, in dem ich den Inhalt eines 
Ringbuffers abfrage. Der Ringpuffer ist wie folgt gebaut:
1
#define ComBuffSize 255
1
struct RingBuff {
2
    unsigned char Head;
3
    unsigned char Tail;
4
    unsigned char Lap;
5
    unsigned char Element[ComBuffSize];
6
} ComBuff = {0,0,0,{0}};

Wenn Daten im Ringpuffer liegen, möchte ich die über die serielle 
Schnittstelle schicken. Ich habe folgende if-Bedingung, die nicht 
compiliert werden kann (der Inhalt wurde durch Nop() ersetzt:
1
if (((ComBuff.Lap == 0) && (ComBuff.Tail < ComBuff.Head)) || ((ComBuff.Lap == 1) && (ComBuff.Tail > ComBuff.Head))) {
2
        Nop();
3
    }
Mit ComBuff.Lap unterscheide ich, ob die Daten momentan über das 
Speicherende in den Speicheranfang reichen.

Irrerweise hat die Abfrage mal funktioniert. Ich hatte zwischenzeitlich 
integer Daten in der RingBuff Struktur (für Head und Tail, wegen 
größerer Puffergröße), aber die dann wieder auf char geändert.

Wenn ich folgende Teilbedingung durch eine 1 ersetze, wird der Code 
kompiliert:
1
(ComBuff.Tail < ComBuff.Head)
als:
1
if (((ComBuff.Lap == 0) && (1)) || ((ComBuff.Lap == 1) && (ComBuff.Tail > ComBuff.Head))) {
2
        Nop();
3
    }

Kennt jemand eine Strategie, wie man diese "can't generate code for this 
expression" Fehler ausbügeln kann? Leider versagt das Microchip Forum 
momentan, sodass die meisten Google Treffer auch nix taugen...

Vielen Dank für Tips und Tricks,
Ulminpoika

von chirs (Gast)


Lesenswert?

probier mal folgendes:

if (!ComBuff.Lap && ComBuff.Tail < ComBuff.Head || ComBuff.Lap == 1 && 
ComBuff.Tail > ComBuff.Head) {
        Nop();
    }

Aber, wieso fragst du, ob das Ende vor dem Anfang ist, wenn kein 
Überlauf (lap) stattgefunden hat ?

Weiters, ComBuffSize sollte warscheinlich 256 sein.

von B. S. (bestucki)


Lesenswert?

Ich würde als erstes die neuste Version des XC8 installieren (1.30).

Schau mal auf Seite 36 in den aktuellen Release Notes (Kapitel: Known 
Issues):
http://ww1.microchip.com/downloads/en/DeviceDoc/Readme_XC8v1_30.pdf

von Sven W. (ulminpoika)


Lesenswert?

Hallo,

danke für eure Antworten:

@chirs: Der Überlauf ComBuff.Lap wird 1 gesetzt, wenn der Kopf 
ComBuff.Head wieder die Anfangsadresse indiziert. ComBuff.Lap wird 
wieder zurück auf 0 gesetzt, wenn das Ende ComBuff.Tail den Sprung 
zurück auf die Anfangsadresse macht.
Und ja, ComBuffSize sollte tatsächlich 256 sein :-).

@be stucki: Vielen Dank für den interessanten Link. Zu den Änderungen in 
V1.30 ist aber nichts zu den "Can't Generate Code" messages gesagt.

Ich hab ein wenig an den Datenwerten und -typen gedreht. Mittlweile 
kompiliert das ganze wieder, obwohl die Datentypen für die 8bit Struktur 
eigentlich eher umständlicher sind.
1
#define ComBuffSize 1000
1
struct RingBuff {
2
    unsigned int Head;
3
    unsigned int Tail;
4
    unsigned char Lap;
5
    unsigned char Element[ComBuffSize];
6
} ComBuff = {0,0,0,{0}};
1
if (((ComBuff.Lap == 0) && (ComBuff.Tail < ComBuff.Head)) || ((ComBuff.Lap == 1) && (ComBuff.Tail > ComBuff.Head))) {
2
        Nop();  // Hier steht natürlich weitere Code
3
    }

Vielen Dank trotzdem für eure Unterstützung. Wenn ich der genauen 
Ursache noch auf die Schliche komme, werde ich sie hier posten.

Ulminpoika

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.