Forum: Mikrocontroller und Digitale Elektronik Codegröße verkleinern


von Markus S. (acepilot)


Angehängte Dateien:

Lesenswert?

Guten Morgen,

Ich versuche gerade für ein Projekt eine Tankanzeige zu entwickeln. Das 
ganze soll kapazitiv gemessen werden und mittels Nokia Display 
visualisiert werden. Meine ersten Versuche sind auch sehr viel 
versprechend. Nachdem ich die erste Version meiner Software geflasht 
habe viel mir auf das durch die Rechnung in Zeile 121:
1
fuelLevel = ((TANK_ACTUAL_FREQ - TANK_FULL_FREQ) / (TANK_EMPTY_FREQ - TANK_FULL_FREQ) - 1) * -100;
 immer nur Ganzzahlen ausgegeben werden und somit kein Valides Ergebniss 
zustande kommt. Ist auch eigentlich klar alle Variablen in der Gleichung 
bis auf  fuelLevel sind uint32_t.
Versuche ich nun die Rechnung in float zu casten steigt die verwendete 
Codegröße im Flash von 15340 Bytes auf 16016 Bytes an.

Da ich aber einige Kalibrierdaten im Flash unterbringen möchte müßte die 
letzte Page unbenutzt bleiben, da ich ja nur Pageweise löschen kann.

Habt Ihr eine Idee an welche Stelle ich noch optimieren kann damit ich 
mit einem Flashspeicher von 15360 Bytes auskomme, ohne das ich 
Funktionen streichen müsste.

Das ganze läuft auf einem STM32F030F4P6 und ist mit CooCox entwickelt. 
Eine größere CPU wäre eine Lösung möchte ich aber vermeiden den die 
Platinen sind schon geliefert.

Schonmal im voraus danke für sachdienliche Hinweise und Ideen.

Gruß,
Markus

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Du solltest durch Umstellung des Terms und anschließender Klammerung 
dafür sorgen, dass zuerst mit -100 multipliziert wird, bevor Du 
dividierst.

Sonst: Welche Compiler-Optionen nutzt Du.

von Markus S. (acepilot)


Lesenswert?

Mist genau die diese Info ist mir durchgegange zu nennen. Das ganze wird 
schon mit der Compiler Option -Os compiliert.

von Daniel A. (daniel-a)


Lesenswert?

https://www.mikrocontroller.net/articles/Festkommaarithmetik

Forme das doch etwas um, falls (TANK_ACTUAL_FREQ-TANK_EMPTY_FREQ)*10000 
< 2^32 sollte folgendes gehen, auf 2 Nachkommastellen genau:
1
fuelLevel = 100000 - (uint32_t)(TANK_ACTUAL_FREQ - TANK_FULL_FREQ) * 100000 / (TANK_EMPTY_FREQ - TANK_FULL_FREQ);

von Markus S. (acepilot)


Lesenswert?

Frank M. schrieb:
> Du solltest durch Umstellung des Terms und anschließender Klammerung
> dafür sorgen, dass zuerst mit -100 multipliziert wird, bevor Du
> dividierst.

Das war der richtige Hinweis, habe da sowieso ein wenig idiotisch 
gerechnet.
Mit der Formel
1
fuelLevel = ((TANK_ACTUAL_FREQ - TANK_FULL_FREQ) * 100) / (TANK_EMPTY_FREQ - TANK_FULL_FREQ);
funktioniert es.

Danke für den schnellen Denkanstoss.

von Gerd E. (robberknight)


Lesenswert?

Markus S. schrieb:
> Habt Ihr eine Idee an welche Stelle ich noch optimieren kann damit ich
> mit einem Flashspeicher von 15360 Bytes auskomme, ohne das ich
> Funktionen streichen müsste.

wieso willst Du das?

> Das ganze läuft auf einem STM32F030F4P6

Wenn Du nicht dem Marketing von ST glaubst, sondern Dir Fakten wie 
Die-IDs anschaust und ausprobierst, siehst Du daß der 32 KB Flash hat. 
Außerdem auch den Timer2.

STM32F030F4P6 und STM32F031F6P6 verwenden den selben Die.
Der einzige Unterschied ist der von ST in das Flash size register 
programmierte Wert. Das ist nur <=, aber eben nicht == dem real 
vorhandenen oder ansprechbaren Flash.

Du hast also noch massenweise Platz zur Verfügung.

von Markus S. (acepilot)


Lesenswert?

Gerd E. schrieb:
> STM32F030F4P6 und STM32F031F6P6 verwenden den selben Die.
> Der einzige Unterschied ist der von ST in das Flash size register
> programmierte Wert. Das ist nur <=, aber eben nicht == dem real
> vorhandenen oder ansprechbaren Flash.

Das hört sich erstmal sehr gut an, ich hatte das wohl schon mal 
irgendwoe gelesen aber doch wieder verdrängt. Dann muss ich mich mal auf 
die Suche machen das ich diesen auch Nutzen kann, ist gut zu wissen für 
zukünftige Projekte.

Danke für diesen super Hinweis!

Bei dem aktuellen konnte ich durch weiteres Umstellen von anderen 
Berechnungen den verwendeten Flash Speicher auf 11620 Byte drücken.

Gruß,
Markus

von Peter D. (peda)


Lesenswert?

