Hallo,
in meinem C Programm habe ich zahlreiche Flags, welche nur auf 1 oder 0
gestellt werden.
Für jedes Flag nutze ich bisher eine 8 Bit Variable.
Nun wird der Programmspeicher meines ATmega88 langsam knapp und ich
würde gern für jedes Flag nur 1-Bit verbraten.
Wie funktioniert das?
mfg
Ingo Wendler schrieb:> txet schrieb:>>> Nun wird der Programmspeicher meines ATmega88 langsam knapp ...>> Der Programmspeicher wird damit aber nicht entlastet, eher der RAM.
Eine grundlegende Fähigkeit des menschlichen Gehirns ist es, über banale
Fehler einfach hinwegzuelsen.
Eine Fähigkeit mancher Zeitgenossen ist, vortrefflich Korinthen kacken
zu können.
Johann L. schrieb:> Als erstes untersuchen wo Sparpotential ist, anstatt blindlinks den> Code zu ändern :-)
Genau. Guck mal ob jedes int wirklich ein int sein muss. Oder ob das
eine oder andere Array auch im Flash untergebracht werden kann.
mfg.
Thomas Eckmann schrieb:> Eine grundlegende Fähigkeit des menschlichen Gehirns ist es, über banale> Fehler einfach hinwegzuelsen.
so banal finde ich diese Zwischenbemerkung nun auch nicht, sondern schon
entscheidend, ob die weitere Diskussion Sinn macht bzw. in eine andere
Richtung gelenkt werden sollte!
die drei ??? schrieb:> Thomas Eckmann schrieb:>> Eine grundlegende Fähigkeit des menschlichen Gehirns ist es, über banale>> Fehler einfach hinwegzuelsen.>> so banal finde ich diese Zwischenbemerkung nun auch nicht, sondern schon> entscheidend, ob die weitere Diskussion Sinn macht bzw. in eine andere> Richtung gelenkt werden sollte!
Wer sagt denn, daß die Zwischenbemerkung banal ist? Der Fehler ist
banal.
Denn jeder weiss, was gemeint ist. Nur einer muss mal wieder mit seinem
Blabla dazwischenbrabbeln. Ohne auch nur den geringsten konstruktiven
Hinweis zu geben.
Aber vielleicht war das ja gar kein Fehler. Sondern es ist der
Programmspeicher, der auf Grund diverser Initialisierungen langsam
überläuft.
Man könnte sich aber auch mit einem Atmega328 in beiden Fällen aus der
Affäre ziehen.
mfg.
die drei ??? schrieb:> so banal finde ich diese Zwischenbemerkung nun auch nicht, sondern schon> entscheidend, ob die weitere Diskussion Sinn macht bzw. in eine andere> Richtung gelenkt werden sollte!
Hatte ich auch so gemeint, wenn nämlich, wie der TE schrieb, der
Programmspeicher (Flash) knapp wird, wärend RAM noch ausreichend
verfügbar ist, wäre das rauspicken einzelner Bits nämlich eher
kontraproduktiv, weil mehr Befehle erforderlich. Andersrum (genug Flash,
RAM knapp) ist die Diskussion schon sinnvoll, hatte ich aber so nicht
gelesen, vielleicht mein Fehler, dann sorry für den Beitrag.
Naja, meine C-Erlebnisse sind schon länger her (C interessiert mich auch
nicht sonderlich, wenn ich ehrlich bin), aber soweit ich das damals
mitbekommen habe, ist ein char normalerweise ein Oktett groß, ergo wäre
dieses "struct of 8 chars" dann 8 Bytes groß. Inwieweit dann C noch
irgendwas zusätzliches für den Zugriff auf das struct speichern muß weiß
ich nicht und hängt wohl auch vom Compiler ab, aber kleiner als 8 Bytes
wird's sicher nicht (ausser es gibt Redundazen, die der Compuler
wegfegt).
Insofern kann man sich dann auch gleich die struct-Konstruktion sparen
und und das bool-flag direkt in einem char (oder von mir aus uint8_t
oder wie der Kram grade en vogue in C genannt wird) speichern.
Falls ich damit falsch liege, würde ich mich aber über Berichtigung
freuen.
LG, N0R
Norbert M. schrieb:> Naja, meine C-Erlebnisse sind schon länger her
Dann solltest du das aber nicht kommentieren.
> mitbekommen habe, ist ein char normalerweise ein Oktett groß, ergo wäre> dieses "struct of 8 chars" dann 8 Bytes groß.
Nö, ist es nicht.
Denn hinter jedem char steht ein klitzekleines ": 1", welches diesen
Member als 1 Bit groß ausweist, und der Compiler diese Bits alle
zusammenfasst.
Karl Heinz schrieb:> Norbert M. schrieb:>> Naja, meine C-Erlebnisse sind schon länger her> Dann solltest du das aber nicht kommentieren.
Wer alles weiß braucht nicht zu fragen, das ist klar.
> Denn hinter jedem char steht ein klitzekleines ": 1", welches diesen> Member als 1 Bit groß ausweist, und der Compiler diese Bits alle> zusammenfasst.
Danke, das wusste ich nicht. Der Doppelpunkt-Operator ist mir eigentlich
noch nie über den Weg gelaufen. Naja, wieder wass gelernt.
LG, N0R
Ist ja auch ein kein Operator, sondern Teil des Typspezifizierers.
: taucht in C(++) nie als Operator auf, sondern nur als
- Zusätzlicher Typspezifizierer
- switch case: (Quasi Keywordanhängsel)
- Als Teil des ternären Operators ?:
Marian B. schrieb:> Ist ja auch ein kein Operator, sondern Teil des Typspezifizierers.> : taucht in C(++) nie als Operator auf, sondern nur als> - switch case: (Quasi Keywordanhängsel)> - Als Teil des ternären Operators ?:
Diese beiden Fälle kannte ich, aber das da:
> - Zusätzlicher Typspezifizierer
war mir eben unbekannt.
Danke für den Hinweis (auch wenn ich C hoffentlich nie wieder brauchen
werde).
LG, N0R
Btw, an die Moderation: Jetzt trudeln hier lauter C- und
Programmierfragen ein, die haben doch alle nix mit Mikrokontrolleuren
oder Digitalelektronik zu tun, kann man die nicht mal in's passende
Subforum abschieben?
Leute, Ihr seid meine Rettung !
Ich bin hier eher durch Zufall "reingelesen" aber schon nach dem Beitrag
mit dem Zerlegen einer 8 Bit char Variablen in einzelne Bits und deren
Nutzung hat sich nun ein Problem gelöst, dass ich hatte um ein kleines
Programm in einen ATtiny13 zu quetschen.
In der SPS Programmierung mache ich es jeden Tag, dass einzelne Zustände
oder Fehlerbits in einem Merkerbyte gespeichert werden ... Warum kommt
man da als KOP (RSLogix5000) Programmierer nicht drauf.
Danke! Ihr habt mit dem Hinweis auf die Einzelnutzung von Bits in
Variablen mein kleines, privates, Projekt gerettet.
Schreibt diesen Hinweis inkl. dem Beispielcode bitte in das AVR C
Tutorial als eigenes Kapitel gleich nach der Beschreibung, wie man
Register beschreibt und liest. Ich glaube, da passt es am besten hin.
Gruß
Irfan
Norbert M. schrieb:> Karl Heinz schrieb:>> Norbert M. schrieb:>>> Naja, meine C-Erlebnisse sind schon länger her>> Dann solltest du das aber nicht kommentieren.>> Wer alles weiß braucht nicht zu fragen, das ist klar.
Ich sehe nicht, dass du etwas gefragt hättest. Ich sehe, dass du eine
falsche Antwort gegeben hast.
Norbert M. schrieb:> Btw, an die Moderation: Jetzt trudeln hier lauter C- und> Programmierfragen ein, die haben doch alle nix mit Mikrokontrolleuren> oder Digitalelektronik zu tun, kann man die nicht mal in's passende> Subforum abschieben?
Und welches sollte das sein?
Ein explizites Forum für Fragen zu Programmiersprachen /
Programmiertechniken gibt es hier nicht. Das Forum GCC ist offiziell für
"Fragen zu den GNU-Toolchains" gedacht. Wie man etwas Bestimmtes in der
Programmiersprache C umsetzt, gehört da nach offizieller Lesart gar
nicht rein - wird aber wohl geduldet.
Das spuckt AVR Studio 5 aus:
Device: atmega88p
Program: 7330 bytes (89.5% Full)
(.text + .data + .bootloader)
Data: 120 bytes (11.7% Full)
(.data + .bss + .noinit)
Der ATmega hat 8 kByte Flash, 1 kByte SRAM und 512 Byte EEPROM
Wie es scheint habe ich noch ne Menge an Arbeitsspeicher zur Verfügung.
Der Programmspeicher ist fast voll (wobei hier schon einiges
Auskommentiert ist, um erstmal weiter arbeiten zu können).
Leider fehlt mir das Wissen, was ich im Quelltext ändern muss, sodass
der Flash frei wird.
Was sind typische "Speicherfresser" ?
Wie kann man diese minimieren?
Hab bisher immer drauf los programmiert, ohne mir um den Speicher
Gedanken gemacht zu haben.
Zur Not nehm ich den ATmega168.
mfg
Mark Brandis schrieb:> Norbert M. schrieb:>> Btw, an die Moderation: Jetzt trudeln hier lauter C- und>> Programmierfragen ein, die haben doch alle nix mit Mikrokontrolleuren>> oder Digitalelektronik zu tun, kann man die nicht mal in's passende>> Subforum abschieben?>> Und welches sollte das sein?>> Ein explizites Forum für Fragen zu Programmiersprachen /> Programmiertechniken gibt es hier nicht. Das Forum GCC ist offiziell für> "Fragen zu den GNU-Toolchains" gedacht. Wie man etwas Bestimmtes in der> Programmiersprache C umsetzt, gehört da nach offizieller Lesart gar> nicht rein - wird aber wohl geduldet.
Die Mods hatten sich vor einiger Zeit geeinigt, das 'GCC' Forum mehr so
als allgemeineres C-Forum anzusehen. Denn so klar ist das nicht, wo da
jetzt die Grenze ist, was jetzt GCC spezifisch ist und was nicht. Wenn
man es genau nimmt, dann wäre dieses Forum wohl recht leer, während sich
die C-Fragen im allgemeinen µC-Forum tummeln. Das kann ja auch nicht der
Sinn der Sache sein. Auf der anderen Seite will man aber auch nicht für
jeden sich irgendwo eröffnenden Teilaspekt ein neues Forum aufmachen.
Daher die Bitte an alle: das GCC im Forumstitel nicht allzu eng zu
sehen. Seht es mehr als Forum für Programmierprobleme unter Verewndung
von C an. Ob das dann GCC spezifisch ist oder nicht, ist dagegen nicht
mehr so ganz der entscheidende Punkt.
txet schrieb:> Leider fehlt mir das Wissen, was ich im Quelltext ändern muss, sodass> der Flash frei wird.> Was sind typische "Speicherfresser" ?> Wie kann man diese minimieren?
Kann man so nicht sagen.
Zeig halt mal was. Dann kann man mal durchsehen und im Map-File
nachsehen, welche Funktionen eher lang sind und wo es sich lohnt, da mal
über den Quelltext drüber zu sehen, ob man was findet.
Ein relativ typischer Fehler, den ich in letzter Zeit zb öfter gesehen
habe, ist die unkritische Verwendung von zu großen Datentypen. Also zb
ein int in
1
for(inti=0;i<5;i++)
nicht nur dass zb das Inkrementieren eines 16 Bit Wertes länger dauert,
als das eines 8 Bit Wertes, erfordert es ja auch mehr Code 16 Bit Werte
zu vergleichen, zu inkrementieren, etc. Dabei braucht das in diesem Fall
kein Mensch, denn auch mit einem uint8_t kann man wunderbar von 0 bis 4
zählen.
Wie gesagt, das ist mir in letzter Zeit des öfteren hier im Forum
begegnet.
> Hab bisher immer drauf los programmiert, ohne mir um den Speicher> Gedanken gemacht zu haben.> Zur Not nehm ich den ATmega168.
Zeig mal den Code. Wunder darf man natürlich keine erwarten, aber das
eine oder andere findet man meistens dann doch.
PS: den Optimizer hast du aber schon eingeschaltet? Wenn nicht: der
bringt dir jetzt erst mal am meisten.
txet schrieb:> Was sind typische "Speicherfresser" ?> Wie kann man diese minimieren?
Indem man das Gegenteil von dem tut, was oben empfohlen wurde. ;-)
Denn viele Tricks, die RAM einsparen, kosten ROM.
Thomas Eckmann schrieb:> die drei ??? schrieb:>> Thomas Eckmann schrieb:>>> Eine grundlegende Fähigkeit des menschlichen Gehirns ist es, über banale>>> Fehler einfach hinwegzuelsen.>>>> so banal finde ich diese Zwischenbemerkung nun auch nicht, sondern schon>> entscheidend, ob die weitere Diskussion Sinn macht bzw. in eine andere>> Richtung gelenkt werden sollte!txet schrieb:> Wie es scheint habe ich noch ne Menge an Arbeitsspeicher zur Verfügung.> Der Programmspeicher ist fast voll (wobei hier schon einiges> Auskommentiert ist, um erstmal weiter arbeiten zu können).
...ach ne, dann war die bisherige Diskussion vollkommen sinnlos (wie
auch schon kurz eingeworfen, aber ignoriert...). Alle bisherigen
Vorschläge (Bit-Felder) sind kontraproduktiv, da sie noch mehr Code
generieren!
Den Optimizer hab ich auf -O1.
Was wird denn bei -Os noch alles "optimiert"?
Sind dabei Beeinträchtigungen und Fehlfunktionen möglich?
Ja fprintf nutze ich sehr häufig.
Genauso strcmp.
Denke das wird es sein und das einfachste ist für 10 Cent mehr einen
168er zu nehmen.
txet schrieb:> Ja fprintf nutze ich sehr häufig.
Du schreibst mit dem µC in Dateien?
txet schrieb:> Denke das wird es sein und das einfachste ist für 10 Cent mehr einen> 168er zu nehmen.
Das Einfachste ist nicht immer das Beste.
Irgendwann wird der neue Controller auch zu klein.
Wenn du jetzt anfängst zu verstehen daß manche Funktionen viel Speicher
kosten, und wie man das ggf. vermeiden kann, dann lernst du was für alle
nachfolgenden Projekte.
Zumal wenig Code oft auch schneller heisst.
txet schrieb:> Den Optimizer hab ich auf -O1.>> Was wird denn bei -Os noch alles "optimiert"?> Sind dabei Beeinträchtigungen und Fehlfunktionen möglich?
Wenn du sauber programmiert hast, dann macht es keinen Unterschied. Wenn
du dem Compiler aber Schlupflöcher offen gelassen hast, dann optimiert
er dir gnadenlos mit allem was er hat und sich im Rahmen der
Sprachdefninition bewegt.
> Ja fprintf nutze ich sehr häufig.
was benutzt du von sprintf?
Wie schon gesagt: sprintf ist mächtig - aber auch umfangreich. Wenn du
keine allzugroßen Formatieransprüche hast, dann kann man sprintf
sicherlich auch durch etwas einfacheres ersetzen.
(Ich geh mal davon aus, dass du sprintf meintest und nicht fprintf)
> Genauso strcmp.
Wenn du Strings vergleichen musst, dann musst du die vergleichen. Da
führt kein Weg drann vorbei. strcmp trägt allerdings nicht besonders
auf. Fast alle str... Funktionen sind sehr einfach zu implementieren.
> Denke das wird es sein und das einfachste ist für 10 Cent mehr einen> 168er zu nehmen.
Zeig halt mal.
Du könntest dabei noch was lernen.
Der Optmimierer erzeugt keine "Beeinträchtigungen und Fehlfunktionen".
Der deckt höchstens Programmierfehler deinerseits auf. Wenn dein Prgramm
aber mit -O1 läuft, läuft es auch mit -Os.
Über fprintf solltest du nochmal nachdendenken. Brauchst du das
wirklich?
Hast du wenigstens die Minimalversion von printf hinzugelinkt?
Oliver
txet schrieb:> Ja fprintf nutze ich sehr häufig.> Genauso strcmp.
Das Problem sind nicht die Funktionen selber, sondern daß sie exzessiv
als Copy&Paste-Monster benutzt werden.
Dadurch wird nicht nur der Code sehr unübersichtlich, sondern auch groß
und schwer wartbar.
Z.B. man hat mehrere Kommandos über die UART auszuwerten. Dann ist es
effektiver, man hat ein Array aus Strings und Funtionspointern, was dann
mit einem einzigen strcmp durchlaufen wird.
Auch sprintf Ausgaben ähneln sich oft, d.h. es reichen wenige, denen man
dann Pointer auf die Unterschiede übergibt.
txet schrieb:> Hab bisher immer drauf los programmiert, ohne mir um den Speicher> Gedanken gemacht zu haben.
Im Prinzip ist es richtig, erst mal ein Programm zu erstellen welches
ein korrektes Ergebnis liefert, und dann erst zu optimieren.
Um hier aber optimieren zu können, müssten wir den Sourcecode sehen. Da
Du Dich bisher hartnäckig weigerst auch nur eine einzige Zeile vom Code
zu zeigen, verstehe ich ehrlich gesagt nicht wie Du Dir das vorstellst,
in diesem Forum Hilfe zu finden.
txet schrieb:> Hab bisher immer drauf los programmiert
Das ist ausnahmslos immer der falsche Ansatz.
Zuerst macht man sich einen Plan, wie sind die Abläufe und Zustände,
welche Aufgaben sind zu lösen, welche sind ähnlich oder wiederholen sich
und können zusammengefaßt werden.
Das spart schonmal ne Menge Arbeit, Fehler und Sackgassen.
Ob man dann zuerst das Gerüst oder die Teilaufgaben oder beides
schrittweise implementiert, ist nicht so entscheidend.
http://de.wikipedia.org/wiki/Top-Down-_und_Bottom-Up-Design
Mark Brandis schrieb:> txet schrieb:>> Hab bisher immer drauf los programmiert, ohne mir um den Speicher>> Gedanken gemacht zu haben.>> Im Prinzip ist es richtig, erst mal ein Programm zu erstellen welches> ein korrektes Ergebnis liefert, und dann erst zu optimieren.
Im Prinzip geb ich dir durchaus recht.
Allerdings macht es meiner Erfahrung nach einen Unterschied, ob ein
Könner 'einfach drauf los programmiert', oder ab das ein Neuling tut.
Könner manövrieren sich designmässig seltener in eine Sackgasse und
haben auch keine Hemmungen, das bisher entstandene einfach zu verwerfen,
wenn sie merken, dass sie sich selbst ins Eck gestellt haben. Neulinge
tun das nicht und ziehen schlechtes Design auf Biegen und Brechen durch.
D.h. 'optimieren' kann in manchen Fällen auch heißen: Anerkennen das die
Methodik schlecht ist und nach algorithmischen Alternativen suchen.
Meist ist das sogar die bessere Alternative für Optimierung als irgendwo
händeringend nach einzelnen Taktzyklen suchen. Man kann einen
Bubble-Sort optimieren so viel man will, gegen andere Sortierverfahren
mit logarithmischer Komplexität hat er bis auf ein paar Sonderfälle
keine Chance. Selbst wenn die auf Assemblerebene überhaupt nicht
optimiert wurden.
> Um hier aber optimieren zu können, müssten wir den Sourcecode sehen. Da> Du Dich bisher hartnäckig weigerst auch nur eine einzige Zeile vom Code> zu zeigen, verstehe ich ehrlich gesagt nicht wie Du Dir das vorstellst,> in diesem Forum Hilfe zu finden.
Das frag ich mich mittlerweile auch.
Vielleicht geht auch wirklich nichts mehr und die Lösung 'größerer µC'
ist tatsächlich der vernünftigste Ausweg. Möglich ist es - so ist das ja
nicht. Vielleicht liegt aber auch der andere Fall vor, dass es recht
einfache Möglichkeiten gibt, 40% vom Code los zu werden. Jeder der
Profis hat wohl beide Fälle schon erlebt.