Forum: Compiler & IDEs ISR viel zu mollig


von Joachim .. (joachim_01)


Lesenswert?

Freunde des Interrupts,
ich wunderte mich die ganze Zeit warum meine ISR so langsam ist... Aus 
zwei Zeilen Code:
1
ISR( TIMER0_OVF_vect ) {       
2
TCNT0 = 0x55; //Dval;   
3
PORTC ^= (1 << PHI_2);   
4
  }
wird dieses pushig-poppige Ungetüm:
1
00000746 <__vector_18>:
2
     746:  1f 92         push  r1
3
     748:  0f 92         push  r0
4
     74a:  0f b6         in  r0, 0x3f  ; 63
5
     74c:  0f 92         push  r0
6
     74e:  11 24         eor  r1, r1
7
     750:  8f 93         push  r24
8
     752:  9f 93         push  r25
9
     754:  85 e5         ldi  r24, 0x55  ; 85
10
     756:  86 bd         out  0x26, r24  ; 38
11
     758:  88 b1         in  r24, 0x08  ; 8
12
     75a:  90 e1         ldi  r25, 0x10  ; 16
13
     75c:  89 27         eor  r24, r25
14
     75e:  88 b9         out  0x08, r24  ; 8
15
     760:  9f 91         pop  r25
16
     762:  8f 91         pop  r24
17
     764:  0f 90         pop  r0
18
     766:  0f be         out  0x3f, r0  ; 63
19
     768:  0f 90         pop  r0
20
     76a:  1f 90         pop  r1
21
     76c:  18 95         reti
Wie kann ich dieses Biest in Schach halten?

: Verschoben durch Admin
von Ottmar K. (wil1)


Lesenswert?

Hallo Joachim,
bin zwar von der PIC-Fraktion, aber so wie es ausieht werden in Zeile 
746-754 Systemrelevante Daten gesichert und ab Zeile 75e wieder 
zurückgeschrieben. Dazwischen liegen die Nutzdaten.
mfG Ottmar

von Heisenberg (Gast)


Lesenswert?

Mach mal:
1
ISR(TIMER0_OVF_vect, ISR_NAKED) {       
2
    TCNT0 = 0x55; //Dval;   
3
    PORTC ^= (1 << PHI_2);   
4
}

Allerdings obliegt es dann dir, die entsprechenden Register zu sichern.

von Karl H. (kbuchegg)


Lesenswert?

Anstatt den Timer vorzuladen, könntest du den CTC Modus des Timers 
benutzen. Dazu ist er schliesslich da.

Und wenn du anstatt
   PORTC ^= (1 << PHI_2);

die scheinbar längere Variante
   if( PORTC & ( 1<<PHI_2 ) )
     PORTC &= ~( 1<<PHI_2 );
   else
     PORTC |= ( 1<<PHI_2 );

wählst, ermöglichst du dem Compiler die Benutzung der Port-Bitbefehle, 
was ihn dann wiederrum nicht dazu zwingt Register zu benutzen, die dann 
auch nicht gesichert werden müssen.

von Joachim .. (joachim_01)


Lesenswert?

Jetzt weiß ich endlich was dieses ISR_NAKED bedeutet.

Danke für die Tips, ich werd's heute mittach ausprobieren.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Karl Heinz Buchegger schrieb:
> die scheinbar längere Variante
>    if( PORTC & ( 1<<PHI_2 ) )
>      PORTC &= ~( 1<<PHI_2 );
>    else
>      PORTC |= ( 1<<PHI_2 );
>
> wählst, ermöglichst du dem Compiler die Benutzung der Port-Bitbefehle,
> was ihn dann wiederrum nicht dazu zwingt Register zu benutzen, die dann
> auch nicht gesichert werden müssen.

Guter Plan. :-)

Was ist eigentlich mit den Statusregister SREG? Das muss doch bei 
ISR_NAKED von Hand gesichert werden, oder? Klar, bei sbis und sbi ist 
das nicht nötig, aber man muss schon genau hinschauen, was der Compiler 
tut. Vielleicht ist es dann sowieso besser, die komplette ISR per 
Inline-Assembler zu schreiben.

Eine andere Frage: Gibt es eines der 32 Register, die der Compiler nie 
verwendet? Oder kann man den Compiler dazu anweisen, bestimte Register 
nicht zu verwenden?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Markus Weber schrieb:

> Was ist eigentlich mit den Statusregister SREG? Das muss doch bei
> ISR_NAKED von Hand gesichert werden, oder?

Ja

> Klar, bei sbis und sbi ist das nicht nötig,
> aber man muss schon genau hinschauen, was der Compiler tut.

Du musst genau hinschauen, was dein Code tut.

Der einzige Weg, naked-Funktionen sicher zu verwenden, ist den Body 
komplett in inline-Assembler zu schreiben.

Oder nach jedem Compilieren den erzeugten Code checken, ob der korrekt 
ist.

Immerhin bewirkt naked, das wesentliche Teile des Codes nicht erzeugt 
werden -- umabhängig davon, ob sie benötigt werden oder nicht:

- Register sichern und wieder herstellen

- Programmstatus sichern und wieder herstellen

- Return-Instrukton erzeugen

- Frame-Pointer initialisieren

> Vielleicht ist es dann sowieso besser, die komplette ISR per
> Inline-Assembler zu schreiben.

Jupp.

> Eine andere Frage: Gibt es eines der 32 Register, die der Compiler nie
> verwendet?

Nein.

> Oder kann man den Compiler dazu anweisen, bestimte Register
> nicht zu verwenden?

Ja. Du kannst dem Compiler die Register von R2...R7 wegnehmen, etwa 
mittels -ffixed-2.

Beachte aber, daß -ffixed- keine Multilib-Option ist, d.h. die 
Bibliotheken wie libc sind ohne diese Schalter erzeugt und können 
diese Register verwenden.

libgcc verwendet R2...R7 nicht.

von Kein Name (Gast)


Lesenswert?

Der Z80 hatte ein ähnliches Konzept. 8 Register für das Hauptprogramm, 
ein Befehl zum Umschalten und 8 alternative Register für die ISR.
Hat sich nicht bewährt.

von Axel S. (a-za-z0-9)


Lesenswert?

Markus Weber schrieb:

