2012-06-11 6 views
6

Ich kompiliere für LPC1114, ein kleines ARM (eigentlich Cortex) Ziel. RAM ist viel begrenzter als ROM. Ich benutze den neuesten Mentor (CodeBenchLite) GCC Compiler (GCC 4.6.3). Ich habe einige konstante Objekte, die ich gerne im ROM haben möchte. Soweit ich verstehe, sollte das ffx-Objekt im unten stehenden Code in ROM (Code) enden, aber stattdessen wird es in DATA platziert.Wie bekomme ich GCC, um ein C++ consExpr in ROM zu platzieren?

class flop { 
    public: 
     int x; 
     constexpr flop(int x) : x(x){} 
}; 

extern constexpr flop ffx(1); 

Wie kann ich den Compiler überzeugen das Objekt vorab zu berechnen und sie in ROM platzieren?

oder vielleicht soll ich fragen:

  • kann ich irgendwie erwarten, dass die G ++ Compiler ROMable Daten für ffx
  • wenn ja, ist mein Code korrekt für diesen
  • wenn so zu erzeugen, für die G ++ Version wird dies unterstützt (ich benutze 4.6, vielleicht ich brauche 4.7?)

============================= ==========

Dieser Bugzilla-Eintrag c++/49673 scheint anzuzeigen, dass meins ein bekanntes Problem ist, das wahrscheinlich in GCC 4.7 behoben wurde. Leider benutze ich lieber die Mentor/CodeSourcery, die immer noch unter 4.6.3 steht. Ich denke, vorerst stecke ich mit dem Käfer fest. :(

+1

Ich kenne die Architektur nicht, aber scheint es nicht ein Oxymoron zu sein, zu * schreiben * zu * schreibgeschütztem * Speicher zu versuchen? –

+1

@JohnDibling: Es scheint so, aber du liegst falsch. Kleine Prozessoren haben oft eine Möglichkeit, Ihr Programm auf ROM zu flashen. –

+0

Es gibt nichts, was Ihnen der C++ - Standard bietet. Sie können jedoch * scatterloading * wie hier beschrieben ausprobieren: [Ortung von Code und Daten im Speicher (Scatterloading)] (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc. faqs/ka3558.html). HTH! – dirkgently

Antwort

1

Update # 2: Testergebnisse mit gcc 4.7.0

Diese in der Tat in gcc 4.7.0 festgelegt ist Ihr Code erzeugt die folgende Assembler-Ausgang:.

.file "constexpr.cpp" 
    .globl _ffx 
    .section .rdata,"dr" 
    .align 4 
_ffx: 
    .long 1 

was Sie wahrscheinlich wollen.Upgrade?

Ich denke, dass Sie eine plattformspezifische Lösung dafür benötigen.Siehe Locating code and data in memory (Scatterloading):

Mit Scatterloading können Sie eine Anwendung in mehrere separate Code- und Datenbereiche aufteilen, die über die Adresskarte verteilt sind. Die Lage dieser Bereiche kann zwischen der Ladezeit und Laufzeit unterscheiden:

  1. Lastbereiche Anwendungscode enthalten und/oder durch die Anwendung verwendet, um Daten bei Einschalten/Ladezeit (in der Regel ROM).

Statt allein auf gcc verlassen, versuchen Verwendung von armlink zu machen, wie in den darin enthaltenen Link oben vorgeschlagen.

Update: Ich sah den GCC-Fehler, den Sie bemerkt haben. LLVM/MinGW ist gleichermaßen hoffnungslos. Aber ich habe mit GCC 4.6 herum spielen und hier ist etwas, denke ich kann helfen Ihnen:

struct Data 
{ 
    int i;  
}; 
constexpr Data getData() { return Data{1}; } 

Wenn stattdessen eine Ctor zu haben, haben Sie eine constexpr Funktion, und versuchen, den Assembler Ausgabe zu erzeugen, Die Ausgabe ist normalerweise leer (keine .data Sektionen).Und wenn Sie diese verwenden, um einige Variable initialisiert werden (in globalen Bereich) wie folgt:

const Data foo = getData(); 

Sie würden eine Versammlung erhalten wie folgt:

.file "constexpr.cpp" 
    .section .rdata,"dr" 
    .align 4 
__ZL3foo: 
    .long 1 

(dies ist mit g++ -std=c++0x -S Kommandozeile). Funktioniert das für dich?

+0

Siehe meinen Kommentar zur Travis-Antwort (und ich habe die Frage bearbeitet): Das Problem besteht darin, dass der Compiler RAM reserviert und Initialisierungscode generiert, anstatt initialisierte konstante Daten zu generieren. –

+0

@WoutervanOoijen: Ich denke, es könnte mit der Tatsache zusammenhängen, dass ein CTor eine spezielle Member-Funktion ist und der Compiler dieses Bit Code erzeugt, um sicherzustellen, dass alles gut geht. Ändert sich die Ausgabe mit aktivierten Optimierungs-Flags (ich denke nicht, dass es das wäre, aber ich denke, es ist einen Versuch wert). Jedenfalls habe ich meine Antwort mit meinen neuesten Untersuchungen aktualisiert und es kann Ihnen helfen. – dirkgently

+0

Ja, das endet in .rodata, aber es hilft mir nicht viel: Der Code, den ich zeigte, ist ein vereinfachtes Beispiel, ich brauche ein Klassenobjekt mit einem nicht-trivialen (aber immer noch consExpr) ctor. Danke für die Überprüfung von LLVM. –

0

Meiner Erfahrung nach werden const Daten in einen Nur-Lese-Abschnitt geschrieben, so dass alle Daten in diesem Abschnitt in ROM geschrieben werden können (oder in FLASH programmiert werden können).

Die GCC-Linker-Anweisungsdatei (* .ld) kann Adressen verschiedenen Abschnitten zuweisen.

Eine weitere Alternative besteht darin, große Datenstrukturen (z. B. Schriftarten) in die Assemblersprache zu platzieren. Die Assemblersprache kann die Daten einfacher in Segmente unterteilen als die C- oder C++ - Sprache.

Eines unserer nächsten Ziele ist es, die Daten von unserer ausführbaren Datei zu trennen. Dies verkürzt die ausführbare Datei und reduziert die Testzeit für die ausführbare Datei.

+0

Ein const-Objekt, das einen (nicht-trivialen?) Initialisierer hat, wird nicht im ROM platziert. Einer der Gründe für conetexpr ist es (soweit ich es verstehe), dies zu ermöglichen, aber es scheint mir nicht zu passieren.(constexpr ist ein C++ 0x09/11-Konstrukt, das stärker ist als const). –