Forum: Mikrocontroller und Digitale Elektronik MSP430 seltsamer Fehler: "placement fails for object."


von Wildkatz (Gast)


Lesenswert?

Sitze hier mal wieder am Notebook und programmiere MSPg2211, da taucht 
dieser seltsame Fehler auf:

"../lnk_msp430g2211.cmd", line 60: error: placement fails for object 
".text",
   size 0x810 (page 0).  Available ranges:
   FLASH        size: 0x7e0        unused: 0x7e0        max hole: 0x7e0
error: errors encountered during linking; "AlarmClock.out" not built

Klingt fast als wäre mein Code zu lang. Er enthält einige recht lange 
Funktionen zur Ansteuerung eines Schieberegisters, das Hauptprogramm ist 
eher kurz:
1
void main(void)
2
{
3
  long counter = 0;
4
  short zaehler  = 0;
5
  
6
  WDTCTL   = WDTPW | WDTHOLD;      //Watchdog stoppen
7
  P1DIR   = BIT0|BIT1|BIT2;      //Outputs setzen
8
  while(1)
9
  {
10
    for(counter = 0; counter < 20000; counter++){}
11
    writevalue(zaehler);
12
    zaehler++;
13
    if(zaehler==10)zaehler=0;
14
  }
15
}


Besonders seltsam:
Zuvor hatte ich in der Main einfach nur die while schleife mit 
writevalu(99) stehen. Da hat der Compiler noch nicht aufgemuckt. Nun 
wollte ich die Zahlen auf der Anzeige mal durchlaufen lassen und dann 
das.

Noch erwähnenswert:
-ich programmiere den µC mit dem Launchpad

-es ist reiner C-Code

-schreibe den Code mit Code Composer Studio. Die kostenlose Version hat 
eine beschränkte Länge für den Code, glaub 16 KB?! Meine Quelldatei 
selbst hat 9354  bytes

-in dem Projektordner fliegt noch viel Schrott rum, wo ich kein Bock hab 
zu löschen. Ist aber natürlich alles "excluded from built"

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wildkatz schrieb:
> Die kostenlose Version hat eine beschränkte Länge für den Code, glaub 16 KB?!
> Meine Quelldatei selbst hat 9354  bytes

Der Compiler erzeugt nicht mehr als 16 kB Binärcode, wie groß der 
Quelltext ist, hat damit nur sehr wenig zu tun.

Das Problem aber ist ein anderes: Der aus Deinem Programm erzeugte 
Binärcode ist größer als der im µC zur Verfügung stehende Platz - das 
Flash-ROM ist voll.

Anhand Deines Codeschnipselchens lässt sich natürlich nicht beurteilen, 
was hier so viel Code erzeugt.

Deine Zählvariable "counter" ist vom Typ long, also 32 Bit groß. Der 
MSP430 kann 32-Bit-Werte nicht direkt verarbeiten, also ist für 
32-Bit-Berechnungen etwas mehr Programmcode erforderlich als für 
16-Bit-Variablen. Das sind zwar nur eine Handvoll Bytes, aber das 
läppert sich.

Wenn Du aber eh' nur bis 20000 zählst, gibt es überhaupt keinen Grund, 
einen long einzusetzen, das passt auch in einen (16 Bit großen) int.

von Wildkatz (Gast)


Lesenswert?

Danke für die Einschätzung.
Dann lag ich mit meiner Einschätzung ja gar nicht so falsch. Aber was 
kann ich tun?! Ich hab hier noch mehr MSPs rumliegen, aber mehr als 1 KB 
Flash hat keiner. Und das Programm ist noch lange nicht fertig. Es kommt 
mindestens nochmal die selbe Menge dazu. Enttäuschend - finde ich schon 
en bisschen schwach, die Dinger haben alle Finessen ADUs, Oszillatoren 
und Kram aber en gescheiter Speicher Fehlanzeige.

von Wildkatz (Gast)