> Was ist eigentlich mit den Statusregister SREG? Das muss doch bei
> ISR_NAKED von Hand gesichert werden, oder?

Ja.

> Klar, bei sbis und sbi ist
> das nicht nötig, aber man muss schon genau hinschauen, was der Compiler
> tut. Vielleicht ist es dann sowieso besser, die komplette ISR per
> Inline-Assembler zu schreiben.

Meines Erachtens ist (Inline) Assembler die einzig sinvolle Möglichkeit, 
"nackte" ISR zu schreiben. Und SREG nicht zu sichern, fällt dir 
spätestens dann auf den Fuß, wenn du die ISR mal erweiterst und nicht 
(mehr) daran denkst. Dann suchst du dir den Wolf, weil vorher 
funktionierender Code an ganz anderer Stelle unerwartete Dinge tut.

> Eine andere Frage: Gibt es eines der 32 Register, die der Compiler nie
> verwendet?

In einer ISR mußt du immer alle verwendeten Register sichern. Eine ISR 
unterbricht ja nicht nur vom Compiler generierten Code, sondern auch 
(Inline) Assembler und möglicherweise auch andere ISR.

> Oder kann man den Compiler dazu anweisen, bestimte Register
> nicht zu verwenden?

Du kannst eine globale Variable auf ein Register binden und die dann 
nicht benutzen. Wie das geht und welche Register sich eignen, steht im 
avr-libc Manual. Ist aber ziemlicher Pfusch und kann schon mit der 
nächsten Version des Compilers oder der avr-libc nicht mehr 
funktionieren.

Wenn du so viel Kontrolle über die Registerbenutzung haben willst, dann 
darfst du keinen Compiler verwenden. Schreib alles in Assembler.


XL

von (prx) A. K. (prx)


Lesenswert?

Joachim ... schrieb:
> PORTC ^= (1 << PHI_2);

NB: Bei nicht zu alten AVRs ist das äquivalent zu:
  PINC = (1 << PHI_2);

von Axel S. (a-za-z0-9)


Lesenswert?

Kein Name schrieb:

> Der Z80 hatte ein ähnliches Konzept.

Ähnlich zu was?

> 8 Register für das Hauptprogramm,
> ein Befehl zum Umschalten und 8 alternative Register für die ISR.
> Hat sich nicht bewährt.

Was meinst du mit "nicht bewährt"? Ich habe Code, der den Z80 
Zweitregistersatz erfolgreich in ISR nutzt, um sich die PUSH/POP Orgien 
zu sparen. Und anderen Code, der das nutzt um mehr Register zu haben 
(und so ganz ohne RAM auszukommen).

Der Z8 hat das Konzept noch weiter geführt: ein Block von 16 Registern 
(insgesamt hatte der Z8 bis zu 256 Register) konnte per /register 
pointer/ ausgewählt und mit verkürzter Adresse angesprochen werden. 
Eignet sich ebenfalls prima für ISR; einfach den RP pushen und dann auf 
die für die ISR reservierte Registergruppe stellen.

Die SPARC CPUs haben IIRC ein ähnliches Konzept und verwenden es, um 
schnelle Taskwechsel hinzubekommen. Etc. pp.

Nur weil ein Konzept nicht im AVR oder PIC umgesetzt ist, heißt das noch 
lange nicht daß es sich nicht bewährt hätte.


XL

von Coder (Gast)


Lesenswert?

Ist deine ISR subjektiv oder objektiv langsam? Wie schnell muss deine 
ISR sein? Was liefert den der Compiler mit aktivierten 
Geschwindigkeits-Optimierungen

von Heisenberg (Gast)


Lesenswert?

Der gute alte 8051 kann das auch. 4 Registerbänke umschaltbar mit einem 
einzigen Befehl. Darüberhinaus hat er auch noch Interruptprioritäten. Da 
kann sich der AVR eine Scheibe abschneiden.

Frage mich sowieso warum der 8051 so unbeliebt ist. Es gibt sogar einen 
kostenlosen Pascal Compiler mit IDE/Simulator:

http://turbo51.com/8051-editor-ide

von (prx) A. K. (prx)


Lesenswert?

Das Konzept umschaltbarer Registersets ist tatsächlich nicht so selten.

Bei SPARC stellt sich das freilich etwas anders dar als bei Z80. Die 
Register von SPARC sind als Stack organisiert (wie auch IA64 und früher 
AMD29000). Das erspart zwar das Sichern von Registern, die Inhalte gehen 
aber bis zum nächsten Interrupt verloren. Demgegenüber können bei ARMs 
FIRQ-Registerset die dort oft benötigten Basisadressen vorab 
initialisiert werden und zusätzlich Zeit sparen.

von (prx) A. K. (prx)


Lesenswert?

Heisenberg schrieb:
> Frage mich sowieso warum der 8051 so unbeliebt ist.

8051 leidet etwas unter der historisch gewachsenen Architektur, bei der 
eigentlich nie mehr als 256 Bytes an häufiger verwendetem RAM vorgesehen 
waren. Weshalb es allein fürs RAM mittlerweile 4 mehr oder weniger 
verschiedene Speicherbereiche mit entsprechend verschiedenen 
Adressierungen gibt. Und der grösste davon nur recht umständlich 
adressierbar ist.

Der Befehlssatz hat zudem deutliche Schwächen bei der Umsetzung der 
heute dominanten Programmiersprache C. Ein Problem, das jede Architektur 
hat, die auf einen einzelnen 8-Bit Akkumulator konzentriert ist.

AVRs sind bei Interrupts vollständig in C umständlicher, da kein 
separater Registerset vorhanden ist. Legt man jedoch auf maximale 
Effizienz wert, dann kann man per Assembler-Programmierung bestimmte 
Register für ISR reservieren und erreicht so das Gleiche. Dafür eignet 
sich AVR deutlich besser als Ziel für C Compiler, da dies bereits am 
Anfang in das Design einfloss.

von Peter D. (peda)


Lesenswert?

A. K. schrieb:
> Ein Problem, das jede
> Architektur hat, die auf einen einzelnen 8-Bit Akkumulator konzentriert
> ist.

Das haut er aber gegenüber dem AVR dadurch wieder raus, daß viele 
Operationen (XRL, INC, DJNZ usw.) direkt im SRAM und den SFRs gemacht 
werden können. Dadurch ist auch in C der erzeugte Code des 8051 kleiner.
Nur die Grundrechenarten ADD, SUBB, MUL, DIV müssen im Akku erfolgen.

