Hallo zusammen.
Ich nutze IAR Embeddet Workbench IDE V.5.20 und den µC MSP430F2013.
Ich bekomme folgenden Error:
Error[e104]: Failed to fit all segments into specified ranges. Problem
discovered in segment CODE. Unable to place 25 block(s) (0x7bc byte(s)
total) in 0x7b6 byte(s) of memory. The problem occurred while processing
the
Heißt das mit anderen Worten, dass der µC stack voll ist?
Das wäre sehr krass, weil so viel Code habe ich noch gar nicht
geschrieben.
Vielen Dank alle Hilfe. :)
BL
BL schrieb:> Heißt das mit anderen Worten, dass der µC stack voll ist?
Nein, schlimmer: der Programmspeicher ist voll.
> weil so viel Code habe ich noch gar nicht geschrieben.
Zeig doch mal, was du hast. Als Dateianhang mit Nachmane *.c
BL schrieb:> weil so viel Code habe ich noch gar nicht> geschrieben.
Es reicht ja, wenn der von Dir geschriebene Code größere
Libraryfunktionen einbindet -- der 'F2013 ist beispielsweise gar kein
guter Kandidat für Floatingpoint-Arithmetik.
Mit nur 2 kiB Flash-ROM kann man keine großen Sprünge machen.
ui ui ui ^^
Gibt es in IAR die Möglichkeit, die Größe des compilierten Codes zu
sehen?
2 KB Flash Memory ist nicht viel, stimmt.
Als Code habe ich paar headerfiles mit defines drin und dann das
USI_I2C.c file mit den state machines für den jeweiligen Befehl für das
I2C Protokol.
Als kleines Beispiel:
BL schrieb:> USI_I2C.c file mit den state machines für den jeweiligen Befehl
#den# state machines?
Wieviele sind es denn?
Den Optimizer hast du aber schon eingeschaltet?
für das
> I2C Protokol.>> Als kleines Beispiel:>>
Na ja. das sieht jetzt nur so weltbewegend aus. Aber im Grunde sind das
nur ein paar Zuweisungen. Also nichts dramatisches. Das braucht ein paar
Bytes, aber bis 2Kb ist da noch weit hin.
Such nach effektiven Berechnungen! Dort könnte was unbeabsichtigtes
stecken. Oder tu das, was Lothar vorgeschlagen hat: Häng deinen verd....
Code hier an. Dann helfen wir dir das Zeug auf Kandidaten durchzusehen.
Das ist doch nicht so schwer. Wenn du vom Arzt einen Rat willst, gehst
du ja auch selber hin, damit er sich die Sache mal selber ansehen kann.
Karl Heinz Buchegger schrieb:> #den# state machines?> Wieviele sind es denn?
Es sind 5 statemachines. Für jeden Befehl eine. Siehe Funktionen unten:
int I2C_SendCommand (int iCommand);
int I2C_Write_1ByteRegister (int iRegister);
int I2C_Write_2ByteRegister (int iRegister);
int I2C_Read_1ByteRegister (int iRegister);
int I2C_Read_2ByteRegister (int iRegister);
In der main ist einfach eine kleine while-Schleife mit Befehlen. Zum
Beispiel:
1
//config. temp. sensor
2
giDS1621_Sensor_Register=DS1621_ACCESS_CONFIG;
3
USICTL1|=USIIFG;// Set flag and start communication
4
LOW_POWER_MODE_1;
5
__no_operation();
6
Sleep(20);//give sensor time to write to EEPROM
7
8
if(giI2C_ERROR)
9
{
10
USI_ERROR();
11
break;
12
}
13
14
//start temp. conversion
15
giDS1621_Sensor_Register=DS1621_START_CONVERSION;
16
USICTL1|=USIIFG;// Set flag and start communication
17
LOW_POWER_MODE_1;
18
__no_operation();
19
Sleep(10);
20
if(giI2C_ERROR)
21
{
22
USI_ERROR();
23
break;
24
}
25
...
Gibt es in IAR die Möglichkeit, die Größe des compilierten Codes zu
sehen?
Ich habe jetzt unter "Optimizations" von Low auf High gestellt.
Jetzt scheint etwas mehr Platz zu sein. Der Fehler ist weg.
Würde aber gerne noch sehen, wieviel Platz denn da nun ist.
BL schrieb:> Ich habe jetzt unter "Optimizations" von Low auf High gestellt.> Jetzt scheint etwas mehr Platz zu sein. Der Fehler ist weg.>> Würde aber gerne noch sehen, wieviel Platz denn da nun ist.
WIes beim IAR ist, weiß ich nicht.
Aber die übliche Bezeichnung dafür ist: Du willst ein Map erzeugt haben,
oder Memory Map. Und die Option müsste sich irgendwo bei den Linker
Optionen finden.
Danke! Hab nun nen Map File erstellt. Ich schicks dir mal im Anhang.
Nach der Aussage des Files, verbrauche ich 1,5k ROM Speicher.
Mal suchen, was denn da soviel speicher frißt....
[Den Code selbst darf ich leider nicht senden. Sorry an alle!]
Also falls noch jemand die Antwort wissen möchte:
Ich habe dem Code auf den Zahn gefühlt. Es sind tatsächlich die state
machines. Benötigen 1k ROM Speicher. Können aber nicht kleiner
programmiert
werden. Böse böse... ^^
Vielen Dank euch fürs Helfen!
BL
BL schrieb:> if (giI2C_ERROR)> {> USI_ERROR ();> break;> }BL schrieb:> __no_operation();> Sleep(10);
Wenn der ganze Code solche Dinge und weitere Überraschungen enthält,
wundert mich dein Speicherproblem nicht.
BL schrieb:> LOW_POWER_MODE_1;> __no_operation();> Sleep(20); //give sensor time to write to EEPROM
kurze Fragen:
Warum wird mitten im Ablauf (keine Verzweigung) der Low Power Mode
gewechselt?
Warum wird vor einem Delay ein NOP eingefügt?
> if (giI2C_ERROR)> {> USI_ERROR ();> break;> }
weitere Frage:
Warum wird ein if Zweig am Ende unterbrochen?
Ja, ja, ich weiß, der Compiler optimiert das eine oder andere. Aber man
sollte im Groben schon wissen, was man tut.
Das break dient, um aus der while-Schleife auszubrechen. Bevor man sich
Gedanken, um Low Power macht, sollte erstmal das Programm funktionieren.
Ein __no_operation gefolgt vom sleep ist natürlich unschön...
Ihr solltet wissen, dass ihr euch grad über einen Code gedanken macht,
der nur zu testzwecken geschrieben wurde, um das I2C Protokol zu testen
und dann gelöscht wird.
Hier kurz die Erklärung:
Der Low-Power Mode wird nicht gewechselt.
__no_operation(); <-- Diese Zeile ist nur für die IAR Workbench
gedacht. War in den Beispiel Codes von Texas Instruments so angegeben.
Das ist aber kein Low-Power Mode für den µCs.
Sleep() <-- Sleep ist kein delay, sondern ein tatsächliches "sleep".
Der µC geht da, der angegebenen Zeit entsprechend in Low-Power Mode und
wird dann von einem Interrupt geweckt.
Die if-Abfragen sind in einer while-Schleife, die mehrere Befehle
hintereinander ausführt. Entsteht zwischendrin ein Error, wird die
gesamte
while-Schleife unterbrochen.
--------------------
Zusatz: Also mein Speicherproblem ist ja im Grunde "behoben". Ich habe
1) die Optimierung von low auf high gesetzt
2) aus den 5 statemachines, eine gemacht.
Damit habe ich 800 bytes gesparrt. Meine Sleep Funktion frisst natürlich
auch bytes, aber ich möchte sie trotzdem nicht durch eine delay funktion
austauschen.
Danke für euer Interesse an meinem Problem! :)
BL schrieb:> Ihr solltet wissen, dass ihr euch grad über einen Code gedanken macht,> der nur zu testzwecken geschrieben wurde, um das I2C Protokol zu testen> und dann gelöscht wird.
Sei doch froh, dass man es gut mit dir meint oder Mitleid hat. ;-D
BL schrieb:> Der Low-Power Mode wird nicht gewechselt.
und was soll dann die Zeilen:
BL schrieb:> LOW_POWER_MODE_1;BL schrieb:> __no_operation(); <-- Diese Zeile ist nur für die IAR Workbench> gedacht. War in den Beispiel Codes von Texas Instruments so angegeben.> Das ist aber kein Low-Power Mode für den µCs.
Du weisst nicht was NOP ist? LoL
BL schrieb:> Sleep() <-- Sleep ist kein delay, sondern ein tatsächliches "sleep".
Das war nicht gemeint. Ein NOP vor einem Delay, Sleep oder was auch
immer ist einfach Blödsinn.
BL schrieb:> Die if-Abfragen sind in einer while-Schleife, die mehrere Befehle> hintereinander ausführt. Entsteht zwischendrin ein Error, wird die> gesamte> while-Schleife unterbrochen.
Das hört sich nach einem halben goto an. ;-D
Meist lässt sich das durch else if lösen.
Du hast ein massives Programmspeicherproblem. In den gezeigten
Codefragmenten sind mehere unnütze und verwirrende Anweisungen. Wie
sieht der Rest wohl aus? Wahrscheinlich reicht ein 1k Flash. :-DDD
Alter...
@Optimizer:
Hier der Original Code von Texas Instruments msp430x20x3_usi_06.c:
1
...
2
while(1)
3
{
4
USICTL1|=USIIFG;// Set flag and start communication
5
LPM0;// CPU off, await USI interrupt
6
_NOP();// Used for IAR
7
for(i=0;i<5000;i++);// Dummy delay between communication cycles
8
}
9
...
Oh Wunder, da steht auch zuerst LPM0 und dann _NOP() ...
Was ist nun bitteschön falsch daran, diese beiden Zeilen in den eigenen
Code zu übertragen????
Und als Kommentar zum NOP steht: USED for IAR. Genau das hab ich oben
geschrieben.
BL schrieb:> Oh Wunder, da steht auch zuerst LPM0 und dann _NOP()
Ja ja, manche MSP's haben Probleme aus einem LPM wieder aufzuwachen wenn
hinter der LPM-Anweisung kein NOP steht. Das kann also schon seinen Sinn
haben, genaueres verrät das Datenblatt.
BL schrieb:> Oh Wunder, da steht auch zuerst LPM0 und dann _NOP() ...> Was ist nun bitteschön falsch daran, diese beiden Zeilen in den eigenen> Code zu übertragen????
Dort wird auch ein Low Power Mode eingenommen, bis der direkt davor
scharf gemachte USI Interrupt kommt. Wenn du es wie beim TI Beispiel
machen möchtest, gehört NOP hinter dein Sleep.
Sei doch froh, dass man es dir erklärt, anstatt mit Unwissenheit zu
pralen.