Forum: Mikrocontroller und Digitale Elektronik Controller voll, Codeoptimierung oder anderen Controller?


von Karl (Gast)


Lesenswert?

Vielleicht kann mir jemand helfen, beim optimieren meines Programms...
Wie kann ich unnötigen müll vermeiden...
Der Controller ist randvoll und mein hexfile passt nicht auf den 
controller...

Device: attiny45

Program:    4178 bytes (102.0% Full)
(.text + .data + .bootloader)

Data:        235 bytes (91.8% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...

bringt es was, wenn ich in meinem Code sowas
                     _delay_us(125);
    _delay_us(125);
      _delay_us(125);
    _delay_us(125);
      _delay_us(125);
    _delay_us(125);
      _delay_us(125);
    _delay_us(125);
      _delay_us(125);
    _delay_us(125);
      _delay_us(125);
    _delay_us(125);
      _delay_us(125);
    _delay_us(125);
      _delay_us(125);
    _delay_us(125);

durch sowas
                  _delay_ms(x) ersetze?

oder muss ich variablen minimieren etc?
die Codeoptimierung steht schon auf -Os... muss ich unbedingt den 
attiny85 verwenden?

Danke und Gruß Karl

von ?? (Gast)


Lesenswert?

>Device: attiny45
>
>Program:    4178 bytes (102.0% Full)
>(.text + .data + .bootloader)


Die 4200byte sind nur 2100 Instruktionen. Hut ab dass du da schon einen 
Bootloader drin hast. Und offensichtlich immer noch mit C arbeitest.
Ich hab mal einen Bootloader fuer den Mega16 probiert und war sehr 
schnell bei ASM, es ging dann doch nicht, und ein Mega32 wurde auch sehr 
schnell voll, die Bootpartition mein ich.

von none-wodim (Gast)


Lesenswert?

Hast Du schon mal an AUSPROBIEREN gedacht? Das gibt's doch nicht. Den 
Betrag zu schreiben, dauert 10x so lange.

von spess53 (Gast)


Lesenswert?

Hi

>bringt es was, wenn ich in meinem Code sowas
>                     _delay_us(125);
>    _delay_us(125);
>      _delay_us(125);
>    _delay_us(125);
>      _delay_us(125);
>    _delay_us(125);
>      _delay_us(125);
>    _delay_us(125);
>      _delay_us(125);
>    _delay_us(125);
>      _delay_us(125);
>    _delay_us(125);
>      _delay_us(125);
>    _delay_us(125);
>      _delay_us(125);
>    _delay_us(125);
>.....

Nein. Wer so etwas macht hat, grundsätzliche Probleme beim 
Programmieren.

MfG Spess

von Peter D. (peda)


Lesenswert?

Karl schrieb:

>                      _delay_us(125);
>     _delay_us(125);
>       _delay_us(125);
>     _delay_us(125);
>       _delay_us(125);
>     _delay_us(125);
>       _delay_us(125);
>     _delay_us(125);
>       _delay_us(125);
>     _delay_us(125);
>       _delay_us(125);
>     _delay_us(125);
>       _delay_us(125);
>     _delay_us(125);
>       _delay_us(125);
>     _delay_us(125);

Welchen triftigen Grund gibt es denn für diesen Spaghetticode?
So kriegt man ja jeden Flash leicht zum platzen.

Ansonsten:
Eine agressive Optimierung erreicht man mit:
--combine
-fwhole-program


Peter

von Malte _. (malte) Benutzerseite


Lesenswert?

Wenn dein Programm ansonsten fertig ist, versuch mal solche Sachen zu 
ersetzen, das bringt einige Bytes.
Falls aber sowieso noch Funktionen fehlen, kauf die gleich einen 
größeren Controller.

von Karl (Gast)


Lesenswert?

Hi,
sorry aber bin da halt nicht so firm mit der informatik...
dennoch danke für eure kritik. Ich habe auch überlegt wie ich das mit 
einem Timer machen könnte aber leider bin ich dran gescheitert.
da die kleinste wartespanne, die ich warten muss bevor ich einen Pin 
toggel 250µs ist und alle anderen wartespannen bis zum nächsten toggeln 
mehrfache von 250µs sind, könnte ich alle 250µs einen interrupt erzeugen 
lassen. Aber wie gestallte ich meine Routine, wo in bestimmten abständen 
mein pin getoggelt wird? mache ich das auch in der ISR oder lasse ich da 
nur eine Variable laufen und toggel dann in meiner Routine selbst wo ich 
die Variable abfrage?
Wie gestalte ich es, dass ich bis zum ablaufen der Sequenz (pintoggeln) 
in meiner routine bleibe? vielleicht mit einem flag in der ISR und in 
meiner routine while(flag)???
Wenn ich in diesen Punkten klarheit bekomme wage ich es vielleicht 
nochmal... aber wie gesagt, im moment scheiterts schon an dem 
Grundgedanken. Vielleicht könnt ihr mir dahingehend ein tip geben...
Danke und Gruß

von Malte _. (malte) Benutzerseite


Lesenswert?

Wenn du generell ein vielfaches an Delays brauchst, eine Funktion 
definieren die dann ungefähr folgenden Inhalt hat:
for (i = 0; i < k; i++) {
_delay_us(125);
}
und k wird dann per Parameter gesetzt.

von ?? (Gast)


Lesenswert?

>sorry aber bin da halt nicht so firm mit der informatik...

Ich wuerde empfehlen nicht mit so kleinen Controllern zu arbeiten. Die 
bringen nichts. Die Ersparnis von 2.70 euro gegen ueber einem Mega32 is 
vernachlaessigbar in Vergleich zu den besprochenen Problemen. Solche 
Teile machen erst Sinn bei hinreichend grossen Serien ( > 1000 Stueck). 
Fuer Anfaenger ist ein Mega32 gerade das Richtige.

von Karl H. (kbuchegg)


Lesenswert?

Karl schrieb:
> Vielleicht kann mir jemand helfen, beim optimieren meines Programms...
> Wie kann ich unnötigen müll vermeiden...
> Der Controller ist randvoll und mein hexfile passt nicht auf den
> controller...
> oder muss ich variablen minimieren etc?

So wie das gepostete Teilstück aussieht, dürfte es in deinem Programm 
noch viele Stellen geben, an denen man den Hebel ansetzen kann.
Zeig doch mal das komplette Programm, dann kann man mehr dazu sagen.

Beim Optimieren fängt man sinnvollerweise damit an, die benutzten 
Verfahren und Algorithmen in Frage zu stellen. Das bringt viel mehr als 
irgendwelche Mikrooptimierungen an einzelnen isolierten Codestellen, die 
vom Compiler nicht optimal umgesetzt werden.

von Hannes Lux (Gast)


Lesenswert?

> Beim Optimieren fängt man sinnvollerweise damit an, die benutzten
> Verfahren und Algorithmen in Frage zu stellen.

Danke...

...

von Michael U. (amiga)


Lesenswert?

Hallo,

Karl schrieb:
> Hi,
> sorry aber bin da halt nicht so firm mit der informatik...
> dennoch danke für eure kritik. Ich habe auch überlegt wie ich das mit
> einem Timer machen könnte aber leider bin ich dran gescheitert.
> da die kleinste wartespanne, die ich warten muss bevor ich einen Pin
> toggel 250µs ist und alle anderen wartespannen bis zum nächsten toggeln
> mehrfache von 250µs sind, könnte ich alle 250µs einen interrupt erzeugen
> lassen. Aber wie gestallte ich meine Routine, wo in bestimmten abständen
> mein pin getoggelt wird? mache ich das auch in der ISR oder lasse ich da
> nur eine Variable laufen und toggel dann in meiner Routine selbst wo ich
> die Variable abfrage?
> Wie gestalte ich es, dass ich bis zum ablaufen der Sequenz (pintoggeln)
> in meiner routine bleibe? vielleicht mit einem flag in der ISR und in
> meiner routine while(flag)???
> Wenn ich in diesen Punkten klarheit bekomme wage ich es vielleicht
> nochmal... aber wie gesagt, im moment scheiterts schon an dem
> Grundgedanken. Vielleicht könnt ihr mir dahingehend ein tip geben...
> Danke und Gruß

Du hast doch alle Antworten hier schon selbst gegeben...
Timer mit 250µs bauen.
Soviele Hilfvariabeln für soviele Pseudotimer anlegen, wie Du brauchst 
und für jede ein Flag definieren
Die Variablen in der ISR durchgehen und wenn nicht auf 0 dann Variable 
-1 und wenn die dann auf 0 ankommt, das Flag setzen.

Wenn Du jetzt in der main einen Timer brauchst löschst Du dessen Flag 
und setzt die Hilfsvariabel ab das gewünschte Vielfache Deiner 250µS.

Jetzt muß Du nur noch wartem bis das zugehörige Flag von der ISR gesetzt 
wird und dann Dein Pin bewegen.

Gruß aus Berlin
Michael

von gast (Gast)


Lesenswert?

Wenn das Programm fertig und zu 95% durchgetestet ist, sollte man nicht 
an den Optimierungsschaltern des Compilers drehen, da man ansonsten böse 
Überraschungen erleben kann, d.h. das Programm läuft plötzlich nicht 
mehr oder nur noch teilweise. Die obigen 95% gelten danach wieder als 
"ungetestet" und müssen wiederholt werden. I.d.R. solltest du prüfen, 
welche Funktionen wie Optimierungsbedarf besteht (z.T. reicht es aus 
CASE durch IF Anweisungen zu ersetzen um Speicherplatz zu sparen (Tipp 
u.U. compilerabhängig)) oder aber stille Reserven (z.B. Debug-code) 
freizuschaufeln.

von Malte _. (malte) Benutzerseite


Lesenswert?

gast schrieb:
> Wenn das Programm fertig und zu 95% durchgetestet ist, sollte man nicht
> an den Optimierungsschaltern des Compilers drehen, da man ansonsten böse
> Überraschungen erleben kann, d.h. das Programm läuft plötzlich nicht
> mehr oder nur noch teilweise.
IMHO trifft das aber nur zu, wenn das Programm versteckte Fehler 
enthält, die bei den aktuell verwendeten Optionen nur keine Auswirkungen 
haben. (Vom eventuell langsameren Aublaufen zeitkritischem Code und 
ändern der Typgrößen mal abgesehen).

Hier sind noch einige Flags aufgelistet, die was bringen könnten:
http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html

von Peter D. (peda)


Lesenswert?

Karl schrieb:
> nochmal... aber wie gesagt, im moment scheiterts schon an dem
> Grundgedanken. Vielleicht könnt ihr mir dahingehend ein tip geben...

Dem stimme ich zu.
Du hast warscheinlich nichtmal einen Programmablaufplan gemacht. So kann 
das natürlich nichts werden.

Du mußt Dir erstmal Klarheit schaffen, was und in welcher Reihenfolge zu 
machen ist.
Und zwar nicht als Programm sondern mit Worten (Pseudosprache) 
beschrieben. Pro Funktion ein A4-Blatt und wenn das nicht reicht, die 
Funktion weiter unterteilen.

Erst dann kann man überhaupt den PC anschalten und es in Code umsetzen.


Beschreib dochmal, was das 250µs-Dingens genau machen soll. Dann kann 
man Tips geben, wie sowas realisiert werden kann.


Peter

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.