Was beim 8051 für Anfänger etwas schwer zu begreifen ist, daß 
unterschiedliche SRAM-Bereiche vorhanden sind. Anfänger nehmen einfach 
immer das LARGE-Model und dann wird der Code natürlich groß und langsam.

Der Profi nimmt SMALL und dann läuft alles im schnellen DATA-SRAM. Der 
ist in etwa mit den AVR-Registern vergleichbar, nur das es 128 Byte 
sind, statt nur 32. Und große Puffer (z.B. UART-Empfang) legt man dann 
in den langsamen XDATA-SRAM.
Das LARGE-Modell ist daher die schlechteste Wahl, wenn Effizienz 
gewünscht ist.


Peter

von Falk B. (falk)


Lesenswert?

Die Frage ist doch eher. Was will der OP mit DIESER ISR? Ist das eine 
praktische Anwendung? Das kann man per CTC-Mode bzw. Output Compare auch 
ohne Interrupt machen. Oder ist es nur ein Beispiel für sehr einfache, 
hochfrequente ISRs? Die schreibt man dann wie mehrfach gesagt komplett 
in ASM, wahrscheinlich sogar als separate Datei und nicht Inline-ASM.

von Peter D. (peda)


Lesenswert?

Joachim ... schrieb:
> ich wunderte mich die ganze Zeit warum meine ISR so langsam ist

Wenn das wirklich zu langsam ist, dann hast Du die falsche Architektur 
gewählt. Vergiß den AVR.

Beim AVR sollte man für jeden Interrupt mindestens 50..100 Zyklen 
reservieren. Er ist schließlich ein RISC, und die brauchen eben viele 
Zyklen.
Mit dem 8051 kannst Du das nicht vergleichen.

Auch nützt es garnichts, nur einen Interupt zu optimieren. Der längst 
mögliche Interrupt bestimmt die maximale Interruptlatenz. Man kann ja 
nicht wie beim 8051 Prioritäten vergeben.


Peter

von (prx) A. K. (prx)


Lesenswert?

Peter Dannegger schrieb:
> Das haut er aber gegenüber dem AVR dadurch wieder raus, daß viele
> Operationen (XRL, INC, DJNZ usw.) direkt im SRAM

Aber nur in einem der 4 erwähnten RAMs. Weshalb ich das ja erwähnte. Man 
muss sich also genau überlegen, welche Daten in welchem RAM liegen 
sollen. Das macht die Programmierung komplizierter.

Datenstacks sind auch nicht grad dessen starke Seite, was Folgen für 
reentrant code hat. Weshalb altgediente Programmierer solcher 
Architekturen dies denn auch für Giftzeug halten - und Leute, die nicht 
mit 8051 oder PICs aufgewachsen sind, nicht recht verstehen weshalb.

Ich wollte hier ausserdem keinen Prozessorkrieg vom Zaun brechen. Denn 
auch mit 8051 kann man gut arbeiten, zumal schneller/kürzer als 
schnell/kurz genug nichts einbringt. Es gibt aber eben auch Gründe 
dafür, weshalb Neueinsteiger sich die den alten Hasen im Schlafe 
vertrauten Tricks vielleicht ersparen wollen.

Dass AVRs im Forum so beliebt sind, hat ohnehin andere Gründe. Sind in 
allen Grössen gut zu kriegen und das Development-System gibts ebenso in 
allen Grössen für lau.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Coder schrieb:
> Was liefert den der Compiler mit aktivierten
> Geschwindigkeits-Optimierungen

Pro- und Epilog normaler ISRs sichern / restaurieren immer R0, R1 und 
SREG, unabhängig vom Optimierungsgrad oder sonstigen Optionen, siehe

http://gcc.gnu.org/PR20296

Bjorn Haase dazu:

>> everyone working on the avr back-end is aware of this problem.
>> The difficulty is, that the present architecture of the avr
>> back-end does not easily permit to improve this case

Zu Deutsch:  Es ist sehr aufwändig, diese Optimierung in avr-gcc 
einzubauen.  I.w. bedeutet es, einen Großteil des avr-Backends von GCC 
neu zu schreiben, nur um eine handvoll Instruktionen zu sparen.

Wenn du dir anschaust, wieviel Entwickler dazu bereit sind, zu avr-gcc 
beizutragen, kommst du auf eine Zahl nahe an 0.


A. K. schrieb:

> AVRs sind bei Interrupts vollständig in C umständlicher, da kein
> separater Registerset vorhanden ist. Legt man jedoch auf maximale
> Effizienz wert, dann kann man per Assembler-Programmierung bestimmte
> Register für ISR reservieren und erreicht so das Gleiche.

Ist aber sehr tricky.  Vor allem auch deshalb, weil globale Register 
nicht volatile sind und es daher nicht ratsam ist, Werte zwischen 
unterschiedlichhen IRQ-Ebenen über globale Register zu transportieren.

Die Lib-Problematik wurde oben bereits genannt.

> Dafür eignet sich AVR deutlich besser als Ziel für C Compiler,
> da dies bereits am Anfang in das Design einfloss.

Leider wurde das nicht zuende gedacht.

Die Instruktionen IN und OUT zum Beispiel belegen 4096 Opcodes die nicht 
wirklich gebraucht werden, denn LDS uns STS leisten das gleicht.

Letztere sind zwar 32-Bit Befehle, aber je größer ein Programm wird, 
desto weniger Code entrfällt antailig auf I/O Zugriffe.

Hauptproblem der AVR ISA ist ein fehlender Barrel-Shift / Barrel-Rotate.

Mit einem Barrel etwa, der Ein- und Ausgabe von R0/R1 nimmt und ein 
Register als Offset erlaubt, wären nur 32 Opcodes belegt.  Aber sehr 
viele Programme würden dadurch deutlich schneller und kleiner.

Erlaubte man als 16-Bit Operand ein W-Register, wäe der Code nochmals 
kleiner und schneller und würde nur 128 Opcodes belegen.

Immerhin sind Shifts nicht gerade unüblich und so elementar wie 
Addition, Subtraktion und Vergleiche.

von (prx) A. K. (prx)


Lesenswert?

