Daniel Platte wrote:
> ja,
> den beitrag hatte ich auch schon gelesen.
> was ich noch nicht ganz verstehe ist, das GPIOR0 register liegt im
> bereich der "working register" wo man schnell drauf zugreifen kann, wenn
> ich aber den code so wie oben beschrieben nutze, benutzt der compiler
> den pointer wie einen pointer auf sram...
Klaro, so ist's ja auch auf C-Ebene formuliert und für I/O-Regs bzw IN,
OUT, SBI, CBI, SBIC, SBIS gibt's AFAIK keine Relocs. Wüsst auch garnet
wie man das GCC ohne neue Qualifier beibringen sollte (übliches Problem
bei Harvard-Architektur).
Der Compiler kann nur dann Instruktionen wie IN etc. verwenden, wenn er
die Adresse kennt. Ok? Bei den ersten 2 Beispielen ist die zur
Compilezeit nicht bekannt, erst zur Link-Zeit. Dividier für Dich nochmal
die Schritte auseinander, wie man zu nem hex-File kommt, was da jeweils
gemacht wird und welche Infos man jeweils hat bzw. nicht hat.
1) Präprozess c->i
2) Compile i->s
3) Assemble i->o
4) Link o->elf
5) Hexify elf->hex
> das sind hier wären nur 6 clocks, aber ein ganzes register weg...
>
>
1 | > register unsigned char p asm("r3");
|
2 | >
|
3 | > void foo4 (void){
|
4 | > cb6: a2 e4 ldi r26, 0x42 ; 66
|
5 | > cb8: 3a 2e mov r3, r26
|
6 | > cba: 08 95 ret
|
7 | >
|
>
> der code bringt 9 clocks:
>
>
1 | > #define P (*((unsigned char**) (&TCNT1)))
|
2 | >
|
3 | > void foo (void)
|
4 | > {
|
5 | > *P = 0x42;
|
6 | > }
|
7 | >
|
>
> die anderen oben beschriebenen varianten beide 11 clocks.
>
> es gibt da eine variable die long int ist bei mir und teils 6*10^6 oder
> noch öfter geschrieben wird, da ist der geschwindigkeitszuwachs mit
> einer registrierung in einem register enorm. z.b. von 31 sec auf 26
> sec...
>
Ich vermute mal Du verwendest avr-gcc und avr-binutils.
Falls Du keine (lib-)Funktionen verwendest, die R2-R5 verwenden, kannst
Du die zum Speichern nehmen als globales Register. Da gcc die eh kaum
verwendet, ist's nicht dramatisch.
In einigen lib-Funktionen werden diese Regs jedoch verwendet.
0) Überleg Dir GENAU, was es bedeutet, ein GPR zu einem globalen
Register zu machen!
1) Du übersetzt Dein Projekt mit -ffixed-2 -ffixed-3 -ffixed-4 -ffixed-5
2) Wenn im hex-Dump eins von r2-r5 verwendet wird, geht's so nicht. Evtl
kommt die Verwendung von call-prologues, das ist wiederum ok.
3) Die Variable p kommt in ein globales Register
1 | register unsigned long p asm ("r2");
|
> ps: bei der linker option fehlte eine 0 glaub ich, bei mir läuft das nur
> so: -Wl,--section-start=bar=0x80002B,--defsym=bazz=0x80001E
> (atmega168 bar=GPIOR2 bazz=GPIOR0)
Jo, die VMAs sieht man im map-File und im elf-Dump