Hi zusammen,
ich hab ein kleines C-Programm geschrieben dass mir zwei DS1621 Temp.
Sensoren und einen ADS1112 AD Wandler abfrägt und auf einem LCD Display
mit 4x20 Zeichen ausgibt.
So, nun habe ich leider das Problem dass ich das Programm nicht in den
Controller bringe. Es ist um ein paar % zu groß und würde auch gerne
noch ein wenig mehr Text auf das Display werfen.
Die Berechnung der Werte vom ADS1112 habe ich ebenfalls schon sehr
gekürzt und es hingenommen dass die Messwerte so nicht ganz korrekt
sind.
Kann man noch was optimieren? Controllertausch ist leider nicht drin :(
(außer es kennt jemand einen pincompatiblen mit mehr Speicher).
Programm findet ihr im Anhang.
In "Thermometer.c" ist die Main.
Bin über jede Hilfe dankbar.
Probiere halt mal ein paar Compilerflags:
-g2 -Os -nostartfiles -ffunction-sections -fdata-sections -fpack-struct
-fno-inline-small-functions -fno-move-loop-invariants
-fno-tree-scev-cprop
Aber sonst:
- Was kostet eine MCU mit mehr als 2kb flash?
- Wie viel verdienst Du pro Stunde?
bork schrieb:> Probiere halt mal ein paar Compilerflags:>> -g2 -Os -nostartfiles -ffunction-sections -fdata-sections -fpack-struct> -fno-inline-small-functions -fno-move-loop-invariants> -fno-tree-scev-cprop>
... hilft etwas, aber nicht viel. 100,9% full sagt er nun.
> Aber sonst:>> - Was kostet eine MCU mit mehr als 2kb flash?> - Wie viel verdienst Du pro Stunde?
Ja, doof... ist ne alte Platine die ich sonst neu machen müsste :(
Oh mann, hätte ich auch selbst draufkommen können. Hab mir noch das alte
Datenblatt angeschaut wo nur der 2313 aufgeführt wird.
Den µC bestell ich gleich :)
Trotzdem bin ich natürlich gespannt wie man den Code noch optimieren
kann.
Borsty B. schrieb:> Kann man noch was optimieren?
Dürfte ich vorschlagen, du siehst selbst mal dein Programm durch?
Da fallen mir beim erstmaligen überfliegen des Codes schon eine Menge
Dinge auf.
Die Sache mit double lassen wir mal aussen vor.
Aber: auch mit den restlichen Datentypen ist es nicht so prickelnd
bestellt. Als Faustregel kannst du dir merken, dass du auf einem AVR
eher selten einfach nur int nehmen willst, sondern du willst spezifisch
sein. Insbesondere willst du 8-Bit Integer benutzen wo es auch immer
geht.
zb hier
messageBuf[1] bzw messageBuf[2] sind unsigned char (schreib das lieber
als uint8_t. Ist zwar dasselbe, schreibt sich aber kürzer).
Frage: Wozu sind dann hv und lv in der Funktion plain vanilla int. Das
alles verursacht Mehrarbeit für den Prozessor, der sich auch in Code
niederschlägt. Selbiges füe den Parameter 'zeile'. Der hat keinen
Wertebereich von -32768 bis +32767. zeile kann sich im Bereich 0 bis 4
bewegen. Ein 8-Bit uint8_t ist da mehr als angebracht. Deshalb sind zb
in den lcd Funktionen
1
voidlcd_setcursor(uint8_tx,uint8_ty)
da auch überall uint8_t.
Dein int verursacht da hier wieder Konvertieraktionen.
Dann seh ich da 'dead code'
ich weiss zwar nicht was das 0xAA macht, das du zum DS1621 schickst,
aber offenbar machst du mit dem Ergebnis nichts. Denn 2 Zeilen weiter
drunter wird temp mit einem neuen Ergebnis überschrieben.
Auch könnte man sich überlegen, ob man diese ganzen Teile
Per TWI etwas abfragen, umrechnen anzeigen, der mehrmals mehr oder
weniger identisch vorkommt, nicht in eine eigene Funktion steckt und so
die Code Duplizierung eindämmen.
Danke Karl Heinz, mit deinen Änderungen passt der Code jetzt tatsächlich
rein.
Knapp, aber es passt.
Dein zweiter Vorschlag erzeugt übrigens mehr Code.
Im AtmelStudio beim Compiler und beim Linker jeweils die Option "-flto"
eintragen. Das schadet nicht, optimiert aber so wie wenn es nur ein
einziges C-File gäbe. Damit kann der Compiler alles beliebig
umorganisieren.
Borsty B. schrieb:> Dein zweiter Vorschlag erzeugt übrigens mehr Code.
Ah, ok.
Dann hat der Compiler offenbar schon selbst erkannt, wie er die gleichen
Teile aus den einzelnen Teilzweigen rausziehen kann.
Für so einen kurzen Code
double adc_rechnen(int hb, int lb) {
long t = hb << 8 | lb;
if (t >= 32768) t = 65536 *lb - t;
double volt = (double) t * 2048/32768;
volt = volt*18.55;
return volt;
}
gleich die Fließkomma-Lib in so nen kleinen Prozessor bauen lassen
sprengt den Speicher.
Mit reiner Ganzzahl-Arithmetik kommste nicht ans Ziel ?
So Long hat schon einige Stellen zur Verfügung
Karl H. schrieb:> Die Sache mit double lassen wir mal aussen vor.
die könnte aber das entscheidende sein.
1
doubleadc_rechnen(inthb,intlb){
2
3
longt=hb<<8|lb;
4
if(t>=32768)t=65536*lb-t;
5
doublevolt=(double)t*2048/32768;
6
volt=volt*18.55;
7
returnvolt;
8
}
später wird das ganze auch nur eine int variable zugewiesen. Da sollte
sich doch ein weg finden lassen ohne double zu rechnen.
Hier dürfte sogar ein fehler drin sein
1
doublevolt=(double)t*2048/32768;
der cast erfolgt zu spät, erst nach der Berechnung.
1
int16_tadc_rechnen(uint8_thb,uint8_tlb){
2
uint16_tt=hb<<8|lb;
3
4
// versteh ich grade nicht
5
//if (t >= 32768)
6
// t = 65536 *lb - t;
7
8
// es wird doch einfach volt = (t *2048/32768)*18.55;
9
// gerechnen also -> Volt = t*1.159375
10
int16_tvolt=t;
11
volt=volt+t/8;
12
volt=Volt+t/32;
13
returnvolt;
14
}
so in der Art - falls fehler drin liegt es an der Urzeit.
long?
wieso long?
hb und lb sind 2 Bytes die du vom Sensor schon als 2-er Komplement Zahl
(wegen negativ) kriegst?
Dann ist erstens der richtige Datentyp für Bytes ein uint8_t und um
daraus eine 16 Bit Zahl inklusive Vorzeichen richtig zusammenzusetzen,
macht man das so
1
doubleadc_rechnen(uint8_thb,uint8_tlb)
2
{
3
int16_tt=(int16_t)(hb<<8|lb);
4
5
doublevolt=.....
6
....
7
}
kein Grund, da den Prozessor auch noch in long reinzujagen. double ist
schon schlimm genug.
Dem widmen wir uns als nächstes.
Peter II schrieb:> Karl H. schrieb:>> Die Sache mit double lassen wir mal aussen vor.>> die könnte aber das entscheidende sein.
Ich wollte mir erst mal die simplen formalen Dinge vorknüpfen. SOzusagen
die Dinge, bei denen man nicht denken braucht sondern einfach nur sein C
können muss :-)
> Hier dürfte sogar ein fehler drin sein>>
1
>doublevolt=(double)t*2048/32768;
2
>
> der cast erfolgt zu spät, erst nach der Berechnung.
Das passt schon. Ein cast bindet so ziemlich am stärksten. t wird auf
double gecastet und dann wird durch 16 dividiert.
intvorKomma=Messwert/1000;// zwei Nachkommastellen "abschneiden"
5
intnachKomma=Messwert%1000;// zwei Nachkommastellen "isolieren"
6
lcd_setcursor(0,zeile);
7
8
utoa(vorKomma,ausgabe,10);
9
lcd_string(ausgabe);
10
lcd_string(",");
11
utoa(nachKomma,ausgabe,10);
12
lcd_string(ausgabe);
13
lcd_string(" ");
14
}
noch schwere Fehler enthalten.
zum Vorkommateil:
die korrekte Funktion wäre itoa und nicht utoa.
int -> itoa
unsigned int -> utoa
zum anderen kannst du im Nachkomma Anteil nicht einfach führende 0-en
unterschlagen. Eine Zahl in Messwert 3004 muss als 3,004 ausgegeben
werden und nicht als 3,4
entweder du ergänzt selber die durch utoa fehlenden führenden 0-en oder
du änderst die Strategie. Das ist insofern auch sinnvoll, weil bei
negativen Zahlen ein Messwert % 1000 nicht das von die erwartete
Ergebnis bringen wird.
Du hast keine negativen Zahlen?
Warum hast du dann überall einen int?
Waaahnsinn, Leute... man könnte mein Projekt wohl zu schulungszwecke
verwenden.
Ich muss ja zugeben dass ich so gut wie nie programmiere und daher nicht
so fit bin. Muss mich wohl doch mehr einarbeiten.
Wir sind jetzt übrigens trotz einiges mehr an Text auf dem Display bei
73%.
Karl H. schrieb:> int -> itoa> unsigned int -> utoa
Ist bereits geändert.
Karl H. schrieb:> zum anderen kannst du im Nachkomma Anteil nicht einfach führende 0-en> unterschlagen. Eine Zahl in Messwert 3004 muss als 3,004 ausgegeben> werden und nicht als 3,4
Und ja, das Thema beschäftigt mich grad noch...
Borsty B. schrieb:> Waaahnsinn, Leute... man könnte mein Projekt wohl zu schulungszwecke> verwenden.
Na ja, das ist hier nicht das erste Projekt, das Karl Heinz so ausgiebig
zerpflückt. :-)
bork schrieb:> - Wie viel verdienst Du pro Stunde?
Das nennt man dann Lehrgeld.
bork schrieb:> Probiere halt mal ein paar Compilerflags:>> -g2 -Os -nostartfiles -ffunction-sections -fdata-sections -fpack-struct> -fno-inline-small-functions -fno-move-loop-invariants> -fno-tree-scev-cprop
Das -g2 würde ich entfernen, debugsymbole brauchen platz. Zu
-ffunction-sections -fdata-sections gehört noch -Wl,-gc-sections, bzw.
--gc-sections ausserdem kan -s helfen.
Bastler schrieb:> Im AtmelStudio beim Compiler und beim Linker jeweils die Option "-flto"> eintragen. Das schadet nicht, optimiert aber so wie wenn es nur ein> einziges C-File gäbe. Damit kann der Compiler alles beliebig> umorganisieren.
Ja, das halte ich auch für eine sinnvolle Option. Bei meinen Projekten
mit vielen kleinen C-Dateien macht das eine ganze Menge aus. Aber
wichtig ist dann in diesem Zusammenhang, dass man -Os auch bei den
Linkeroptionen angeben muss. Sonst wird das Compilat sogar größer.
(Grund: Der Linker ruft den C-Compiler in einem 2nd-Pass auf. Wenn man
hier kein -Os angibt, wird im zweiten Durchgang ohne Optimierung
übersetzt)
Bastler schrieb:> Ok, gut zu wissen. Das -Os im Linker probier ich bei nächster> Gelegenheit mal aus.
Wie gesagt: -Os als Linker-Option ist nur in Verbindung mit -flto (als
Compiler- und Linker-Option) sinnvoll.
Schon verstanden. Ich hätte erwartet, das der Zwischencode aus den
Compilerläufen diese Info an den linker weiter gibt (oder war nicht -Os
default?), aber es ist tatsächlich "von Hand" zu machen. Spart bei einen
kleinen Beispielprojekt rund 2% Flash ein. Also das -Os beim Linker, LTO
benutzte ich schon vorher.
Nochmal für Begriffsstutzige kurz zusammengefasst: hier soll ein
C-Programm soweit optimiert werden, dass es in einen Ziel-uC passt. Das
ist ein ganz alltägliches zu lösendes Problem.
Die Verwendung einer anderen Sprache wie Cobol, Fortran, Basic, ASM,
Suaheli, Klingonisch,... sowie deren Vor- und Nachteile steht hier
ausdrücklich nicht zur Diskussion. Sie wurde im Übrigen schon
ausführlich und immer wieder durchgekaut. Für Vergessliche hilft die
Forumssuche weiter...
Fürderhin werden wie oben einfach alle Posts gelöscht, die nichts zum
Thema beitragen. Persönliche Angriffe und die Verwendung mehrerer
Namen in einem Thread sind sowieso nicht erlaubt:
https://www.mikrocontroller.net/user/conditions
Leute, Leute, seit ihr denn verrückt?
Der Thread hat so schön strukturiert angefangen und mir wurde
vorbildlich geholfen. Sogar so geholfen dass ich ans Ziel gekommen bin.
Mittlerweile werkelt übrigens ein 4313 in der Schaltung und ich bin mit
allem fertig. Dank den ersten Threads hier.
Es so eskalieren zu lassen finde ich schade.
Danke an diejenigen die mir konstruktiv geholfen haben.
Borsty B. schrieb:> Sogar so geholfen dass ich ans Ziel gekommen bin.> Mittlerweile werkelt übrigens ein 4313 in der Schaltung
Gib zu, genau das war die Lösung ;-)
> Jede Sekunde die man Arbeitet um beim 2313er zu bleiben ist
verschwendete Zeit.
Er hat aber die Wartezeit auf den Großen verwendet, um was dazuzulernen.
Von der Nutzung der richtigen Compileroptionen bis hin zur Umgehung von
Floatingpoint, wenn man das nicht wirklich braucht.
Und jeder, aber absolut jeder Chip, den ich nicht in der "Bastelkiste"
hab, ist teuerer, egal wie billig ich ihn bestellen kann. Und dann die
Lieferzeit bewertet mit meinen "Stundensatz" ;-)
Moby schrieb:> Asm - das rote Tuch für Löschmod Wunsch.> Wie lächerlich ist das denn?
Schon mal in Erwägung gezogen, dass ASM die Antwort auf eines Frage ist
die niemand hier gestellt hat und auch nicht stellen wollte?
Moby schrieb:> Asm - das rote Tuch für Löschmod Wunsch.
Du könntest falscher nicht liegen...
Welchen Teil meines Posts hast du nicht kapiert? Oder unter welcher
seltenen Form der Begriffstutzigkeit leidest du?
Nochmal in Kurzform: es geht nicht um Assembler.
Und die etwas längere Ausführung: es geht nicht um Assembler, weil
dieses Problem problemlos auch in C gelöst werden kann.
> Wie lächerlich ist das denn?
Das frage ich mich allerdings auch. Aber wenn einer nur einen Hammer
hat, dann sieht für ihn die ganze Welt wie ein Nagel aus...
Frank M. schrieb:> -flto
Das benutze ich standardmässig für ARM und geht immer problemlos.
Neulich aber hab ich mal ein altes AVR-Projekt rausgekramt und bin auf
die Idee gekommen dort ebenfalls mal -flto zu probieren und der Compiler
(offizielle gcc Toochain von Atmel) hat mich mit überaus bizarren
Fehlermeldungen zugeworfen. Welche genau das waren kann ich bei erneutem
Versuch irgendwann die Tage nochmal ausprobieren wenn mir jemand
bestätigen kann daß es in der Tat überhaupt möglich sein sollte, denn
ich habe nach einer halben Stunde aufgegeben unter der Vermutung daß das
einfach (noch) nicht unterstützt wird und habs mir dann aus dem Kopf
geschlagen.
Bernd K. schrieb:> Frank M. schrieb:>> -flto>> Das benutze ich standardmässig für ARM und geht immer problemlos.>> Neulich aber hab ich mal ein altes AVR-Projekt rausgekramt und bin auf> die Idee gekommen dort ebenfalls mal -flto zu probieren und der Compiler> (offizielle gcc Toochain von Atmel) hat mich mit überaus bizarren> Fehlermeldungen zugeworfen. Welche genau das waren kann ich bei erneutem> Versuch irgendwann die Tage nochmal ausprobieren wenn mir jemand> bestätigen kann daß es in der Tat überhaupt möglich sein sollte, denn> ich habe nach einer halben Stunde aufgegeben unter der Vermutung daß das> einfach (noch) nicht unterstützt wird und habs mir dann aus dem Kopf> geschlagen.
Irgendwelche Libs eingebunden die ohne -flto kompiliert wurden? Hab dann
bei ARM Projekten merkwürdige Fehler.
Moby schrieb:> Asm - das rote Tuch für Löschmod Wunsch.> Wie lächerlich ist das denn?
Ich habe mal einen kleinen Versuch gestertet:
> Beitrag #4219665 wurde von einem Moderator gelöscht.
Das war ein Rezept für einen Kuchen, vollkommen korrekt und köstlich.
Ich denke auch nicht, dass der Mod etwas gegen Kuchen hat (korrigier
mich bitte wenn ich falsch liege).
Trotzdem wurde es gelöscht, wieso wohl?
Weil es absolut rein gar nichts mit "C-Code optimieren" tun hat.
Wenn der TO nach einem Kuchenrezept gefragt hätte, würde der Post sicher
noch da stehen.
Ein kleiner Veruch schrieb:> Ich denke auch nicht, dass der Mod etwas gegen Kuchen hat (korrigier> mich bitte wenn ich falsch liege).
Danke, hatte schon, bin satt.
> Wenn der TO nach einem Kuchenrezept gefragt hätte, würde der Post sicher> noch da stehen.
Allerdings wäre der gesamte Thread nach Offtopic verschoben worden. Wenn
nicht gar komplett gelöscht, weil das Thema "Kuchen backen" nicht mal
entfernt in ein technisches Forum passt...
Was ist so schnell, was ist so klein?
Das kann doch nur Assembler sein!
Nur im C-Thread da sei auf der Hut,
Die bessere Lösung nennen ist dort nicht immer gut!
Das passt nicht ins schöne Hochsprachen-Bild.
Die C-Mods wetzen sofort die Messer.
Gegen den Fakt fuchtelnd wie wild:
Der Feind des C-Guten heißt ASM-Besser!
Dabei ist der C-Freak hier ständig im Hilfe-Mode.
Sein Werkzeug ist eben kein simpler Hammer!
Komplexer Ausdruck, viel zu viel Code-
wohin man auch schaut- groß das Gejammer.
C scheint ja erstmal bequemer-
und Sprache großer Programmierer-Väter.
Bei einfachen Progs ist alles kein Thema-
Aufwand und Grenzen zeigen sich später.
Der große Unterschied verletzt schnell manche Ehre.
Bei dem der nur Hochsprache kennt.
Kann ja nicht sein daß ASM klein und schneller wäre,
daß es die Hardware viel effizienter lenkt.
ASM- das böse schlimme Wort.
Da sieht der LöschMod gern schnell rot-
Bloß weg damit, schnell hinfort,
sonst kippt die C-Welt noch aus ihrem Lot!
Was ist so schnell, was ist so klein?
Das kann doch nur des C-Mods Löschfinger sein!
Schnell beim Löschen, klein beim Verstand,
wieder mal gerettet ist's,
schönes Mod-Abendland.
***
MOD kommt von MODERIEREN und NICHT von DELETE.
Drum sing ich sicher weiter,
dies MOD-unrühmliche Klagelied ;-(
Moby, der TO hat sein Programm veröffentlicht. Präsentiere eine ASM
Lösung mit gleicher Funktionalität und lasse uns alle in Ehrfurcht
erstarren. Jede allgemeine Preisung von ASM ohne Beispiel der
Überlegenheit, wird niemanden überzeugen.
Gut, die Spiele sind eröffnet. Die Spielregeln wurden von Moby selbst
festgelegt: sein ASM Code ist bei gleichem Funktionsumfang kompakter als
aus C compilierter Assembler. Und zwar um so viel kompakter, dass sich
der Mehraufwand tatsächlich lohnt. Und bis er die Lösung für dieses
Platzproblem liefert ist Ruhe.
Und Moby, lass das kleinkindliche Getue mit dem "Löschmod", das nervt.
Lothar M. schrieb:> Gut, die Spiele sind eröffnet.
Ein LöschMod verfügt nicht über meine Zeit und eröffnet für mich hier
gar nichts mehr. Zumal ich zu einem anderen Thread schon mal ganz
ungefragt eine Asm-Lösung lieferte und Mod-seitig hoch und heilig
versprochen wurde das mal eben schnell und gleichgroß in C zu coden...
Wurde natürlich nix draus. Kann aber gern nachgeholt werden. In
Vorleistung bin ich gegangen :-)
> Und Moby, lass das kleinkindliche Getue mit dem "Löschmod", das nervt.
Gut so. Dann triffts ja ins Schwarze!
Weitere Name:Moby initiierten Löschorgien werden meine Kreativität nur
weiter anheizen ;-)
Scelumbro schrieb:> Jede allgemeine Preisung von ASM ohne Beispiel der> Überlegenheit, wird niemanden überzeugen.
Ich preise nicht allgemein, sondern begründe ausführlich.
Leider wurde das meiste meiner diesbezüglichen Mühen hier mit einem
Federstrich gelöscht. Das tut mir auch leid für jene, die den Verteil
von Asm zur Optimierung von Code gern weiter diskutiert hätten. Die auch
ein paar weiterführende (gleichfalls gelöschte) Gedanken äußerten, zu
denen ich gern Stellung bezogen hätte. Irgendwo ists aber auch egal,
denn Problem- Gelegenheiten bieten sich ja weiter am laufenden Band:
Komplexität und Ressourcenverbrauch von Hochsprachen bleiben ein
aktuelles Thema!
Moby schrieb:>> Moby, lass das kleinkindliche Getue mit dem "Löschmod", das nervt.> Gut so. Dann triffts ja ins Schwarze!
Gut, dass du auch mal was getroffen hast.
> Leider wurde das meiste meiner diesbezüglichen Mühen hier mit einem> Federstrich gelöscht.
Dein einziger Post, der nicht nur "Löschmod! Löschmod!" enthält, ist der
vom 30.07.2015 22:13 und darin ist nur allgemeines Gesülze vom Niveau
"weil ich in Assembler alles selber mache und keine Libs benutze, ist es
automatisch besser als ein C-Compilat". Mehr oder gar etwas fundiertes
habe ich nicht gefunden.
Moby schrieb:> Weitere Name:Moby initiierten Löschorgien werden meine Kreativität nur> weiter anheizen ;-)
Wenn du ein grundlegendes Problem mit der Moderation hier hast, dann
wende dich an Andreas oder mach dich vom Acker.
Ich mache den Thread hier jetzt dicht, weil nämlich für die
Ausgangsfrage eine Lösung gefunden wurde und seither nur noch Schlamm
geworfen wird. Wenn jemand meint, er hätte was zur eigentlichen Frage
beizutragen, der kann mir eine PN schicken.