Johann L. schrieb:
> Leider wurde das nicht zuende gedacht.

Yep. Ist auch nur relativ zu den damaligen Vergleichen zu sehen. Nicht 
zu dem, was man hätte draus machen können.

> Die Instruktionen IN und OUT zum Beispiel belegen 4096 Opcodes die nicht
> wirklich gebraucht werden, denn LDS uns STS leisten das gleicht.

Sind aber ein Wort grösser und insbesondere einen Takt langsamer. Zudem 
entstanden die heutigen LDS/STS Befehle auch erst, nachdem ein 
Compiler-Hersteller den Designern ob dem eigentlich geplanten Banking 
die Leviten lasen.

> Letztere sind zwar 32-Bit Befehle, aber je größer ein Programm wird,
> desto weniger Code entrfällt antailig auf I/O Zugriffe.

Yep. Hier muss man aber einrechnen, dass auch AVR nicht wirklich für 
Mega256er konzipiert wurde. Die 8-Bitter sind alle für kleine Aufgaben 
konzipiert und dann bis übers eigentlich Sinnvolle hinaus aufgeblasen 
worden. Architektur-Designer haben einen geplanten Einsatzbereich im 
Auge und wundern sich später, in welche nie vorgesehenen Dimensionen 
ihre Ergebnisse einmal vorstossen könnten (wie der 8086 in dem heute 
irgendwie noch der 8080 drinsteckt ;-).

Der Designer hat also einen anderen Ansatz, als ein 10 Jahre mit der 
Architektur arbeitender Produktentwickler. Der Designer denkt wie 
Niklaus Wirth, der für jedes Problem eine angepasste Programmiersprache 
entwickelte (weshalb keiner davon durchschlagender Erfolg zuteil wurde).

> Hauptproblem der AVR ISA ist ein fehlender Barrel-Shift / Barrel-Rotate.

Jau, aber das hat schon recht viel mit Aufwand zu tun, denn die 
sinnvolle Mindestausstattung wäre nicht ein 8:8 barrel shifter, sondern 
ein 16:8 funnel shifter mit summarum 3 Input-Operanden und somit 
aufgrund der Busse mindestens 2 Takten Laufzeit. Weil sonst nicht gut 
auf breitere Typen kaskadierbar.

Auch eine saubere Manipulation des Stackpointers fehlt. Dass die auch 
beim XMega nicht hinzu gefügt wurde, was für mich der psychologische 
Killer.

von (prx) A. K. (prx)


Lesenswert?

A. K. schrieb:
> ein 16:8 funnel shifter mit summarum 3 Input-Operanden und somit
> aufgrund der Busse mindestens 2 Takten Laufzeit.

Alternativ die wirklich teure Lösung mit 3 Bussen und 3 Readports. Oder 
ein Spezialregister für die Shiftcount. Eben alles etwas unschön.

> war für mich der psychologische Killer.

Und die fehlende Einblendung von Flash in den Datenadressraum. Die Sache 
mit dem Stack ist wie gesagt eher psychologisch, nur bin ich eben kein 
alter µC-Entwickler mit Deadlines und kann es mir leisten.

von Axel S. (a-za-z0-9)


Lesenswert?

Peter Dannegger schrieb:

> Auch nützt es garnichts, nur einen Interupt zu optimieren. Der längst
> mögliche Interrupt bestimmt die maximale Interruptlatenz. Man kann ja
> nicht wie beim 8051 Prioritäten vergeben.

Nein. Aber man kan eine längerlaufende "Niederfrequenz" ISR 
unterbrechbar machen. So kann die kurze "Hochfrequenz" ISR trotzdem 
laufen. Mache ich regelmäßig.


XL

von Peter D. (peda)


Lesenswert?

Axel Schwenke schrieb:
> Nein. Aber man kan eine längerlaufende "Niederfrequenz" ISR
> unterbrechbar machen.

Leider ist das aber oft die Hose mit der Kneifzange anziehen.

Kandidaten für lange Interrupts sind ja z.B. I2C, UART, ADC, diese 
löschen aber nicht ihr Flag beim Eintritt!

Man muß sie also erst disablen, ehe man wieder global freigeben kann, 
d.h. erst sehr spät nach der Sicherung sämtlicher verwendeten Register. 
Und damit sind schon wieder nen Haufen Zyklen um. Und beim Verlassen hat 
man dann die gleichen Zeitbedarf unter Interruptsperre.
Der Effekt ist also eher gering bis kaum.

Meine Methode (nur) beim AVR ist daher, sämtliche Interrupts kurz zu 
halten.
Die Daten werden in einen Puffer geschrieben, denn dann das Main in Ruhe 
auswerten kann.

Axel Schwenke schrieb:
> Mache ich regelmäßig.

Mache ich deshalb nie. Es hat mir nichts gebracht.
Kannst aber gerne mal ein Beispiel posten, wo es einen merkbaren Effekt 
hatte.


Peter

von Ralph (Gast)


Lesenswert?

Wenn diese ISR zu langsam ist bist du auf dem AVR falsch.

Überlege dir genau was du brauchst, und such dir dann einen µC mit 
ausreichend Leistung.

Alles andere ist Murks.

von Axel S. (a-za-z0-9)


Lesenswert?

Peter Dannegger schrieb:
> Axel Schwenke schrieb:

>> ... man kan eine längerlaufende "Niederfrequenz" ISR
>> unterbrechbar machen.
>> Mache ich regelmäßig.
>
> Mache ich deshalb nie. Es hat mir nichts gebracht.
> Kannst aber gerne mal ein Beispiel posten, wo es einen merkbaren Effekt
> hatte.

Einfach. Beitrag "Kurzzeittimer (z.B. für Platinenbelichter)"

Hier läuft die "langsame" ISR einmal jede Millisekunde und entprellt 
u.a. den Encoder. Die "schnelle" ISR läuft alle 125µs, wenn der Buzzer 
angeschaltet ist und toggelt im wesentlichen 2 Pins. Wenn die langsame 
ISR nichtunterbrechbar ist, hört man ein häßliches Schnarren auf dem 
Pfeifton.

