Forum: Mikrocontroller und Digitale Elektronik MSP430 C-Programmierung, Programmgröße reduzieren


von Sonntagsbraten (Gast)


Lesenswert?

Hallo Leute,
die Sonne scheint und der TI Compiler meckert, dass kein Platz mehr ist 
(MSP430G2231, 2kB).
Dabei ist noch lange nicht alles programmiert und die ganzen 
Hardwarefeatures sind auch noch nicht genutzt :-(

Ich bemühe mich gerade, alle Funktionen/Prozeduren, die nur aus 
organisatorischen Gründen bestehen, als inline zu deklarieren, um 
Funktionsaufrufe einzusparen (z.B. Initialisierungs-Prozeduren).
Macht das bei void ... (void) Funktionen überhaupt Sinn?

Variablen nur den nötigen Scope zu geben.
Konstanten nur, wo erforderlich. Es sammelt sich ganz schön was an.

Wie ist es auf einem 16-bit'er mit der Variablengröße? Nutzt oder 
schadet es mehr, wenn man weniger als xint16_t benutzt?

Ist es günstiger, viele 8 Variablen als Flag zu nutzen und = 1 bzw. 0 zu 
setzen, oder 1 Variable zu nutzen und die Bits einzeln zu bearbeiten?

Ich würde mich freuen wenn ihr ein paar Tricks auf Lager habt.

von Bernhard S. (berns)


Lesenswert?

Hallo!

Also, inline deklarierte Funktionen benötigen unter Umständen mehr Platz 
im uC als sonst. "inline" ist eine Geschwindigkeitsoptimierung, die zu 
ungunsten des Platzes gemacht wird. d.h. an jede Stelle, wo die inline 
Funktion aufgerufen wird, wird der komplette Funktionsrumpf kopiert.

RAM lässt sich sparen indem man "jedes Bit" nutzt. Also beispielsweise 
eine 16-Bit variable für 16 Flags verwendet, anstatt 16 bytes die alle 
nur 1bit Information speichern.

Sinnvoll kann sein, anstatt eine Table (f. Table lookups) zu verwenden 
die Daten zu berechnen, wenn die Berechnung weniger Platz benötigt als 
die Tabelle. Wird das Programm zwar langsamer, aber es "passt" mehr in 
den uC - alternativ dazu lässt sich auch ein größerer uC einlöten...

Viel Spaß beim "Bitklauben"!

Grüße,

Bernhard

von Frank K. (fchk)


Lesenswert?

Bei einfachen Variablen ist ein short günstiger als ein char, weil bei 
letzerem irgendwo immer noch ein and r,255 generiert wird, entweder bei 
der Erzeugung des Rückgabewertes oder beim Aufrufer. Lass Dir mal 
Assembler-Quellcode generieren, dann siehst Du den Unterschied.

Außerdem: Bibliotheksfunktionen im MAP-File prüfen. Auch so etwas, was 
man nicht gleich sieht: Division, Modulo, Multiplikation (wenn der 
Prozessor keinen Multiplizierer hat),... Im MAP-File siehst Du die 
Speicherfresser.

fchk

von Bernd N. (Gast)


Lesenswert?

Ohne den Code zu kennen ist es schwer hier zu helfen. Inlinen hilft nur 
begrenzt aber das kannst du ja einfach ausprobieren.

#pragma inline

und dann die Funktion hinterher schreiben.

von Sonntagsbraten (Gast)


Lesenswert?

Danke für die Tipps!

von deg_gast (Gast)


Lesenswert?

Frank K. schrieb:
> Bei einfachen Variablen ist ein short günstiger als ein char, weil bei
> letzerem irgendwo immer noch ein and r,255 generiert wird, entweder bei
> der Erzeugung des Rückgabewertes oder beim Aufrufer

Kannst Du das evtl. mal näher erläutern?

von Dennis (Gast)


Lesenswert?

Viel mit Adressen arbeiten, nicht Variablen beim Funktionsaufruf durch 
Kopieren übergeben.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Und die obligatorische Frage:
Nutzt Du floating-Point-Arithmetik? Nutzt Du printf/scanf oder Derivate 
davon?

von Peter (Gast)


Lesenswert?

hi,

jetzt hatts mich auch erwischt :( der 2k controller ist scheinbar zu 
klein für mein programm.

ich habe an 2 stellen floatingpoint operationen die die codesize extrem 
aufblähen :(

kann ich die irgendwie umgehen?
1
return (int)((100.0/16384) *raw); //Berechnung des der Luftfeuchte [%] und Rückgabe
1
return (char)(((ADC10MEM - 673) * 423) / 1024); //Temperatur in °C ausrechnen und zurückgeben


allein diese beiden operationen benötigen gut 500b an instructionen?!

Ich programmiere auf dem Launchpadcontroller MSP430G2231 :(

VG

von Peter (Gast)


Lesenswert?

gibts es soetwas wie short double?! ich brauche keine 32bit fp zahl -.-

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ich sehe nur ein Beispiel mit floating-Point-Arithmetik:
1
return (int)((100.0/16384) *raw);

Welchen Typ und Wertebereich hat "raw"?

Genähert könnte eine int-Division durch 164 reichen.
1
return (char)(((ADC10MEM - 673) * 423) / 1024);

Hier wird keine Floatingpoint-Arithmetik verwendet.

von Peter (Gast)


Lesenswert?

raw ist vom typ int nutzt aber effektiv "nur" 14bit

hast du nen tipp ? :)

von Peter (Gast)


Lesenswert?

"Genähert könnte eine int-Division durch 164 reichen."
was bedeutet das?

von Stefan (Gast)


Lesenswert?

100/16384 ist ungefähr 1/164.
Statt mit 100.0/16384 zu multiplizieren könntest du durch 164 
dividieren.

von Bernd N (Gast)


Lesenswert?

Temperatur und Luftfeuchte ? und floating point ? Dein Konzept ist 
falsch, fixed point ist bei so einem kleinen Controller angesagt und 
sicherlich auch machbar.

von Peter (Gast)


Lesenswert?

was heist hier mein konzept ist falsch?

ich muss schnellst mölglich zu einem Ziel kommen und bin leider kein 
profi. deshalb werde ich wohl einige subotimalitäten in kauf nehmen 
müssen...
hast du mir nen literatur-tipp für berechnungen mit fixed point ?

leider stehen jetzt klausuren an so dass es vorerst keine beachtung mehr 
finden wird.Das projekt muss bis anfang januar abgeschlossen sein...

von Roland H. (batchman)


Lesenswert?

Peter schrieb:
> was heist hier mein konzept ist falsch?
>
> ich muss schnellst mölglich zu einem Ziel kommen und bin leider kein
> profi. deshalb werde ich wohl einige subotimalitäten in kauf nehmen
> müssen...

M. A. nach sind die 2k msp430 Controller nur für Profis geeignet. Die 
sind meiner Erfahrung nach noch schwieriger zu programmieren als z. B. 
der attiny2313 mit vergleichbaren Kenndaten. Ich stoße auf den msp430 - 
mit der gleichen Applikation - noch früher an die RAM-Grenze.

Generell - und als Einsteiger m. A. sowieso - würde ich mit einem 
"großen" µC beginnen, also mindestens 16k Flash und 1k RAM. Downgrade 
geht immer, Bitklauben macht gar keinen Spass.

Die Frage ist also: Ist der MSP430G2231 vorgegeben? Wäre evtl. der 
msp430g2553 eine Alternative? Geht's auch ganz anders? In der gleichen 
preislichen Region gibt es genug Alternativen, wo Du definitiv bis 
Januar nicht an irgendwelche Grenzen der HW stößt.

> hast du mir nen literatur-tipp für berechnungen mit fixed point ?

http://drdobbs.com/cpp/207000448

Würde mich allerdings wundern, wenn Du das alles unter Berücksichtigung 
Deiner restlichen Informationen in 2k realisieren kannst. Vor allem bis 
Jan. Bleib bei "integer".

> leider stehen jetzt klausuren an so dass es vorerst keine beachtung mehr
> finden wird.Das projekt muss bis anfang januar abgeschlossen sein...

Das ist dann der dritte Fehler im Konzept, da der Weihnachtsmann das 
auch nicht mehr hinbekommt :-)

von Bernd N (Gast)


Angehängte Dateien:

Lesenswert?

400 : 3.14 = 127.38

Anstatt mit Flotaing Point zu rechnen könntest du auch...

40000 : 314 rechnen oder ?

Wir sind es gewohnt Zahlen im dezimal System zu erweitern aber das kann 
man auch zur Basis 2 und dann sind es nur noch Schiebeoperationen.

Im Anhang mal ein Beispielcode für den Controller deiner Wahl in der 
sämtliche Korrekturrechnungen per fixed point gemacht werden, vielleicht 
hilft das.

Ansonsten:
http://www.hackersdelight.org/divcMore.pdf

Oder zeig deinen Code her statt herumzumeckern wie wenig zeit du noch 
hast. Ich denke das ist mit wenigen Korrekturen schnell zu machen.

von Bernd N (Gast)


Angehängte Dateien:

Lesenswert?

Dann verwenden wir mal den internen Temperatursensor und beachten dabei 
was wir gelernt haben.

Im Anhang der Code inklusive Ausgabe auf dem USB Appl. COM Port. Gerade 
mal 672 Byte Code.

Wenn es bei dir nur um 2 Sensoren geht dann sollte dein gesamter 
Codeverbrauch nicht über 1.4k gehen also noch reichlich Platz für den 
Rest deiner Anwendung.

Bei dem Codebeispiel solltest du die beiden Stützpunkte kalibrieren 
(Eiswasser + Körpertemperatur) so habe ich es gemacht. Kannst auch 
Wasserdampf verwenden und deinen MSP kochen :-)

von Karl (Gast)


Lesenswert?

Das beantwortet dann auch fast meine Frage in 
Beitrag "Re: Erfahrungen UART TI Launchpad" an Bernd :-)

Nur: wie hast du es praktisch gemacht - das Launchpad in destilliertes 
Eiswasser? Styroporbox mit Eiswürfeln und Referenzthermometer?

von Bernd N (Gast)


Lesenswert?

Eiswürfel in Plastikbeutel :-) ist doch ganz einfach. Und dann ein 2tes 
Thermometer und ein bischen experimentieren. So genau muß es ja nicht 
sein oder ?

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.