Man könnte auch versuchen, die ganzen Grafik- und Textausgabemonster zu 
optimieren, z.B. das hier:
1
if (toggler == 1)
2
{
3
  toggler = 0;
4
  LCDPixel(10,yPos,PIXEL_OFF);
5
  LCDPixel(11,yPos,PIXEL_ON);
6
  LCDPixel(12,yPos,PIXEL_OFF);
7
  LCDPixel(13,yPos,PIXEL_ON);
8
  LCDPixel(14,yPos,PIXEL_OFF);
9
  LCDPixel(15,yPos,PIXEL_ON);
10
  LCDPixel(16,yPos,PIXEL_OFF);
11
  LCDPixel(17,yPos,PIXEL_ON);
12
  LCDPixel(18,yPos,PIXEL_OFF);
13
  LCDPixel(19,yPos,PIXEL_ON);
14
  LCDPixel(20,yPos,PIXEL_OFF);
15
  LCDPixel(21,yPos,PIXEL_ON);
16
}
17
else
18
{
19
  toggler = 1;
20
  LCDPixel(10,yPos,PIXEL_ON);
21
  LCDPixel(11,yPos,PIXEL_OFF);
22
  LCDPixel(12,yPos,PIXEL_ON);
23
  LCDPixel(13,yPos,PIXEL_OFF);
24
  LCDPixel(14,yPos,PIXEL_ON);
25
  LCDPixel(15,yPos,PIXEL_OFF);
26
  LCDPixel(16,yPos,PIXEL_ON);
27
  LCDPixel(17,yPos,PIXEL_OFF);
28
  LCDPixel(18,yPos,PIXEL_ON);
29
  LCDPixel(19,yPos,PIXEL_OFF);
30
  LCDPixel(20,yPos,PIXEL_ON);
31
  LCDPixel(21,yPos,PIXEL_OFF);
32
}
in
1
for( int i = 10; i<= 21; i++ ){
2
  toggler ^= 1;
3
  LCDPixel(i, yPos, toggler);
4
}
5
toggler ^= 1;

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Gerd E. schrieb:
> Wenn Du nicht dem Marketing von ST glaubst, sondern Dir Fakten wie
> Die-IDs anschaust und ausprobierst, siehst Du daß der 32 KB Flash hat.
> Außerdem auch den Timer2.
>
> STM32F030F4P6 und STM32F031F6P6 verwenden den selben Die.
> Der einzige Unterschied ist der von ST in das Flash size register
> programmierte Wert. Das ist nur <=, aber eben nicht == dem real
> vorhandenen oder ansprechbaren Flash.

Krass, wieder was gelernt, Danke. Gibt es Hinweise, dass hier ggf. Chips 
mit defektem Flash runtergelabelt werden?
Für den professionellen Einsatz würde ich mich auf sowas nicht 
verlassen, aber man könnte den STM32F031F zur Entwicklung bei -O0 nehmen 
und den STM32F030F in der Serie bei -Os.

von Soul E. (Gast)


Lesenswert?

Marcus H. schrieb:

> Krass, wieder was gelernt, Danke. Gibt es Hinweise, dass hier ggf. Chips
> mit defektem Flash runtergelabelt werden?

Bei Mikrocontrollern wird üblicherweise nicht selektiert, sondern nur 
getestet. D.h. beim 32k-Typ testet man 32k, wenn der besteht, gut. Beim 
64k-Typ testet man 64k, wenn er durchfällt, Schrott.

Binning lohnt sich nur bei teureren Mikroprozessoren. D.h. man testet 
welche Teile funktionieren und bis zu welchem Takt, und sortiert das 
Bauteil dann entsprechend ein. Ein Intel Xeon kostet aber auch in 
Stückzahlen noch über $50, ein ARM-Mikrocontroller keine 50 cent.

von Gerd E. (robberknight)


Lesenswert?

Marcus H. schrieb:
> Gibt es Hinweise, dass hier ggf. Chips
> mit defektem Flash runtergelabelt werden?

Nein, mir sind bisher nirgends Infos in die Richtung untergekommen.

Wie soul eye schon schrieb lohnt das nicht wirklich.

Gehen wir mal davon aus, daß Defekte im Flash gleichmäßig über den 
gesamten Flash verteilt sind. Dann könntest Du auch nur die 
runterlabeln, bei denen der Defekt im oberen Bereich des Speichers ist. 
Die, die den Defekt im Bereich haben der bei jeder vermarkteten 
Speichergröße vorhanden ist, kannst Du nicht weiter runterlabeln. Du 
müsstest eine komplexe remapping-Logik einbauen um das wieder zu 
ermöglichen. Das lohnt sich alles nicht. Die Ausbeute ist wohl in diesen 
Strukturgrößen ziemlich gut.

Hier noch ein interessanter Thread zum Thema STM32 Flashgröße:
Beitrag "Re: Basteltip: STM32F103 DIP40 Board"

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Danke Euch beiden für die Info.
Ich war davon ausgegangen, dass ggf. nur Chips mit Defekten im oberen 
Flash runtergelabelt werden.

Die F03x..F5x kosten in der Serie ca. 0,50€, aber solange ich nichts 
handfestes über Stückzahlen und Ausbeute weiß, bleiben da nur 
Vermutungen, ob der Hersteller außer Marketing eine weiter Motivation 
für zusätzliche Varianten hat.

Will sagen, bei den bekannten Herstellern (z.B. Microchip, 
Microchip-Atmel, ST) gibt es mittlerweile so viele feine Abstufungen, 
dass ich mich schon Frage, ob die versuchen ein Flaggschiff zu bauen und 
die Fehlversuche nach Fehlern sortiert in diverse Eimer verteilen.

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.