Forum: Compiler & IDEs Assembler Code in WinAVR einbetten mit Hilfe asm volatile


von Patrick K. (kaplan)


Lesenswert?

Hallo zusammen,

ich wolle meinen bestehenden Code "beschleunigen" in dem ich einige 
passagen in Assembler programmier. Da ich auf C an manchen Stellen nicht 
verzichten moechte, wollte ich nur teilweise den code ersetzen.

in der doku fand ich:
1
asm volatile ("nop");

bzw
1
static inline void delayloop16 (uint16_t count)
2
{
3
    asm volatile ("cp  %A0, __zero_reg__ \n\t"
4
                  "cpc %B0, __zero_reg__ \n\t"
5
                  "breq 2f               \n\t"
6
                  "1:                    \n\t"
7
                  "sbiw %0,1             \n\t"
8
                  "brne 1b               \n\t"
9
                  "2:                    "  
10
                  : "=w" (count)
11
            : "0"  (count)
12
    );                            
13
}

und dann hab ich mal einfach
while (!(SPSR & (1<<SPIF)));    //wait for SPIF
durch dies ersetzt:
1
asm volatile ("loop1:       \n\t"
2
     "sbis spsr,spif  \n\t"
3
"rjmp loop1     \n\t"
4
);

und der Compiler meldet immer folgenden fehler:
C:\DOKUME~1\root\LOKALE~1\Temp/ccQXaaaa.s: Assembler messages:
C:\DOKUME~1\root\LOKALE~1\Temp/ccQXaaaa.s:123: Error: constant value 
required
C:\DOKUME~1\root\LOKALE~1\Temp/ccQXaaaa.s:123: Error: constant value 
required

Hat jemand erfahrung mit In Code Assemlber?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Patrick Kaplan wrote:

> ich wolle meinen bestehenden Code "beschleunigen" in dem ich einige
> passagen in Assembler programmier.

Was macht dich glauben, dass du ihn damit "beschleunigen" könntest?
Hast du dir denn den generierten Code erstmal angeguckt?

Ist natürlich besonders lustig, wenn du anschließend Warteschleifen in
Assembler schreibst.  Schneller warten, oder was? :-)

> in der doku fand ich:
>
1
asm volatile ("nop");

In der Doku solltest du deutlich mehr darüber finden:

http://www.nongnu.org/avr-libc/user-manual/inline_asm.html

> und dann hab ich mal einfach
> while (!(SPSR & (1<<SPIF)));    //wait for SPIF
> durch dies ersetzt:

Hmm, das ist nun ein typischer Fall, bei dem es wohl absolut gar
keinen Sinn hat.  Erstens (siehe oben) verwartest du deine Zeit ja
sowieso nur, zweitens ist der vom Compiler generierte Code wohl durch
nichts zu unterbieten:
1
.global waitspi
2
        .type   waitspi, @function
3
waitspi:
4
/* prologue: frame size=0 */
5
/* prologue end (size=0) */
6
.L3:
7
        sbis 46-0x20,7
8
        rjmp .L3
9
/* epilogue: frame size=0 */
10
        ret
11
/* epilogue end (size=1) */

(compiliert für einen ATmega8)

>
1
> asm volatile ("loop1:       \n\t"
2
>      "sbis spsr,spif  \n\t"
3
> "rjmp loop1     \n\t"
4
> );

Erstens würden sich SPSR und SPIF groß schreiben, nicht klein.
Zweitens kennt der Assembler diese Namen einfach nicht -- avr/io.h
löst sie ja für den C-Compiler auf, nicht für den Assembler.  Du
müsstest also den Compiler (der die Umsetzung ja kennt) anweisen, die
entsprechenden Zahlenkonstanten in das inline asm statement
runterzureichen.

Aber siehe oben, viel Aufwand für keinerlei Effekt.

von Patrick K. (kaplan)


Lesenswert?

Hallo Jörg,
ok so ohne background sieht es ziemlich unsinnig aus. zugegeben... Aber 
das ganz sollte zur beschleunigung dienen. Und zwar wartet der 
Mikrocontroller ja auf das SPIF signal. schneller warten heisst hier 
auch schneller von der änderung des signals mitzubekommen und folglich 
kann ich schneller den wert des Registers auslesen.
ich wollte damit nur meine SPI kommunikation zwischen MASTER und SLAVE 
(jeweils ATMEga16) beschleunigen..siehe anderer Thread:
Beitrag "AVR AtMega 16 schnellste SPI realisierung? Daisy Chain..."

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Patrick Kaplan wrote:

> Aber
> das ganz sollte zur beschleunigung dienen.

Es hilft eben nur nichts, wenn der compilergenerierte Code bereits
minimal ist.  Da ist nichts mehr dran zu optimieren.

``Never start optimizing before you have profiled it.''

> siehe anderer Thread:

Hmm, ich kann dir aus eigener Erfahrung sagen, dass Microcontroller
ziemlich miserable SPI-Slaves sind.  SPI ist ein Schieberegister und
lässt sich damit am besten mit schieberegisterartiger Hardware
implementieren.  Das Dilemma für einen Software-Slave ist, dass er
keinerlei Möglichkeit hat, dem Master anzuzeigen, ob er schon bereit
ist fortzufahren -- anders als z. B. bei I²C, bei dem der Slave den
Master ,,bremsen'' kann, wenn er noch nicht so weit ist.

von Patrick K. (kaplan)


Angehängte Dateien:

Lesenswert?

Jörg Wunsch wrote:

> Das Dilemma für einen Software-Slave ist, dass er
> keinerlei Möglichkeit hat, dem Master anzuzeigen, ob er schon bereit
> ist fortzufahren -- anders als z. B. bei I²C, bei dem der Slave den
> Master ,,bremsen'' kann, wenn er noch nicht so weit ist.

unn das problem hab ich mithilfe eines SHakehands prinzip geloest 
(zusaetzliche leitung von slave zum master um BUSY Status zu vermitteln.
das ganze geht wunderbar. aber wenn ich da oszi anschau dann wundere ich 
mich dass zwischen den einzelnen Byte bloecken noch so viel platz ist. 
und da hab ich mir gedacht, das kann nur am lahmen code liegen... wobei 
die aktivierung von CODE OPTIMIZATION schon einiges gebracht hat... aber 
vielleicht lass ich es auch so und schau ob die datenuebertragung 
reicht. C gefaellt mir sowieso besser ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Errm, wenn du natürlich ohne Optimierung baust, brauchst du dich über
nichts zu wundern...  Das hatte ich stillschweigend vorausgesetzt.

von JojoS (Gast)


Lesenswert?

eine gute Inline ASM Erläuterung findet sich bei den Robotern:
http://www.roboternetz.de/wissen/index.php/Inline-Assembler_in_avr-gcc

von Patrick K. (kaplan)


Lesenswert?

ok so langsam klappt das ganze aber wenn ich die Code optimierung von 
WINAVR auf "-03" einstelle, bringt das ganze schon keinen spuerbaren 
vorteil mehr...

anscheinend ist mein C-Code schon einfach genug :)


immerhin kann ich jetzt meine Zeitkriterien nun gut einhalten.


vielen dank

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.