Angehängte Dateien:

Lesenswert?

Ok hier is ma noch die ganze Quelldatei.

von Linker (Gast)


Lesenswert?

Wildkatz schrieb:
> Enttäuschend - finde ich schon
> en bisschen schwach, die Dinger haben alle Finessen ADUs, Oszillatoren
> und Kram aber en gescheiter Speicher Fehlanzeige.

Na, na, du wilde Katze, kannst du mit einem Luftgewehr einen Elefanten 
erlegen? Immer den passenden Controller für die Anwendung wählen. Wenn 
du viel 32 Bit verarbeiten willst, nimm einen ARM. Bei kleinen 
Applikationen im Low Power und Low Cost Bereich bist du bei MAPS430 und 
kleinen AVR gut bedient.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wildkatz schrieb:
> Enttäuschend - finde ich schon
> en bisschen schwach, die Dinger haben alle Finessen ADUs, Oszillatoren
> und Kram aber en gescheiter Speicher Fehlanzeige.

Es gibt auch MSP430-Varianten mit ganz erheblich mehr Speicher; der 
'F5834 beispielsweise hat 256 kB Flash-ROM und 16 kB RAM.

Davon abgesehen ist Dein Code etwas, äh, umständlich. Wie ich bereits 
schrieb, solltest Du Dir mal Gedanken über die verwendeten Datentypen 
machen. Welchen Sinn hat es, einen 32-Bit-Datentyp zu verwenden, um 
damit nur bis 50 zu zählen?

Desweiteren solltest Du Dir mal ansehen, was eine Schleife ist; was um 
alles in der Welt soll der Code in den segmentX-Funktionen?

Bist Du Dir dessen bewusst, daß es auch eine 
Hardware-SPI-Schnittstelle gibt?

von Wildkatz (Gast)


Lesenswert?

Die longs habe ich schon geändert. Dann ging es wieder ein paar Zeilen 
mehr zu schreiben. Was ne Schleife ist ist mir bestens bekannt, ich 
arbeite bloß mit einem Schieberegister das doppelt verzögert (wenn ich 
ein Signal anlege steht es erst nacht 3 steigenden Flanken im Register). 
Daher wollte ich erstmal den Code so schreiben dass er überhaupt läuft 
bevor es an die Feinheiten geht. Werde das mit den Schleifen also noch 
verbessern, ob der Speicher langt scheint mir trotzdem fraglich.

von Wildkatz (Gast)


Lesenswert?

würds eventuell was bringen das "i" als globale Variable zu deklarieren? 
Es wird ja in fast allen Funktionen gebraucht aber nie gleichzeitig.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Nein, das ist nicht relevant. i ist eine Variable, die landet im RAM. 
Und nicht das ist es, was bei Deinem, äh, Programmierstil knapp wird. 
Und ob i nun global deklariert wird oder als automatische Variable auf 
dem Stack landet, ändert nichts daran, daß sie im RAM bleibt.

Wildkatz schrieb:
> Was ne Schleife ist ist mir bestens bekannt, ich
> arbeite bloß mit einem Schieberegister das doppelt verzögert (wenn ich
> ein Signal anlege steht es erst nacht 3 steigenden Flanken im Register).

Dann poste doch mal einen Schaltplan, damit man das nachvollziehen kann.

von Stefan (Gast)


Lesenswert?

Ist es eigentlich notwendig, dass segmenta() nach der Null zwei weitere 
Nullen sendet und die anderen segment Unterroutinen nach der Null nur 
Einsen senden?

Wenn die letzten beiden Bits bei segmenta() auch Eins sein dürfen 
könntest du die ganzen Unterprogramme segmenta() bis segmentg() durch 
ein einziges Unterprogramm ersetzen, dem du die Stelle der Null als 
Parameter übergibst:
segment(1), segment(2), ...
Der Übergabeparameter+1 bestimmt dann die Anzahl der nach der Null zu 
übertragenen Einsen.

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.