1
/* once every millisecond */
2
ISR(TIMER1_COMP1_vect)
3
{
4
    sei(); /* allow buzzer interrupt */
5
    debounce_encoder();
6
    debounce_button();
7
    vtick = (vtick == 999 ? 0 : vtick+1);
8
}
9
10
11
/* toggle buzzer pins */
12
ISR(TIMER0_OVF0_vect)
13
{
14
    TCNT0 = 130;
15
    PORTD ^= (_BV(buzzer_pin_a) | _BV(buzzer_pin_b));
16
}


XL

von Axel S. (a-za-z0-9)


Lesenswert?

Axel Schwenke schrieb:
> Einfach. Beitrag "Kurzzeittimer (z.B. für Platinenbelichter)"

Ich sehe gerade, daß da noch eine ältere Version des Codes liegt. Werde 
ich die Tage mal updaten. Der Buzzer ist neu dazu gekommen.


XL

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Axel Schwenke schrieb:

> /* once every millisecond */
> ISR(TIMER1_COMP1_vect)
> {
>     sei(); /* allow buzzer interrupt */
>     debounce_encoder();
>     debounce_button();
>     vtick = (vtick == 999 ? 0 : vtick+1);
> }

Das Problem ist wohl das debounce-Zeug; vermutlich mit Warteschleifen 
gemacht?

von (prx) A. K. (prx)


Lesenswert?

Ein Debouncer per Timer benötigt keine Warteschleifen und dieses Problem 
keine zwei Timer. Einer mit 8 KHz und Tick jedes 8. Mal würde das 
Problem eleganter lösen. Und den betreibt mal sinnvollerweise im CTC 
Modus.

von Axel S. (a-za-z0-9)


Lesenswert?

Johann L. schrieb:

> Das Problem ist wohl das debounce-Zeug; vermutlich mit Warteschleifen
> gemacht?

Nö. Es dauert halt nur alles in allem länger als die ca. 1000 Takte, die 
zwischen zwei Buzzer-Interrupts liegen. Und bevor du mir das nächste Mal 
sowas unterstellst, schaust du besser erst mal in den Code, ok?


XL

von (prx) A. K. (prx)


Lesenswert?

Axel Schwenke schrieb:
> Nö. Es dauert halt nur alles in allem länger als die ca. 1000 Takte,

1000 Takte bloss fürs debouncen???

von Axel S. (a-za-z0-9)


Lesenswert?

Axel Schwenke schrieb:
> Ich sehe gerade, daß da noch eine ältere Version des Codes liegt. Werde
> ich die Tage mal updaten. Der Buzzer ist neu dazu gekommen.

[x] done

von Axel S. (a-za-z0-9)


Lesenswert?

A. K. schrieb:
> Axel Schwenke schrieb:
>> Nö. Es dauert halt nur alles in allem länger als die ca. 1000 Takte,
>
> 1000 Takte bloss fürs debouncen???

Hmm. Wahrscheinlich nicht mal. Aber eben lang genug, daß man es gehört 
hat. Vermutlich ein häßlicher Interferenzeffekt, weil "dank" des 
länglichen ISR-Vorspanns, den der gcc generiert, es womöglich eher 126µs 
sind weil der Timer zu spät nachgeladen wird.

Und wie gesagt: es stört die ISR, die nur alle 1000µs läuft ja nicht, 
daß da zwischendrin eine andere ISR läuft.


XL

von (prx) A. K. (prx)


Lesenswert?

Axel Schwenke schrieb:
> Hmm. Wahrscheinlich nicht mal. Aber eben lang genug, daß man es gehört
> hat. Vermutlich ein häßlicher Interferenzeffekt, weil "dank" des
> länglichen ISR-Vorspanns, den der gcc generiert, es womöglich eher 126µs
> sind weil der Timer zu spät nachgeladen wird.

Da dein Timer nicht im CTC Modus arbeitet variiert die Frequenz der 
Grundwelle mit der Interrupt-Sperrzeit des 1ms Interrupts. Im CTC Modus 
wäre es nur die Phase, also irgendwelche Oberwellen. Bei 4KHz Grundwelle 
stört das jenseits der Jugend nur noch deinen Hund.

Und wenn der Debouncer keine ganzen Interrupts verschluckt, dann ist die 
Kombination in einem Timer fast nebenwirkunsgfrei, weil die Variabilität 
der Latenz dann noch ein paar Takte beträgt.

von xfr (Gast)


Lesenswert?

Warum nimmst Du bei Timer0 nicht den CTC-Modus?

von Axel S. (a-za-z0-9)


Lesenswert?

A. K. schrieb:

> Da dein Timer nicht im CTC Modus arbeitet variiert die Frequenz der
> Grundwelle mit der Interrupt-Sperrzeit des 1ms Interrupts. Im CTC Modus
> wäre es nur die Phase, also irgendwelche Oberwellen.

Wenn das ein tiny2313 wäre, dann könnte mehr als ein Timer CTC. So muß 
ich da leider den Timer nachladen. Für mich mit meiner Z80 Sozialisation 
ja sowieso ein Unding, daß die Timer im AVR kein TOP Register haben. Und 
überhaupt: vorwärts zählen! ;)

Na, vielleicht schreib ich den Krempel nochnmal um. Timer 1 auf 8kHz und 
nur jeden 8. Aufruf entprellen ist ja wirklich sauberer. Allerdings muß 
ich dann auch in der Hauptschleife auf "vtick hat sich geändert" pollen. 
Was ich eigentlich vermeiden wollte. sleep() in Verbindung mit nur einem 
Timer ist so schön praktisch...


XL

von Peter D. (peda)


Lesenswert?

Axel Schwenke schrieb:
> Einfach. Beitrag "Kurzzeittimer (z.B. für Platinenbelichter)"

Timerinterrupts sind die Ausnahme, in denen man (fast) gefahrlos 
Interrupts enablen kann. Nur leider sind das bei mir nicht die langen 
Interrupts.

Auch kann man einfach nur den Beeper-Interrupt nehmen und darin das 
Debounce aufrufen. Dann stört es auch nicht, da es ja synchron ist.

Man könnte aber auch für den Beeper ganz einfach eine PWM nehmen und 
sich den Interrupt ganz sparen.


Peter

von Joachim .. (joachim_01)


Lesenswert?

Prob ist ich brauch mindestens 200kHz an einem Portpin. Hab jetzt den 
CTC-Mode im Datenbl. nicht komplett durchgelesen, bin aber nicht sicher 
ob ich das damit erreichen kann.

