Hallo Zusammen,
ich programmiere gerade für einen AVR128DA32.
Hier kann man die Clock Settings nur anpassen wenn vorher der CCP
Register mit einem bestimmten Wert beschrieben wird, und danach
innerhalb von 4 Clockzyklen kann dann die Clock Einstellung geschrieben
werden.
Habe nun bemerkt dass dies mit Optimierung -O0 nicht funktioniert.
Das ASM listing zeigt auch warum. Es vergehen mehr als 4 Zyklen bevor
CLKCTRL_OSCHFCTRLA geschrieben wird.
Meine Frage ist nun warum. Warum wird ohne Optimierung erst ein anderes
Registerpaar mit der Adresse geladen und danach in Z kopiert.
Und d.h. mit O0 kann man die Clocksettings in C nicht umstellen und
müsste evt. händisch ASM Befehle einfügen?
1
CCP=0xD8;
2
CLKCTRL_OSCHFCTRLA=0x24;
1
CCP=0xD8;
2
a7e: 84 e3 ldi r24, 0x34 ; 52
3
a80: 90 e0 ldi r25, 0x00 ; 0
4
a82: 28 ed ldi r18, 0xD8 ; 216
5
a84: fc 01 movw r30, r24
6
a86: 20 83 st Z, r18
7
CLKCTRL_OSCHFCTRLA=0x24;
8
a88: 88 e6 ldi r24, 0x68 ; 104
9
a8a: 90 e0 ldi r25, 0x00 ; 0
10
a8c: 24 e2 ldi r18, 0x24 ; 36
11
a8e: fc 01 movw r30, r24
12
a90: 20 83 st Z, r18
PS:
Mit Optimierung (Os) wird aus den 5 Zeilen vorher um eine Konstante zu
schreiben ein 2 Zeiler:
Gute Frage, wobei ich selbst noch nie Probleme damit hatte. Vielleicht
hat Johann ja recht, dass das AVR-Backend einfach mit der Zeit
vergammelt.
Welchen gcc nimmst Du denn?
Cyblord -. schrieb:> Hier kann man die Clock Settings nur anpassen wenn vorher der CCP> Register mit einem bestimmten Wert beschrieben wird, und danach> innerhalb von 4 Clockzyklen kann dann die Clock Einstellung geschrieben> werden.
Stimmt nicht ganz: 4 Instruktionen.
Cyblord -. schrieb:> Habe nun bemerkt dass dies mit Optimierung -O0 nicht funktioniert.
Sorry, das habe ich jetzt erst gelesen: -O0 schaltet fast alle
Optimierungen ab. Also, was willst Du erwarten. Ab -O oder -O1 ist alles
so wie es sein soll.
Wilhelm M. schrieb:> Cyblord -. schrieb:>> Habe nun bemerkt dass dies mit Optimierung -O0 nicht funktioniert.>> Sorry, das habe ich jetzt erst gelesen: -O0 schaltet fast alle> Optimierungen ab.
Das ist bekannt. Erklärt für mich aber nicht warum hier derart unnötige
Operationen eingefügt werden.
> Also, was willst Du erwarten. Ab -O oder -O1 ist alles> so wie es sein soll.
Ich hätte erwartet dass es für die Zuweisung einer Konstanten an eine
Speicherstelle, auch ohne Optimierung, eine bessere Umsetzung gibt.
Hier ist ja kein Optimierungsbedarf im eigentlichen Sinne. Selbst wenn
kein OUT verwendet werden würde, könnte man mit 3 Instruktionen (Z
Pointer laden + STORE) jede Speicherstelle beschreiben.
Wilhelm M. schrieb:> Ich sehe überhaupt keinen Sinn darin, mit -O0 zu compilieren.
Macht ja nichts. Aber manchmal will oder muss man. Ich finde es nur
interessant das dann die 4 zugebilligten Instruktionen des CCP gerissen
werden.
Cyblord -. schrieb:> Wilhelm M. schrieb:>> Ich sehe überhaupt keinen Sinn darin, mit -O0 zu compilieren.>> Macht ja nichts. Aber manchmal will oder muss man.
Ich will und musste es nie ...
> Ich finde es nur> interessant das dann die 4 zugebilligten Instruktionen des CCP gerissen> werden.
Dieses semantische Constraint ist im backend nicht drin. Wie schon
gesagt: es gammelt vor sich hin und fliegt bald raus.
Wilhelm M. schrieb:> Cyblord -. schrieb:>> Wilhelm M. schrieb:>>> Ich sehe überhaupt keinen Sinn darin, mit -O0 zu compilieren.>>>> Macht ja nichts. Aber manchmal will oder muss man.>> Ich will und musste es nie ...
Das ist sehr schön für dich.
Cyblord -. schrieb:> Macht ja nichts. Aber manchmal will oder muss man. Ich finde es nur> interessant das dann die 4 zugebilligten Instruktionen des CCP gerissen> werden.
Das dich das überrascht zeigt, daß du anscheinend das allerstemal mit
einem AVR und dem gcc dazu zu tun hast.
Diese 4-Zyklen-Absicherung gibts bei allen AVRs für verschiedene
Einstellungen, und das hat der gcc noch nie ohne Optimierung geschafft.
Über das wieso, weshalb, warum zu sinnieren ist zweckfrei, wie alle
solche Fragen darüber, warum ein Compiler etwas so macht, wie er es
macht. Ist halt so.
Und weil das so ist, gibts in der avrlibc dafür Hilfsfunktionen (in
Assembler), die einem diese Sorge abnehmen.
Für die nicht berücksichtigten Fälle muß man sich die dann halt selber
schreiben.
Oliver
Oliver S. schrieb:> Cyblord -. schrieb:>> Macht ja nichts. Aber manchmal will oder muss man. Ich finde es nur>> interessant das dann die 4 zugebilligten Instruktionen des CCP gerissen>> werden.>> Das dich das überrascht zeigt, daß du anscheinend das allerstemal mit> einem AVR und dem gcc dazu zu tun hast.
Beileibe nicht.
> Diese 4-Zyklen-Absicherung gibts bei allen AVRs für verschiedene> Einstellungen, und das hat der gcc noch nie ohne Optimierung geschafft.
Nicht übertreiben. Lange nicht bei allen. Ich arbeite bisher vorwiegend
mit dem ATTiny841. Dort gibts das noch nicht und auch bei keinen der
Vorgänger. Auch nicht bei Megas der gleichen oder Vorgängergeneration.
Das ist ein recht neues Feature der aktuelleren AVRs.
> Für die nicht berücksichtigten Fälle muß man sich die dann halt selber> schreiben.
Was hier auch kein Problem darstellt. Das ist mit 3 Zeilen ASM erledigt.
Cyblord -. schrieb:> Nicht übertreiben. Lange nicht bei allen. Ich arbeite bisher vorwiegend> mit dem ATTiny841. Dort gibts das noch nicht und auch bei keinen der> Vorgänger.
Gibt es bei den xmega-Architekturen
Cyblord -. schrieb:> Auch nicht bei Megas der gleichen oder Vorgängergeneration.> Das ist ein recht neues Feature der aktuelleren AVRs.
Dieses 4 clock cycle Sicherheitsfeature gegen unbeabsichtigtes Setzen
gibt es mindestens beim EEPROM schreiben, Watchdog en/-disablen, Flash
programmieren über SPM, und wer weiß wo sonst noch
Das hat einfach jeder AVR irgendwo, seit dem allerersten Modell.
Oliver
Cyblord -. schrieb:>> Sorry, das habe ich jetzt erst gelesen: -O0 schaltet fast alle>> Optimierungen ab.>> Das ist bekannt. Erklärt für mich aber nicht warum hier derart unnötige> Operationen eingefügt werden.
Er fügt sie nicht zusätzlich ein, sondern optimiert sie nur eben nicht
raus.
>> Also, was willst Du erwarten. Ab -O oder -O1 ist alles>> so wie es sein soll.>> Ich hätte erwartet dass es für die Zuweisung einer Konstanten an eine> Speicherstelle, auch ohne Optimierung, eine bessere Umsetzung gibt.
Was heißt für dich "auch ohne Optimierung eine bessere Umsetzung"? Wenn
man es gegenüber einer direkten 1:1-Umsetzung aus dem C-Code verbessert,
nennt man das "Optimierung".
> Hier ist ja kein Optimierungsbedarf im eigentlichen Sinne. Selbst wenn> kein OUT verwendet werden würde, könnte man mit 3 Instruktionen (Z> Pointer laden + STORE) jede Speicherstelle beschreiben.
CCP ist ein Makro, das einen Integer-Wert in einen Zeiger castet. Genau
das macht der Compiler hier. Er lädt einen Integer-Wert und kopiert ihn
in ein Zeiger-Registerpaar.
Cyblord -. schrieb:> Ich hätte erwartet dass es für die Zuweisung einer Konstanten an eine> Speicherstelle, auch ohne Optimierung, eine bessere Umsetzung gibt.
Ganz einfach: nimm dir die gcc-Quellen, schreib einen Patch, reich den
ein, sorge dafür, daß der angenommen wird, und alles wird gut.
Oliver
Wilhelm M. schrieb:> Wie gesagt, das ist im xmaga-support der avrlibc drin: xmega.h
Ich nutze aber keinen xmega. Ich werde aber mal schauen ob für die
avr128 ein solches Makro auch existiert.
Danke für den Tipp Falk.
Cyblord -. schrieb:> Ich nutze aber keinen xmega.
Doch. Der AVR128DAxxx ist eine xmega4 Architektur.
Benutze einfach das Makro was Du in dem header xmega.h findest, wie oben
schon gesagt.
Wilhelm M. schrieb:> Cyblord -. schrieb:>> Ich nutze aber keinen xmega.>> Doch. Der AVR128DAxxx ist eine xmega4 Architektur.
Also der Hersteller bezeichnet das alles komplett anders.
Es gibt eine AVRxm Architektur (XMEGA). Die AVR128DA sind aber AVRxt
welches der Nachfolger ist.
Hier steht sogar dabei die Anleihen an AVRe (attiny) sind größer.
Wilhelm M. schrieb:> Schau in den specs des gcc nach: avrxmega4 (bezieht sich natürlich nur> auf die CPU)
Danke. Aber ich halte mich an die Specs des Herstellers. Es ist möglich
dass innerhalb des gcc das alles etwas anders heißt oder anders
zusammengefasst ist. Was es nicht unbedingt richtig macht.
Zu behaupten AVR128 wäre im Prinzip XMEGA stimmt aber eben nicht und ist
irreführend.
Cyblord -. schrieb:> Danke. Aber ich halte mich an die Specs des Herstellers. Es ist möglich> dass innerhalb des gcc das alles etwas anders heißt oder anders> zusammengefasst ist. Was es nicht unbedingt richtig macht.
Dann benutzt Du den gcc nicht? Ok, was lamentierst Du dann herum.
Wilhelm M. schrieb:> Cyblord -. schrieb:>> Danke. Aber ich halte mich an die Specs des Herstellers. Es ist möglich>> dass innerhalb des gcc das alles etwas anders heißt oder anders>> zusammengefasst ist. Was es nicht unbedingt richtig macht.>> Dann benutzt Du den gcc nicht? Ok, was lamentierst Du dann herum.
Natürlich nutze ich den. Was mich aber nicht zu falschen Aussagen wie
> Der AVR128DAxxx ist eine xmega4 Architektur.
verleiten könnte.
Vielleicht wolltest du ja sagen:
Der gcc nennt die AVR128 Architektur xmega4.
Wer weiß?
Cyblord -. schrieb:> Also der Hersteller bezeichnet das alles komplett anders.
Das liest sich so, wie eine Unterteilung der VW-Modelle in luftgekühlte
Boxer und wassergekühlte Reihenvierzylinder.
Die Welt hat sich seit dem doch etwas weitergedreht, und die
Modellvielfalt ist in der Realität deutlich komplexer.
Oliver
In dem Zusammenhang (korrektes Timing zwischen zwei Befehlen) hab ich
übrigens auch das umgekehrte Problem schon erlebt: "sei(); sleep();"
müssen direkt aufeinander folgen um Race-Conditions zu vermeiden.
Beides ASM-Statements und klappt ohne Optimierung auch. Dann hatte ich
aber so eine Konstellation[1]:
1
if(...){
2
...
3
sei();
4
sleep();
5
}else{
6
...
7
sleep();
8
}
und der Compiler hat bei -Oirgendwas den "sleep", der in beiden Pfaden
als letzter Befehl vorkommt, zusammengefasst und hinter das if-statement
geschoben. Peng - dem sei() folgte ein Jump zum sleep und damit ist die
Bedingung verletzt und führt irgendwann zu einem Lock-Up.
[1] nicht exakt diese, aber auch CSE basierend mit einem Jump hinter dem
sei.
Cyblord -. schrieb:> Es gibt eine AVRxm Architektur (XMEGA). Die AVR128DA sind aber AVRxt> welches der Nachfolger ist.
Da steht aber auch, dass sie von der Xmega-Architektur abgelitten sind,
und die hatte halt schon immer ihr CCP.
Alternative zu den genannten Makros + Inline-Assembler: schreib dir für
das, wo du CCP anfassen musst, Wrapper-Funktionen, die du in eine eigene
Quelldatei packst und dann mit mehr als -O0 compilierst auch denn, wenn
du für den Rest unbedingt -O0 haben willst.
Jörg W. schrieb:> Da steht aber auch, dass sie von der Xmega-Architektur abgelitten sind,> und die hatte halt schon immer ihr CCP.
In der Tat habe ich das CCP schon unterbewusst auf einem tiny841 benutzt
um das Flash zu beschreiben für einen Bootloader. Für den Schutz
bestimmter Register wird es hier aber noch nicht benutzt.
> Alternative zu den genannten Makros + Inline-Assembler: schreib dir für> das, wo du CCP anfassen musst, Wrapper-Funktionen, die du in eine eigene> Quelldatei packst und dann mit mehr als -O0 compilierst auch denn, wenn> du für den Rest unbedingt -O0 haben willst.
ccp_write_io gibt es ohne Klimmzüge auch für den avr128, somit ich nutze
ich das. Danke für diesen Tipp.