- Akku Tests und Balkonkraftwerk Speicher         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 65

Thema: Bascom Inline-Assembler

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Ich kann ja nur vermuten. Bascom macht ja ein implizites "Casting" auf die Zielvariable (word), d.h. er wählt zum Registerladen die "X" -Methode.
    dann hätt man aber erwarten können
    Code:
     LDI XL,0x61
     LDI XH,0x00
     LD   r24,X            
     CLR R25
    ' ab nun wäre "B" ein gecastetes WORD (R24/R25), und Bascom müsste sich nicht mehr drum kümmern.
    Das geschieht aber auch wieder nicht. Er muss jedesmal doch wieder dran denken, dass "B" eigentlich nur ein Byte ist

    Nun, was soll's
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von PicNick Beitrag anzeigen
    Nun, was soll's
    Hab's Mark geschrieben, mal sehen was draus wird.

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Hallo,

    erstmal danke für die Erklärungen. Ich habe jetzt mal alles, was ich als nicht relevant empfinde, auskommentiert und wollte euch fragen, obs so passt oder ob man noch was optimieren kann? V.a. gehts um möglichst wenige Taktzyklen.
    Code:
    Isr_int0:
    
    push r16                                                    'sichere r16
    
    Push r10
    'Push r11
    Push r24
    Push r26
    'Push r27
    
    lds r16 , {channel}                                         'lade channel in r16
    cpi r16 , 6                                                 'vergleiche r16 mit 6
    brlo _lower                                                 'springe, wenn kleiner
    rjmp _out_of_range                                          'sonst springe nach _out_of_range
    _lower:                                                     '_lower Label
    cpi r16 , 1                                                 'vergleiche r16 mit 1
    brge _higher                                                'springe, wenn größer gleich
    rjmp _out_of_range                                          'sonst springe nach _out_of_range
    _higher:                                                    '_higher Label
    '######################################################################################################################################
    '######################################################################################################################################
    'Ldi R26 , 0x46
    'Ldi R27 , 0x00
    Ld R24 , X
    'Ldi R26 , 0x3f
    'Ldi R27 , 0x03
    Ld R10 , X+
    'Clr R11
    Ldi R26 , 0x15
    'Ldi R27 , 0x03
    Lsl R10
    'Rol R11
    Add R26 , R10
    'Adc R27 , R11
    St X + , R24
    Clr R24
    St X , R24
    '######################################################################################################################################
    '######################################################################################################################################
    _out_of_range:                                              '_out_of_range Label
    ldi r16 , 6                                                 'lade 6 in r16
    !out tcnt0 , r16                                            'schreibe r16 in timer0
    lds r16 , {channel}                                         'lade Channel in r16
    inc r16                                                     'erhöhe Channel um 1
    sts {channel} , r16                                         'lade r16 in Channel
    
    'Pop r27
    Pop r26
    Pop r24
    'Pop r11
    Pop r10
    
    pop r16                                                     'stelle r16 wieder her
    
    Return
    Vielleicht fällt euch ja noch was auf, anderfalls wäre es nett, wenn ihr mir ein OK gebt.

    Btw: Bascom Version ist 1.11.9.5

    Vielen Dank & Gruß
    Chris

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Wäre besser, du stelltst dein ganzes Programm da rein. Man kann sonst die Variablen-Adressen nicht verifizieren. Ausserdem, wenn du Zyklen sparen willst, gibt's da ein paar Vorschläge.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Das ganze Programm ist der Quadrocopter Quellcode von Willa. Leider kann ich ihn nicht hier reinstellen, weil er zu lang ist.
    gibt's da ein paar Vorschläge.
    Wo ist den da? Hier im Thread?

    Gruß
    Chris

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    "DA" ist momentan in meinem Hirn
    Geht darum, dass die 1:1 Übertragung von Bascom ---> Assembler natürlich nicht das Gelbe vom kolumbus ist.

    Nun, wenigstens die (relevanten) Variablen definitionen würd' ma schon noch gerne sehen.
    Oder sind das genau die vom 1.Post ?

    Und worum geht's eigentlich ? Durchschnitt von 6 Messungen ?
    Geändert von PicNick (23.12.2011 um 14:07 Uhr)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Definitionen sind (glaube ich) die vom ersten Post:
    Code:
    Dim Empf(5) As Word  
    Dim Channel As Byte
    Hm, das ist mir durchaus klar, aber ich kann nicht den ganzen Code nach ASM übersetzen; Trotzdem möchte ich die ISR "etwas" verschnellern. Momentan (also reines Bascom) sinds 162 Takte, das ist zulange.
    Worum gehts?
    Mit dieser ISR wird das Summensignal des Empfängers eingelesen (und näturlich mithilfe des Timer0). Es gibt 5 relevante Kanäle, die die Software benötigt. Durchschnittsberechnungen sind keine vorhanden. Hier nochmal der orignale Code:
    Code:
    Getreceiver:                                                'falling edge detection
    If Channel > 0 And Channel < 6 Then                         'fill empf(1-5)
      Empf(channel) = Timer0
    End If
    Timer0 = 6                                                  'preload for 4.096 ms
    Incr Channel                                                'if no falling edge was detected for a longer period, channel will increase above 11
    
    Return
    (wie gesagt von Willa)
    Diesen möchte ich auf ASM umschreiben. Habs auch schon mal so gemacht:
    Code:
    Isr_int0:
    
    push r16                                                    'sichere r16
    
    lds r16 , {channel}                                         'lade channel in r16
    cpi r16 , 6                                                 'vergleiche r16 mit 6
    brlo _lower                                                 'springe, wenn kleiner
    rjmp _out_of_range                                          'sonst springe nach _out_of_range
    _lower:                                                     '_lower Label
    cpi r16 , 1                                                 'vergleiche r16 mit 1
    brge _higher                                                'springe, wenn größer gleich
    rjmp _out_of_range                                          'sonst springe nach _out_of_range
    _higher:                                                    '_higher Label
    '######################################################################################################################################
    '######################################################################################################################################
    Empf(channel) = Timer0
    '######################################################################################################################################
    '######################################################################################################################################
    _out_of_range:                                              '_out_of_range Label
    ldi r16 , 6                                                 'lade 6 in r16
    !out tcnt0 , r16                                            'schreibe r16 in timer0
    lds r16 , {channel}                                         'lade Channel in r16
    inc r16                                                     'erhöhe Channel um 1
    sts {channel} , r16                                         'lade r16 in Channel
    
    pop r16                                                     'stelle r16 wieder her
    
    Return
    Das waren glaube ich 43 Takte, was auch schon deutlich besser ist. (Als Nosave INT) Aber da geht doch noch mehr, oder nicht?

    Gruß
    Chris

    EDIT:
    Bei dem letzten Code habe ich vergessen, die Register, die Bascom für die Anweisung "Empf(channel) = Timer0" braucht, zu sichern. Das sind R10, R11, R24, R26, R27.
    Das macht dann nochmal 5(Register) * 2(Push&Pop) * 2(Takte pro Befehl) = 20 Takte mehr.
    Geändert von Che Guevara (23.12.2011 um 15:04 Uhr)

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    ...ob man noch was optimieren kann?
    Eher richtig machen, weniger "optimieren".
    1) Warum glaubst Du, dass XL/XH nicht durch anderen Code verändert wird ? Du lädst X nicht in der ISR, sondern addierst nur fleissig dazu, das geht so gar nicht.

    2) Anderer Code wird nicht mehr arbeiten, wenn Du XL/XH verwendest ohne den beim ISR-Eintritt zu sichern, XH kann verändert werden, wenn eine Bytegrenze überschritten wird.

    3) Du kannst Dir nur sparen das Carry per ADC auf XH aufzuaddieren, wenn Du sicher bist, dass die absolute SRam-Adresse des Arrays vom Compiler nicht an eine Bytegrenze gelegt wird. Beispiel für Word:
    Index 1: HB/LB = &h01 &hFC
    Index 2: &h01 &hFE
    Index 2: &h02 &h00

    4) SREG wird nicht gesichert.

    Abschließend vielleicht noch die Frage an Dich, warum ich Dir denn eigentlich Beispiele geschrieben habe, wenn Du die weitestgehend ignorierst ?
    Geändert von MagicWSmoke (23.12.2011 um 16:12 Uhr)

  9. #9
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    so, soweit möglich getestet:

    Besonderheiten:
    "dummy" dient nur dazu, damit Bascom bei "Loadadr" keinen Index verlangt, verbraucht aber keinen Platz (Overlay) . könnte man auch anders machen, however.
    "channel" Bascom verlangt Index 1-5. das ist aber ungünstig zu rechnen. Besser 0-4 . man braucht dadurch nur auf > 4 ( >= 5) zu prüfen


    Code:
     
    Dim Empf(5) As Word
    Dim Dummy As Byte At Empf Overlay
    Dim Channel As Byte
     
    Getreceiver:                                                'falling edge detection
       $asm
       PUSH  r24
       PUSH  r25
       PUSH  XL
       PUSH  XH
       !IN   r24, SREG
       PUSH  r24
       LDS   r24, {channel}                                     ' channel 0-4 ( Bascom 1-5)
       CPI   r24, 5                                             ' >= 5 --> skipped
       BRSH  _out_of_range
       LSL   r24                                                ' * 2 (wordlength)
       CLR   r25                                                ' clear  (r24 kann ja nicht grösser als 8 werden)
       Loadadr Dummy , X                                        ' addr Empf(0)  
       ADD   XL, r24                                            ' addr Empf + 2*channel
       ADC   XH, r25
       !IN    r24, TCNT0                                        ' timer0
       ST    X+ , r24                                           ' empf(channel) = timer0
       ST    X  , r25
    _out_of_range:
       LDS   r24, {channel}                                     ' channel 0-4 ( Bascom 1-5)
       INC   r24
       STS   {channel}, r24
       LDI   r24, 6
       !OUT  TCNT0, r24
       POP   r24
       !OUT  SREG, r24
       POP   XH
       POP   XL
       POP   r25
       POP   r24
           $end Asm
    Return
    Anders und vermutl. besser geht' sicher auch

    Ein bisschen kann man noch sparen, wenn "empf" komplett im adressbereich < 256 liegt.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Hallo,

    erstmal danke für das Beispiel!
    @MagicWSmoke:
    Ich habe deine Beispiele keinesfalls ignoriert, nur ist es für mich nicht leicht, das zu verstehen. Ich habs mir mehrfach angesehen, nur bin ich eben mit dieser ASM-Denkerei noch nicht so vertraut.
    @Picture:
    Vielen Dank! Ich werde deinen Code testen, auch auf die Taktzahl werde ich achten. Melde mich dann wieder, wenns funktioniert.

    Gruß & Vielen Dank
    Chris

    EDIT:
    Habs gerade im Simulator getestet, mit der Return-Anweisung braucht die komplette ISR (wenn Channel zw. 1 und 5) nur 48 Takte. Das ist im vergleich zu den anfänglichen ca 160 Takten nur ein Viertel. Später, oder auch morgen, werde ich das dann mal auf den Quadro flashen und mal schaun, obs funktioniert.

    EDIT2:
    Habs gerade getestet, irgendetwas funktioniert nicht. Wenn ich das Programm flashe (mit NUR veränderter ISR, Dummy-Variable und NOsave) blinken schon die LEDs anders, sie zeigen wahrscheinlich einen Fehelrcode.
    Geändert von Che Guevara (23.12.2011 um 17:20 Uhr)

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Inline Assembler
    Von Che Guevara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 01.02.2010, 19:25
  2. AVR GCC inline Assembler
    Von chientech im Forum Assembler-Programmierung
    Antworten: 1
    Letzter Beitrag: 26.09.2009, 16:39
  3. Inline Assembler für Anfänger
    Von 1udo1 im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 25.10.2007, 19:53
  4. Inline Assembler - Register
    Von s.o. im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 02.08.2007, 20:26
  5. Parameterübergabe bei Inline-Assembler
    Von ogni42 im Forum C - Programmierung (GCC u.a.)
    Antworten: 21
    Letzter Beitrag: 30.03.2006, 13:32

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen