Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 Optimierung Problem


von hufnala (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

ich habe schon eine Weile im Forum gesucht komme aber bei einem 
anscheinenden Optimierungsproblem nicht wirklich weiter. Habe auch
schon mit dem ursprünglichen Programmierer der HSB Routine Kontakt
gehabt, aber er verwendet nicht AVR-Studio...

Beiliegender Code soll eigentlich nur durch einen HSB Farbraum 
durchfaden. Tut er im großen und ganzen auch aber unter bestimmten 
Umständen gibt
es falsche Werte. Ohne Optimierung läuft dass ganze durch, aber dann 
bringe ich meine Tastenabfrage nicht unter ;-)

Der Fehler tritt z.B. bei hue = 510 auf (0x01FE), dann springt der Wert 
für blau urplötzlich von 0 auf 0xE3 (Das Log passt nicht ganz zum Code, 
hatte um schneller zu sein in diesem Fall nur die letzten Bytes der 
Farbwerte übertragen (kürzere Transmit Funktion).
Nach 28 Werten ist dass ganze vorbei, und tritt an anderer Stelle (ich 
habe ich kein so langes Log sehe es nur an den LED) wieder (ähnlich?) 
auf.

Alle wichtigen Variablen sind als volatile,
Stack overflow bin ich mir nicht sicher, brauchen Routinen auch Stack?
Data bringt der gcc 71 Byte [55%], und auch das Kapseln der CalcValues 
Routine mit cli()/sei() um Interruptprobleme während der Berechnung 
auszuschliessen hat nichts gebracht.

Der zweite HSB Code (auskommentiert) läuft auch fehlerfrei, aber die HW 
PWM mit den Werten gibt mir zu starke Sprünge, Ziel war auf SW PWM mit 9 
oder 10 bit Auflösung zu kommen (Tiny läuft mit 8Mhz internem 
Oszillator).

Hat irgendjemand noch eine Idee was da faul sein könnte? Die Routinen 
einzeln laufen (PWM, Delay usw.)...

Danke hufnala
RS 232 log:
hue  Bri R  G  B EOF
01FC FF 01 FE 00 0D0A
01FD FF 00 FE 00 0D0A
01FE FF 00 FE E3 0D0A  -->
01FF FF 00 FE E4 0D0A
...
0218 FF 00 FE FE 0D0A
0219 FF 00 FE FF 0D0A
021A FF 00 FE 00 0D0A
021B FF 00 FE 00 0D0A

von Stefan B. (Gast)


Lesenswert?

Den Fehler kann ich mit deinen Werten nicht nachstellen.

>ISR(TIMER0_COMPA_vect)
>{
>  struct Steuerung ActSteuer ;    //Aktualwert
>  ActSteuer = Steuer;             //Aktualwert aus Register
>  if (ActSteuer.PWMCount >= 512)

Das geht so nicht. Wenn du so arbeiten willst, musst du den Inhalt von 
Steuer nach ActSteuer umkopieren. Eine einfache Zuweisung wie oben 
genügt nicht.

von Stefan B. (Gast)


Lesenswert?

Vergiss meinen Post. Die struct wird im Simulator umkopiert.

von hufnala (Gast)


Lesenswert?

Stefan B. schrieb:
> Den Fehler kann ich mit deinen Werten nicht nachstellen.

OK, was kann ich dann Deiner Meinung nach noch tun? Anderen IC?

Danke!

hufnala

von Stefan B. (Gast)


Lesenswert?

Nee, im Programm sind schon noch ein paar Sachen drin, die man 
verbessern kann. Ich kann aber den Fehler nicht nachstellen und weiss 
nicht ob die Verbesserungen damit zusammen hängen.

Nur die in der ISR und im Userprogramm gemeinsam benutzen Werte volative 
machen. Aber Achtung: Im Userprogramm atomar darauf zugreifen (s. 
unten).
1
uint16_t hue, sat, bri;
2
uint16_t bri_val, red_val, green_val, blue_val;
3
volatile uint16_t red, blue, green;

ATOMIC_BLOCK in void CalcValues() benutzen:
1
#include <util/atomic.h>
2
3
  // erfordert -std=c99 Compiler Option!
4
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
5
  {
6
    //im HSB-Programm geht Helligkeit bis 255 (*4)
7
    red   = (bri * red_val)   >> 7;
8
    green = (bri * green_val) >> 7;
9
    blue  = (bri * blue_val)  >> 7;
10
  } /* ATOMIC_BLOCK */

In main() aufräumen:
1
  bri=255;
2
  sat=255;
3
  hue=1;
4
  CalcValues();                   //Initial-Werte berechnen
5
  sei();                          //dann erst Interrupts ein
6
7
//Hauptschleife

Dann kannst du noch Platz sparen. Mir kommt es vor, dass einige 
Variablen nicht benutzt werden oder im Fall des TX-Puffers nicht so groß 
sein müssen.

Dann kann man noch die lokale Variable struct Steuerung ActSteuer 
global machen.

von hufnala (Gast)


Lesenswert?

Stefan B. schrieb:
> // erfordert -std=c99 Compiler Option!

Hi Stefan,

das meiste habe ich verstanden, bis auf das Zitat. Wo stelle ich den 
Schalter ein?

Das mit dem TX Puffer usw. ist klar, den habe ich nachträglich zu 
debuggen reingefrickelt, der ganze RS232 Bereich ist im Originalprogramm 
gar nicht drin. DAs Speicherproblem besteht wenn ich den RS232 Bereich 
rausnehme und ohne Optimierung mit dem Tastenblock compiliere. Dieser 
ist leider etwas überdimensioniert, aber bei der HW die ich habe liegen 
die Tasten leider nicht auf dem selben Port so dass ich mehrmals 
maskieren muss.

Kann es sein, dass red/green/blue trotz dass sie volatile sind i.d. ISR 
verbogen werden und gar nicht in der Rechenroutine? In der ISR lese ich 
aber ja nur...

Das mit dem sei() nach CalcValues im InitBereich verstehe ich auch nicht 
ganz. Warum soll ich da initialwerte berechen? red/green/blue kommen 
immer aufgrund anderer Werte (die bis auf hue nicht verändert werden) 
neu zu Stande.

von Stefan B. (Gast)


Lesenswert?

Wenn du ein Makefile benutzt, dann gehört -stdf=c99 in die 
Compileroptionen. Im 1. Beispiel des Artikels Beispiel Makefile 
macht die Zeile CSTANDARD = -std=gnu99 das. Hier sind C99 plus GNU 
eingestellt. Müsste für ATOMIC auch funktionieren. Wenn du AVR Studio 
benutzt, dann trägst du das -std=c99 oder -std=gnu99 in das Feld neben 
ADD unter Project -> Configuration Options -> Custom Options ein und 
drückst ADD.

Bei deinem Original läuft der Timer eine gute Zeit lang, wenn noch keine 
Initialwerte für red, blue, green berechnet sind und selbst sat, bri und 
hue auf 0 stehen. Dann initialisierst du sat, bri und hue, der Timer 
läuft weiter, red, blue, green sind immer noch nicht berechnet, dann 
kommt die Arbeitsschleife und hue wird erhöht und endlich werden red, 
blue, green berechnet. Schönheitsfehler, könnte aber einen komisch 
aussehenden Start erklären.

Fürs weitere Debuggen: Schicke über UART einen Text, wenn main() 
startet. Dadurch siehst du, ob sich das Programm zwischendurch resettet.

Ich müsste dein abgespecktes Programm eigentlich auf einem Evalboard und 
drei Einzelleds nachstellen können. Taktrate hätte ich 8 Mhz, passt das 
zu deinem Timer oder brauche ich einen anderen Prescalerwert? Da mache 
ich mich mal dran (aber nicht heute).

von hufnala (Gast)


Lesenswert?

Stefan B. schrieb:
> Ich müsste dein abgespecktes Programm eigentlich auf einem Evalboard und
> drei Einzelleds nachstellen können. Taktrate hätte ich 8 Mhz, passt das
> zu deinem Timer oder brauche ich einen anderen Prescalerwert? Da mache
> ich mich mal dran (aber nicht heute).

Hi Stefan,
danke für die Erläuterung. Beim Start ist mir bisher nichts aufgefallen. 
Das mit dem Wert ausgeben im Main/Init werde ich nochmal machen. Ich 
habe den 2313 mit internem Oszillator auf 8Mhz ohne Prescaler am laufen 
gehabt.

Das mit dem Comilerschalter habe ich auch verstanden probiere ich aus.

Bitte warte mit dem Ausprobieren bis die Feiertage um sind, ich werde es 
auch so halten und bin dann vermtl. ein paar Tage im Winterurlaub, also 
keine Hektik ;-)!

Einstweilen ein schönes Fest und einen guten Rutsch
hufnala

von hufnala (Gast)


Lesenswert?

hufnala schrieb:
> Wenn du AVR Studio
> benutzt, dann trägst du das -std=c99 oder -std=gnu99 in das Feld neben
> ADD unter Project -> Configuration Options -> Custom Options ein und
> drückst ADD.

Hi,
war in den Optionen bereits eingestellt...

Gruß hufnala

von hufnala (Gast)


Lesenswert?

Hallo Stefan,

ich habe jetzt mal alle Änderungen gemacht, auch das mit dem Atomic 
Block.
Mit -Os läuft dass ganze jetzt fehlerfrei durch, habe allerdings auf 
einen neuen Chip gebrannt. Habe letztens 2 Stück hingerichtet, 
vielleicht war es einer von denen an die ich gar nicht mehr dran komme.
Momentan finde ich keinen Unterschied ob ich das CalcValues in einen 
sei/cli block packe oder nicht.

Vielleicht war's dass mit dem Atomic Block.

I.d. nächsten Tagen nehme ich mal die RS232 Kommunikation raus und gehe 
auf die reale Harware. Mal sehen was die RGB LED dann machen.
Nu ist aber erst mal Schluss...

Danke Dir für die Unterstützung!

//hufnala

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.