von (prx) A. K. (prx)


Lesenswert?

200kHz Pinfrequenz = 400k Interrupts/sec = 2,5µs pro Interrupt = 50 
Takte bei 20MHz. Das ist schon recht sportlich, wenn per ISR in C 
getoggelt wird.

Nur: Einen Pin toggeln, das kann der Timer schon selbst, ganz ohne ISR. 
Und das geht problemlos mit 200kHz. Ich habe hier einen Zwerg-AVR 
rumliegen, der 30MHz auf einem Pin liefert.

von Werner (Gast)


Lesenswert?

Joachim ... schrieb:
> Hab jetzt den CTC-Mode im Datenbl. nicht komplett durchgelesen, bin
> aber nicht sicher ob ich das damit erreichen kann.

Hättest du vielleicht tun sollen. Warum sollte es damit nicht 
funktionieren?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Axel Schwenke schrieb:
> Johann L. schrieb:
>
>> Das Problem ist wohl das debounce-Zeug; vermutlich mit Warteschleifen
>> gemacht?
>
> Nö. Es dauert halt nur alles in allem länger als die ca. 1000 Takte, die
> zwischen zwei Buzzer-Interrupts liegen. Und bevor du mir das nächste Mal
> sowas unterstellst, schaust du besser erst mal in den Code, ok?

Das ist keine Unterstellung, es ist eine Frage.

Und aus dem Pseudo-Code, der oben gepostet ist, ist deine Antort auch 
nicht ableitbar.

Wie sich dieser Code konkret verhält ist stark von der Umgebung 
abhängig, z.B. wie die debounce* Funktionen implementiert sind, ob sie 
geinlint werden oder nicht, Compilerschalter und -version, etc.

Falls die Funktionen z.B. nicht geinlint werden, erzeugen sie in der 
entsprechenden ISR einen starken Jitter, den du vermutlich nicht haben 
willst.

von Karl H. (kbuchegg)


Lesenswert?

Axel Schwenke schrieb:
> Axel Schwenke schrieb:
>> Ich sehe gerade, daß da noch eine ältere Version des Codes liegt. Werde
>> ich die Tage mal updaten. Der Buzzer ist neu dazu gekommen.
>
> [x] done


Schön für dich.
Aber ein tar.gz mach ich nicht auf. Nicht weil ich es nicht könnte, 
sondern weil es mich nicht interessiert mir dafür Software extra 
downzuloaden. Und dazu hab ich keine Lust, um festzustellen auf welche 
Weise du in einer ISR 1000 Takte verbruzelst um ein paar Taster und 
einen Encoder zu entprellen.

von (prx) A. K. (prx)


Lesenswert?

Naja - wenn man Windows auf der Kiste hat, dann hat man mit 7-zip 
weitgehend ausgesorgt. Frisst auch .tar.gz, was im Linux-Umfeld recht 
verbreitet ist.

Die Debounce-Routinen sehen harmlos aus. Nur bei der int Division durch 
32 sollte man vorsorglich nachsehen und ggf. nachsorgen, dass der 
Compiler daraus keine echte Division macht. Ist bei -Os ja nicht 
zwangsläufig so.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

A. K. schrieb:
> Naja - wenn man Windows auf der Kiste hat, dann hat man mit 7-zip
> weitgehend ausgesorgt. Frisst auch .tar.gz, was im Linux-Umfeld recht
> verbreitet ist.

Darum geht's doch nicht.  Glaubst Du etwa Karl Heinz ist nicht in der 
Lage, ein tar auszupacken?

Der OP will Hilfe bei einem Problem und werwartet, daß man sich alle 
Informationen selbst zusammensucht? Kann er natürlich erwarten, aber 
dass diese Erwartung erfüllt wird ist weniger wahrscheinlich als eine 
Antwort auf eine Anfrage zu erhalten, die klipp und klar darlegt, wie 
die Sachlage ist ohne daß man ein Reverse-Engineering starten muss 
oder quer duchs Netz und Threads suchen muss...

von Rolf Magnus (Gast)


Lesenswert?

Johann L. schrieb:
> A. K. schrieb:
>> Naja - wenn man Windows auf der Kiste hat, dann hat man mit 7-zip
>> weitgehend ausgesorgt. Frisst auch .tar.gz, was im Linux-Umfeld recht
>> verbreitet ist.
>
> Darum geht's doch nicht.  Glaubst Du etwa Karl Heinz ist nicht in der
> Lage, ein tar auszupacken?

Wenn ich als Linux-Nutzer auch so pingelig wäre, wäre ich nur noch am 
motzen. Wenn's ein zip-File wäre, hätte er bestimmt nichts gesagt, aber 
dann wäre es ein Format gewesen, das auf meinem System nicht üblich ist. 
So what? Jedes File einzeln anhängen, statt ein Archiv zu verwenden, 
weil jeder seine Vorlieben hat bezüglich Archiv-Format?

von (prx) A. K. (prx)


Lesenswert?

Johann L. schrieb:
> Der OP will Hilfe bei einem Problem und werwartet, daß man sich alle
> Informationen selbst zusammensucht?

Mitnichten. OP ist Joachim und der hat sein Codehäppchen hier verbatim 
reingepostet.

Das einzige .tar.gz ist in einer nicht direkt in Zusammenhang stehenden 
verlinkten Implementierung von Axel Schwenke, und darauf bezog sich Karl 
Heinz. Und wer eine eigenes Programm anderen zur Verfügung stellt, der 
hat m.W. eine etwas grössere Freiheit beim Format.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

A. K. schrieb:
> Johann L. schrieb:
>> Der OP will Hilfe bei einem Problem und werwartet, daß man sich alle
>> Informationen selbst zusammensucht?
>
> Mitnichten. OP ist Joachim und der hat sein Codehäppchen hier verbatim
> reingepostet.

Ah Tippfehler meinerseite.  Es geht nicht um den OP.

von Karl H. (kbuchegg)


Lesenswert?

Rolf Magnus schrieb:

> So what? Jedes File einzeln anhängen, statt ein Archiv zu verwenden,
> weil jeder seine Vorlieben hat bezüglich Archiv-Format?

Tja.
War ja auch eher als freundlicher Hinweis gedacht, dass er mit einem 
tar.gz eher nicht auf rege Beteiligung am Codestudium hoffen soll.

