Da hast da das Übertragen von NULL nicht dabei, nur eine EINS.
Würde ich erstmal ganz einfach machen:
das zweite Beispiel analog.Code:if (Ir_data_tmp & (1<<5)) command_rc5 |= (1<<7) else command_rc5 &= ~(1<<7)
Ich hatte mal Code von Bascom nach WinAVR übertragen. https://www.roboternetz.de/phpBB2/viewtopic.php?t=20209
Bei den einfachen WINAVR-Bitoperationen hatte ich hiermit noch kein Problem:
Zitat von BascomNur wie übertragt man folgendes nach C?Zitat von WINAVR
Ich habe nur den Workaround gefunden:Zitat von Bascom
Zitat von WINAVR
Da hast da das Übertragen von NULL nicht dabei, nur eine EINS.
Würde ich erstmal ganz einfach machen:
das zweite Beispiel analog.Code:if (Ir_data_tmp & (1<<5)) command_rc5 |= (1<<7) else command_rc5 &= ~(1<<7)
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Das mit der NULL ist mir entgangen
Man scheint aber um eine IF ... ELSE und SHIFT nicht herum zukommen.
Das ist irgendwie eine Lücke in WinAVR-C, da der µC in ASM mit SBIC/SBIS und SBI/CBI diese o.g. Bitoperationen direkt unterstützt.
Es ginge schon (scheinbar) mit bit-structuren. Es kommt aber der gleiche Code raus.
SBIC etc. bringt auch nur was, wenn es sich bei den Bitnummern um Literale handelt. Mit Variablen zur Laufzeit ist da auch nix.
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Wo ist da eine "Lücke" in C?
Ist vielleicht etwas umständlich hinzuschreiben, dafür bleibt man bei den Standards:
Sieht doch gut aus, was avr-gcc daraus macht, oder?! sbic/sbis sind eh nur auf einige SFRs anwendbar...Code:extern uint8_t command_rc5, Ir_data_tmp; void foo() { if (Ir_data_tmp & (1<<5)) command_rc5 |= (1<<7); else command_rc5 &= ~(1<<7); }
Und falls das immer noch zu lange ist:Code:foo: lds r24,Ir_data_tmp lds r25,command_rc5 sbrs r24,5 rjmp .L5 ori r25,lo8(-128) rjmp .L7 .L5: andi r25,lo8(127) .L7: sts command_rc5,r25 ret
gibt:Code:void foo() { uint8_t cmd = command_rc5 & ~(1<<7); if (Ir_data_tmp & (1<<5)) cmd |= (1<<7); command_rc5 = cmd; }
Kürzer oder schneller schreibt das niemand.Code:foo: lds r25,command_rc5 andi r25,lo8(127) lds r24,Ir_data_tmp sbrc r24,5 ori r25,lo8(-128) .L5: sts command_rc5,r25 ret
Disclaimer: none. Sue me.
Absolut überzeugend!
@SprinterSB
Womit erzeugt Du diesen ASM-Code (Labels, Variablen-Namen etc)?
AVRStudio erzeugt bei mir auch mit der *.elf nur RAW-ASM...
Den Assembler-Code erzeuge ich mit avr-gcc. avr-gcc erzeugt immer Assembler-Code (zumindest, wenn er compiliert). Du darft ihn eben nicht löschen
(Als Option hilf dazu -save-temps. Leider bekomme ich dann teilweise Linkerfehler zusammen mit -c, die ich noch nicht nachvollziehen konnte; die Objekte scheinen jedoch gleich auszusehen...)
Generell kannst du auf 2 Wegen an den Assembler-Code kommen:
Indem man die Temporär-Dateien nicht löscht (gcc -save-temps), indem man nicht assembliert/linkt (gcc -S) oder indem man assembliert und dem Assembler sagt, daß er bitte dumpen soll. (avr-gcc -Wa,...).
Weiterhin kann man Disassembles erzeugen aus den Objekten (*.o, *.elf), indem man einen Dump macht oder den Linker anweist, es zu tun.
Welches man bevorzugt ist davon abhängig, welche Informationen man will: Intermix zwischen Assembler/C-Quelle? Maschinen-Codes zu den Assembler-Befehlen? Symbolnamen? Variablennamen? etc.
Für obiges Beispiel sieht das dann so aus:
Compiler dumpt Assembler
avr-gcc -S -save-temps -fverbose-asm ...
Assembler dumpt AssemblerCode:.global foo .type foo, @function foo: /* prologue: frame size=0 */ /* prologue end (size=0) */ lds r25,command_rc5 ; cmd, command_rc5 andi r25,lo8(127) ; cmd, lds r24,Ir_data_tmp ; Ir_data_tmp, Ir_data_tmp sbrc r24,5 ; Ir_data_tmp, ori r25,lo8(-128) ; cmd, .L2: sts command_rc5,r25 ; command_rc5, cmd /* epilogue: frame size=0 */ ret /* epilogue end (size=1) */ /* function foo size 11 (10) */ .size foo, .-foo
avr-gcc -c -Wa,-alhd=dump.s ...
objdump erzeugt Dump aus Object (nicht loakatiert):Code:18 .global foo 20 foo: 21 .LFB2: 22 .LM1: 23 /* prologue: frame size=0 */ 24 /* prologue end (size=0) */ 25 .LM2: 26 0000 9091 0000 lds r25,command_rc5 27 0004 9F77 andi r25,lo8(127) 28 .LM3: 29 0006 8091 0000 lds r24,Ir_data_tmp 30 000a 85FD sbrc r24,5 31 .LM4: 32 000c 9068 ori r25,lo8(-128) 33 .L2: 34 .LM5: 35 000e 9093 0000 sts command_rc5,r25 36 /* epilogue: frame size=0 */ 37 0012 0895 ret 38 /* epilogue end (size=1) */ 39 /* function foo size 11 (10) */
avr-objdump -d -S ...
objdump erzeugt dump aus elf (lokatiert)Code:00000000 <foo>: uint8_t command_rc5, Ir_data_tmp; void foo() { uint8_t cmd = command_rc5 & ~(1<<7); 0: 90 91 00 00 lds r25, 0x0000 4: 9f 77 andi r25, 0x7F ; 127 if (Ir_data_tmp & (1<<5)) 6: 80 91 00 00 lds r24, 0x0000 a: 85 fd sbrc r24, 5 cmd |= (1<<7); c: 90 68 ori r25, 0x80 ; 128 command_rc5 = cmd; e: 90 93 00 00 sts 0x0000, r25 12: 08 95 ret
avr-objdump -S ...
Code:0000005c <foo>: uint8_t command_rc5, Ir_data_tmp; void foo() { uint8_t cmd = command_rc5 & ~(1<<7); 5c: 90 91 60 00 lds r25, 0x0060 60: 9f 77 andi r25, 0x7F ; 127 if (Ir_data_tmp & (1<<5)) 62: 80 91 61 00 lds r24, 0x0061 66: 85 fd sbrc r24, 5 cmd |= (1<<7); 68: 90 68 ori r25, 0x80 ; 128 command_rc5 = cmd; 6a: 90 93 60 00 sts 0x0060, r25 6e: 08 95 ret
Disclaimer: none. Sue me.
was für eine Antwort
Ich schlage vor, es in Deinem Artikel einzupflegen:
https://www.roboternetz.de/wissen/index.php/Avr-gcc
Na, der Artikel ist eh schon arg fett...
Disclaimer: none. Sue me.
Hallo Sprinter,Na, der Artikel ist eh schon arg fett...
Das Problem ist, dieser Post geht schnell in der Menge unter, wenn man es später nachschauen will, ist man am suchen, es wäre wirklich schön, wenn Du das ins Wiki aufnehmen könntest [-o< .
Gruß Sebastian
P.S.
Zur Sicherheit habe ich mir alles kopiert
Linus TorvaldSoftware is like s e x: its better when its free.
Lesezeichen