Auch wenn es vielen nicht gefällt (inklusive mir): an Windows kommt man 
nun mal nicht vorbei.

von Caradhras (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Auch wenn es vielen nicht gefällt (inklusive mir): an Windows kommt man
> nun mal nicht vorbei.

Was hat das Betriebssystem mit der Anwendersoftware (Packer) zu tun? 
7-zip kann alles (und läuft unter Windows).

von xfr (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Auch wenn es vielen nicht gefällt (inklusive mir): an Windows kommt man
> nun mal nicht vorbei.

An nem vernünftigen Archivprogramm à la 7-Zip oder WinRAR aber auch 
nicht ... ;-)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Caradhras schrieb:
> Was hat das Betriebssystem mit der Anwendersoftware (Packer) zu tun?

Windows hat seit XP einen integrierten "Packer" für Zip, was es (egal 
welches BS) häufig einfacher macht wenn man ein Zip bereitstellt, 
außerdem ist TAR meiner Meinung nach auch unter Linux nicht unbedingt 
der Hit, ich seh da keinen Vorteil, die Zeiten der Bandlaufwerke im 
Privaten Bereich sind doch schon etwas länger vorbei ;-)

von (prx) A. K. (prx)


Lesenswert?

Läubi .. schrieb:
> der Hit, ich seh da keinen Vorteil

Schon mal versucht, Symlinks zu zippen und beim Restore ebenso wieder zu 
erhalten? Ebenso gehen die Rechte und UID/GIDs über den Jordan. Das ist 
beides nicht unbedingt ein Problem bzgl. Forum, aber es erklärt, weshalb 
ZIP nicht das Format erster Wahl für Linuxer ist.

Es gibt irgendwelche Installationspakete im (L)AMP-Umfeld, die 
nervigerweise nicht als .tar.gz sondern als .zip ausgeliefert werden. 
Anschliessend muss man dann erst einmal sämtliche Rechte wieder einzeln 
zurecht biegen, weil das in diesem Kontext nicht ganz unwichtig ist.

> die Zeiten der Bandlaufwerke

Weshalb verwendet alle Welt printf(), obwohl 99,9999% aller solchen 
Ausgaben nie auf einem Drucker landen? ;-)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

A. K. schrieb:
> Schon mal versucht, Symlinks zu zippen und beim Restore
> ebenso wieder zu erhalten?
Backup & Restore sind aber wohl ein etwas anderer Anwendungsfall als 
veröffentlichen von Code o.ä... ;-)

A. K. schrieb:
> ZIP nicht das Format erster Wahl für Linuxer ist
Und deshalb muss man auf alles mit dem Hammer einschlagen was wie ein 
Nagel aussieht? Zip ist ein Kompromiss der vor allem was 
Interoperabilität angeht so schlecht nicht ist.

A. K. schrieb:
> Es gibt irgendwelche Installationspakete im (L)AMP-Umfeld, die nicht als
> .tar.gz sondern als .zip ausgeliefert werden. Anschliessend muss man
> dann erst einmal sämtliche Rechte wieder einzeln gerade biegen,

Auch Zip "kennt" Dateirechte, das Problem ist eher das die meisten User 
keine Ahnung haben was das sein soll und wofür man das braucht ;-)
[Und einige Packprogramme das nicht können]

A. K. schrieb:
> Weshalb verwendet alle Welt printf(), obwohl 99,9999% aller
> solchen Ausgaben nie auf einem Drucker landen?
Gute Frage :-)

von (prx) A. K. (prx)


Lesenswert?

Läubi .. schrieb:
> Und deshalb muss man auf alles mit dem Hammer einschlagen was wie ein
> Nagel aussieht? Zip ist ein Kompromiss der vor allem was
> Interoperabilität angeht so schlecht nicht ist.

Was Veröffentlichungen hier im Forum angeht hast du natürlich Recht. 
Aber du wolltest wissen, weshalb Linuxer reflexartig .tar.gz verwenden.

Windows-User meckern traditionell, dass sie für tar/rar/... eigens einen 
(Ent)Packer installieren müssen (hatte ich auch schon, wenn ich grad 
diesen Hut auf und noch kein 7-zip installiert hatte), während ZIP schon 
drinsteckt. Dieses Argument kann man umdrehen: In Debian muss man 
zip/unzip eigens nachinstallieren, tar/gzip ist jedoch schon drauf . ;-)

von Peter D. (peda)


Lesenswert?

A. K. schrieb:
> Mitnichten. OP ist Joachim und der hat sein Codehäppchen hier verbatim
> reingepostet.

Doch.
Das ist eben das Problem an einem Häppchen, niemand weiß, in welchem 
Kontext es steht. Also warum der OP meint, es ausgerechnet nur so lösen 
zu können.

Ohne diesen ewigen Informationsgeiz wären bestimmt 50% der Threads viel 
kürzer und auch viel erfolgreicher.
Es wird manchmal sogar angepißt reagiert, wenn dann alle Leute erstmal 
genervt nachfragen müssen.

Man muß ja keine Romane schreiben. Man muß sich einfach nur überlegen, 
welche Angaben man selber bräuchte, um eine Aufgabe zu lösen.
Also wenn ein Fremder zu einem käme und diese Aufgabe stellt.

200kHz gehen bequem mit PWM ganz ohne Interrupts. Der CPU-Takt muß nur 
 >400kHz sein.


Peter

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

A. K. schrieb:
> In Debian muss man
> zip/unzip eigens nachinstallieren

Sicher? Ich meine das bei meiner (schon recht alten) Installation schon 
von Anfang an dabei gehabt zu haben ... gut möglich das ich es schon 
wieder vergessen hab das ich da mal was nachinstalliert hatte, eventuell 
"fehlt" es auch nur wenn man die "absolute minimalistic installation" 
Option wählt ;-)

> rar
Ist auch immer wieder ein Problem, unter Linux gibt es zwar 
Unterstützung aber ich hab immer Probleme damit egal ob win oder linux 
das es sich mal nicht entpacken lässt oder Mist baut :-(

> weshalb Linuxer reflexartig .tar.gz verwenden
Ich bin da wohl nicht "Linuxer" genug, allein der Buchstabensalat der 
sich Kommandozeilenparameter nennt schreckt schon mal ab :-)

Peter Dannegger schrieb:
> Das ist eben das Problem an einem Häppchen

Das Problem ist: Wenn ich weiß welche Informationen zur Lösung nötig 
sind kann ich auch meist das Problem selber lösen.

von Axel S. (a-za-z0-9)


Lesenswert?

Ist ja krass. Da habe ich mal eben im Vorbeigehen einen 
Betriebssystem-Krieg angezettelt :)

Und alles nur, weil ich auf PeDas Frage "kannst du mal ein Beispiel 
zeigen" auf ein altes Posting mit angehängtem .tar.gz gezeigt habe.

Ich kann zwar nicht so recht nachvollziehen, daß schon das Archivformat 
zur Verweigerung führt, aber andererseits hatte ich ja weder eine Frage 
noch sonstwie im Hilfe gebeten. Kein Verlust also.

Ebenfalls verwundert bin ich, daß einige Windows in den Himmel loben, 
wenn es um µC Entwicklung geht. Mit dem AVR-Studio mag Windows als 
Entwicklungsplattform ja noch erträglich sein. Aber schon make ist 
regelmäßig nicht mehr an Bord und nach grep oder Perl getraut man 
sich schon gar nicht mehr zu fragen. Allein daß die GNU-Toolchain für 
Windows als Binary verteilt werden muß, weil man den Kram mit 
Windows-Bordmitteln nicht gebaut kriegt, spricht Bände. Da ist mir mein 
Linux aber 1000-mal angenehmer.

Aber hey - jeder wie er es mag. Und so wie Windows-Nutzer mir 
proprietären Scheiß wie .docx vorsetzen, nehme ich mir die Freiheit, 
Archive als .tar.gz und Platinenlayouts als .pcb anzubieten.


XL

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

A. K. schrieb:
> In Debian muss man zip/unzip eigens nachinstallieren,
> tar/gzip ist jedoch schon drauf . ;-)

Einfach ein j anstatt ein t?

Auspacken:

jar xf archiv.zip

Inhalt:

jar tf archiv.zip

Einpacken (ohne Manifest, daher M):

jar cfM archiv.zip <dateien>

von (prx) A. K. (prx)


Lesenswert?

-bash: jar: command not found

Es ist jetzt nicht so, dass man das nicht nachinstallieren könnte. 
Zip/unzip und Java sind natürlich in den Repositories drin. Aber eben in 
der Grundinstallation nicht bereits installiert.

Und bei Java ist das auch besser so, denn da steht dann erst einmal die 
Entscheidung an, welche Variante man im Auge hat. Debian favorisiert 
freie Software, folglich ist das nicht freie Oracle/Sun-java nicht die 
einzige Variante und auch nur im non-free Repository zu finden.

von Holm T. (Gast)


Lesenswert?

Unter Dos/WinDOS gab es schon immer Programme die Alles konnten aber 
selten Alles gut. (PcTools/Norton/Xtree als Beispiel). Das Ergebnis war, 
das man Jedes Programm installiert hat.

Unter unixoiden OS gibt es Programme die genau ein Ding können und das 
meistens sehr gut. Tar schreibt und entpackt Archive, er komprimiert 
nicht.
Dazu gibt es dann Kompressoren wie gzip oder bzip oder eben auch zip.
Man kann sich aussuchen was man nimmt, was sich dann in tar.gz oder 
tar.bz2 äußert.

Ein Windows Looser der meint "ein tar.gz packe ich jetzt nicht aus" ist 
eigentlich nur als arroganter Dödel zu bezeichnen, denn mit verwanzten 
Windowsarchiven (Viren gerne im Zip) möchte doch ein Unix User auch 
nichts zu tun haben?

Preisfrage: Was genau kann man mit einem frisch installierten Windows 
ohne Zusätzliche 3rd. Party Software tun, außer im Internet 
herumzusurfen?

Anwesende selbstverständlich ausgenommen...

Gruß,

Holm

von Oliver S. (oliverso)


Lesenswert?

Holm Tiffe schrieb:
> Tar schreibt und entpackt Archive, er komprimiert
> nicht.

Nun ja, welchen praktischen Sinn nicht-komprimierte Archive haben, hat 
sich mir noch nie erschlossen. Die braucht niemand, und daher gibt es 
die auf Windows gar nicht erst.

Oliver

von Peter D. (peda)


Lesenswert?

Oliver S. schrieb:
> welchen praktischen Sinn nicht-komprimierte Archive haben,

Wird wohl historische Gründe haben.
Früher waren die CPUs langsam, das Komprimieren dauerte wesentlich 
länger.
Heutzutage sind die Festplatten der Flaschenhals und daher geht das 
komprimierte Speichern schneller.

Ich habe WinRAR installiert, damit ist tar.gz kein Problem mehr.
Ich versende aber auch nur ZIP, damit es keine Rückfragen gibt.

WinRAR stört sich auch nicht an absoluten Pfaden im Tar-File, es packt 
schön brav im aktuellen Verzeichnis aus und überschreibt nicht woanders 
Dateien.


Peter

von (prx) A. K. (prx)


Lesenswert?

Oliver S. schrieb:
> Nun ja, welchen praktischen Sinn nicht-komprimierte Archive haben, hat
> sich mir noch nie erschlossen. Die braucht niemand, und daher gibt es
> die auf Windows gar nicht erst.

Wie der Name schon sagt: Das war zunächst ein Backup-Programm in 
Verbindung mit Bandlaufwerken. Auf Rechnern, die langsamer komprimierten 
als das Laufwerk Daten durchzog. Die im Unterschied zu cpio geblockte 
Arbeitsweise ist den Bandlaufwerken geschuldet und in seiner heutigen 
Funktion unnötig.

Heute ist dieses Programm in seiner meist gebrauchten Rolle auch deshalb 
nicht umwerfend gut geeignet, da ihm ein Inhaltsverzeichnis mit 
Direktzugriff auf die Einzelteile fehlt. Beim vollständigen Ein- und 
Auspacken ist das egal, aber bei GUI-basierter Arbeitsweise a la 7-zip 
mit Zugriff auf einzelne Files eines grösseren Archivs ist das ziemlich 
unpraktisch. Eine diesen Prozess ebenso negativ beeinflussende 
Gesamtkomprimierung stört dann allerdings auch nicht mehr.

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.