- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 10 von 24

Thema: XC8 inline Assembler

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    53
    Beiträge
    540
    Blog-Einträge
    17
    Zitat Zitat von shedepe Beitrag anzeigen
    Du hast ein #include <xc.h> in deinem File?.
    Ich kann nicht für Siro antworten, aber ich habe für meinen oben geposteten Beispielcode die xc.h als einzigen Header eingebunden.
    Die Fehlermeldungen im Editor kommen bei mir auch. Es ist wohl das normale Verhalten des Preparsers, so steht es zumindest im MPLAB X IDE User's Guide Chap. 9.7.7
    Als Workaround könnte man die Multiline Schreibweise benutzen, allerdings dann ohne die Möglichkeit den Assemblecode zu debuggen
    Code:
    asm("\
        movlw 0x9D;         \
        movwf FSR0L;        \
    delay_a:                \
        decfsz FSR0L,F;     \
        goto delay_a;       \
        nop;                \
    ");
    Ich persönlich mag das mischen von C und ASM nicht. Ich habe bis jetzt inline Assembler gemieden und möchte dabei auch bleiben. Wenn ich um Assembler nicht herum kommen sollte, würde ich lieber das ganze Projekt oder zumindest ein Modul komplett in Assembler machen wollen.
    Geändert von witkatz (12.02.2017 um 19:47 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    So, da bin ich wieder,

    Ich habe auch als "einzigne include Datei XC.h" bei mir drin.

    Jo, Du hast recht witkatz, da steht was im MPLAB UDE User Guide.....Bei mir Kapitel 7.5.2
    Fehler ignorierenm, es wird trotzdem ein Code erzeugt
    Okay, dann ist das nicht nur bei mir so....

    Die Mischung mit Assembler und C ist ja meist nicht erforderlich.
    Ich wuste ja auch nicht, dass es dieses __delay_us Macro gibt.
    Ich hab die Taktzyklen selbst berechnet, Naja ich bin mal ehrlich mit dem Simulator angepasst....

    Die eigentliche Frage mit den Statusbits abfragen bei der asm("xxx") Abfrage bleibt aber eigentlich noch offen.
    Das müste ja auch irgendwie gehen, wenngleich ich das ja jetzt nicht mehr brauche.
    Geändert von Siro (12.02.2017 um 20:22 Uhr)

  3. #3
    Erfahrener Benutzer Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    53
    Beiträge
    540
    Blog-Einträge
    17
    Zitat Zitat von Siro Beitrag anzeigen
    Die eigentliche Frage mit den Statusbits abfragen bei der asm("xxx") Abfrage bleibt aber eigentlich noch offen.
    Bei mir funktionierte es mit
    Code:
    asm("btfss STATUS,2");
    ... weil in dem zu dem PIC dazugehörenden Header pic16fxxx.h der STATUS Register dem inline Assembler per asm("STATUS equ 03h") definiert wird. Dieser Header wird über die xc.h eingebunden und dadrin sind die SFR für den Inline Assembler definiert - aber nicht die Bits. Bei MPASM sind die SFR und die einzelnen Bits in der p16fxxx.inc definiert. Man kann die Definition der Bits für den Inline Assembler ergänzen, dann funktioniert die Zeroflag Abrage auch symbolisch
    Code:
    asm("Z  EQU  0x0002");
    //...
    asm("   btfss STATUS,Z      ");
    Nachtrag:
    Zitat Zitat von Siro Beitrag anzeigen
    Eine definierte Laufzeit, das geht nicht in "C" sondern nur in Assembler...
    Darauf sollte man sich im Inline Assembler nicht verlassen, der vom XC8 compiliert und - wenn man es ihm nicht verbietet - optimiert wird. Ich wollte mal interessenhalber deine erste Delay-Routine als separates ASM Modul einbinden s.Bild und schwups wird die DECF BTFSS Sequenz zu DECFSZ optimiert. Ich habe mich nur gewundert, warum eine ASM Routine, die vorher mit asm() Anweisungen in C genau 1ms gebraucht hat (Simulation für PIC16F88 ), als ASM Modul um 25% schneller läuft. Gut zu wissen, dass XC8 auch innerhalb von ASM optimiert, aber für deterministische Laufzeiten ist das nicht so gut.


    Klicke auf die Grafik für eine größere Ansicht

Name:	MPLAB_SC01.PNG
Hits:	7
Größe:	82,0 KB
ID:	32415
    Geändert von witkatz (13.02.2017 um 13:47 Uhr)

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Gut zu wissen, dass XC8 auch innerhalb von ASM optimiert, aber für deterministische Laufzeiten ist das nicht so gut.
    Upps, das kann natürlich nach hinten losgehen. Wär nicht das erste Mal, dass mir der C-Compiler "wichtigen Code" wegoptimiert
    Auch wenn alle Optimierungen ausgeschaltet werden, sind alle mir bekannten C Compiler der Meinung immer noch was wegzuoptimieren....
    Grausam, aber leider nicht zu ändern. Naja ich war noch nie ein "C" Freund und da hat sich bis heute auch nix dran geändert.
    "C" ver"C"ehnfacht halt die Entwicklungszeit.

    Aber bitte jetzt keine Diskussionen . Das ist ja nur meine persönliche Meinung zu "C"

    Hab nochmal vielen Dank für die Info, damit hätte ich sicher nicht gerechnet, dass der Inline Code auch optimiert wird.
    Geändert von Siro (13.02.2017 um 16:37 Uhr)

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo zusammen,
    ich wollte "mal wieder" etwas Assembler in meinen XC8 Code bringen,
    dafür wollte ich aber keinen neuen Thread öffnen, daher führe ich das mal hier weiter:

    Der XC8 inline Assembler scheint irgendwie überhaupt nicht mit dem XC8-Compiler zu harmonieren.
    Ich kann weder auf Variablen noch auf Konstanten zugreifen, es gibt ständig nur Fehlermeldungen.

    Hier mal ein Auschnitt des Screenshoots: ich hab mal den Fehlermeldungen daneben geschrieben

    Klicke auf die Grafik für eine größere Ansicht

Name:	xc8_inline_2.jpg
Hits:	8
Größe:	60,8 KB
ID:	33294

    Hier ein Ausschnitt des inline Codes:
    Code:
    #define LED_COUNT 24
    unsigned char LedArray[LED_COUNT];
    unsigned char byteCount;
    unsigned char bitCount;
    
    void LedShiftOut(void)
    {
      asm("BANKSEL LedArray");
      asm("LFSR FSR0,LedArray");
    
      asm("BANKSELECT byteCount");
      asm("movlw LED_COUNT");
      asm("movwf byteCount");
    
    asm("ByteLoop:");
      asm("movlw 8");
      asm("movwf bitCount");
      asm("movwi fsr0++");
    
    asm("BitLoop:");
      asm("RRF WREG,F");
      asm("btfss STATUS,Z");
      asm("goto isOne");
    
    asm("isZero:");
      asm("bcf LATA,5"); 
      asm("NOP");
      asm("NOP");  
      asm("goto BitLoop");
      
    asm("isOne:");
      asm("bsf LATA,5");
      asm("NOP");
      asm("NOP");  
      
      asm("decfsz bitCount,F");
      asm("goto BitLoop");
      
      asm("decfsz byteCount,F");
      asm("goto ByteLoop");
      
      // 50us Pause
      
    }
    was mache ich denn falsch ?, das kann doch nicht so kompliziert sein.....

    Es wird mir wieder Mal nix anderes übrig bleiben als den gesamten Code in Assembler zu programmieren.

    [edit]
    auf dei Variablen kann ich evtl. zugreifen wenn ich einen Unterstrich benutze, zumindest meckert der Compiler dann nicht.
    Es bleiben aber noch genug Probleme übrig...
    Geändert von Siro (22.02.2018 um 22:55 Uhr)

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Guten Morgen liebe Gemeinde,

    ich werde mal eine der vielen Fragen konkretisieren:

    Code:
    #define ZAEHLER 8
    
    int main(void)
    { 
     asm("movlw ZAEHLER");   // undefined symbol ZAEHLER
    was ist hier so Besonderes, dass es nicht funktioniert ?

    so funktioniert es ja:
    Code:
    asm("movlw 8");


    Nun habe ich grad etwas Neues ausprobiert und das geht sogar:
    Code:
    // #define ZAEHLER 8   // so geht es nicht 
    
    asm("ZAEHLER EQU 8");   // aber so geht es 
    
    int main(void)
    {
     asm("movlw ZAEHLER");

    Siro
    Geändert von Siro (23.02.2018 um 07:29 Uhr)

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Siro Beitrag anzeigen
    was mache ich denn falsch ?, das kann doch nicht so kompliziert sein.....

    Es wird mir wieder Mal nix anderes übrig bleiben als den gesamten Code in Assembler zu programmieren.
    Was gibt es für einen Grund, hier Assembler zu verwenden? Seitdem es C für die PICS gibt, hab ich kein Assembler mehr verwendet. Und ich kann auch in deinem Code nichts erkennen, daß sich nicht in C formulieren lässt.

    Wenn ich deinen Code richtig verstanden habe, soll er, ein Array von unsigned chars bitweise auf einem Port ausgeben.

    Code:
    #include <xc.h>
    #include <stdint.h>
    
    #define LED_COUNT 24
    uint8_t LedArray[LED_COUNT];
    
    void LedShiftOut(uint8_t *leds, int8_t count) {
        uint8_t one_byte;
        int8_t bit_count;
    
        while (count) {
            one_byte = *leds++; // next Byte
            for (bit_count = 0; bit_count < 8; bit_count++) {
                LATA5 = one_byte & 0x01; // lowest Bit
                one_byte >>= 1;
            }
            count--;
        }
    }
    
    void main(void) {
        LedShiftOut(LedArray, LED_COUNT);
        return;
    }
    Eigentlich ist das Ganze aber eine Aufgabe für das SPI Modul, wobei man MISO und CLK nicht verwendet.

    Und zu deiner Frage mit
    Code:
    #define ZAEHLER 8
    Der Compiler kennt ZAEHLER nicht, alle Zeilen, die mit einem # beginnen, werden vom Präprozessor bearbeitet. Die bekommt der Compiler garnicht zu sehen. Das "#define" tut das Gleiche, was "suchen und ersetzten" in deinem Editor macht, jedesmal vor dem Compilieren.

    Wenn ich lese, was du hier in diesem Thread so schreibst, wirst du mit deinem Ansatz nicht wirklich glücklich werden. Entweder du schreibst alles in Assembler, wozu es IMHO keine Notwendigkeit gibt, oder du programmierst in C. Die Mischung ist eigentlich immer Pfusch und führt am Ende zu unwartbarem Code. Die Arduino-Leute sind noch einen Schritt weiter gegangen und verwenden C++.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Moin Klebwax,
    ersteinmal Danke für deine Mühe und Informationen.

    Im Prinzip hast Du recht, man braucht "meistens" keinen Assembler, wenn man schon in "C" programmiert.
    Aber manchmal gibt es doch einige Ausnahmen.
    Ich möchte die RGB Leds Typ WS2812B ansteuern und die haben/wollen leider ein sehr genaues Timing haben. +/- 150ns laut Datenblatt.
    Da bleibt nicht viel Freiraum für einen "nicht optimierten" C-Code (Free Version )

    Im Prinzip will ich nur die Daten in dem "richtigen" Timing ausschieben, der Rest sollte in "C" sein.
    Auch richtig erkannt, dass man dafür das SPI Interface nehmen könnte, wobei ich hier noch nicht sicher bin ob das
    mit dem Timing hinhaut. Bin mometan noch etwas in der Experimentierphase.

    Generell sollte es aber auch möglich sein, Assembler mit "C" zu mischen und ich bin quasi am erforschen
    wie das am besten oder überhaupt geht. Komme ja auch grad etwas weiter....


    Mit dem Preprocessor ist mir eigentlich klar, aber anscheinend nur "eigentlich"
    Wenn der Preprozssor alle #defines vorher einsetzt bevor er compiliert und/oder assembliert,
    dann müsste die Assemblerzeile doch auch richtig aussehen.

    #define ZAEHLER 8
    sagt aus, daß überall im Code wo ZAEHLER auftaucht die 8 eingetragen wird (wie Du auch geschrieben hast: suchen/ersetzen).
    Erst dann wird compiliert/assembliert und demnach steht doch dann in meiner Assemblerzeile
    anstelle von
    asm("movlw ZAEHLER");
    asm("movlw 8");
    oder habe ich das falsch verstanden ?

    [Edit] mir ist grad ein Licht aufgegangen:
    Ein define wird NICHT ersetzt wenn er in Ausdrücken mit Hochkomma steht.
    Der identifier wird nur ersetzt, wenn er ein Token bildet. Der identifier wird also nicht ersetzt, wenn er in einem Kommentar, in einer Zeichenfolge oder als Teil eines längeren Bezeichners erscheint ...

    Siro

    (Ziel ist es mit einen kleinen 8 Füssler (momentan PIC12F1840) 24 RGB Leds anzusteuern)
    Das gibt es übrigens auch schon fertig in Assembler:
    http://www.picalic.de/PIC2WS2812/picsolution.html
    Geändert von Siro (23.02.2018 um 10:37 Uhr)

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    53
    Beiträge
    540
    Blog-Einträge
    17
    Zitat Zitat von Siro Beitrag anzeigen
    Code:
    ...
    unsigned char LedArray[LED_COUNT];
    
    void LedShiftOut(void)
    {
      asm("BANKSEL LedArray");
    ...
    MPLAB_XC8_C_Compiler_User_Guide.pdf:
    Most C symbols map to an corresponding assembly equivalent.
    ...
    The name of a C function maps to an assembly label that will have the same name, but
    with an underscore prepended. So the function main() will define an assembly label
    _main.
    nach meinem Wissen gilt das für Funktionen als auch für Variablen, also folgendes müsste gehen:
    Code:
    asm("BANKSEL _LedArray");

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Du hast völlig Recht Witkatz, mit dem Unterstrich kann ich auf die Variablen zugreifen
    ebenso auf die Funktionsnamen.
    Bei BANKSEL geht das auch, obwohl der Operand _LedArray dabei sogar in Hochkomma steht.

    Code:
    #define LED_COUNT 24
    unsigned char LedArray[LED_COUNT];
    
    unsigned char count;
    
    void MeineFunc(void)
    { volatile unsigned char x;
      x++;
    }
    
    int main(void)
    {
     asm("movf  _count,W");       // geht Variable laden mit Unterstrich
     asm("movwf _count");         // geht Variable speichern mit Unterstrich
     asm("call _MeineFunc");      // geht Funktionsaufruf mit Unterstrich
     asm("BANKSEL   _LedArray");  // geht mit Unterstrich
    
    // asm("LFSR FSR0,_LedArray");  // geht leider nicht
    Ich werde sicher noch einiges propbieren, das Wochende fängt ja erst an.
    und wünsche Euch allen ein schönes Wochenende und danke, dass ihr meine "Code Eskapaden" ertragt....

Ähnliche Themen

  1. Bascom Inline-Assembler
    Von Che Guevara im Forum Assembler-Programmierung
    Antworten: 64
    Letzter Beitrag: 07.02.2012, 19:00
  2. Inline Assembler
    Von Che Guevara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 01.02.2010, 19:25
  3. AVR GCC inline Assembler
    Von chientech im Forum Assembler-Programmierung
    Antworten: 1
    Letzter Beitrag: 26.09.2009, 16:39
  4. Inline Assembler für Anfänger
    Von 1udo1 im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 25.10.2007, 19:53
  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
  •  

Solar Speicher und Akkus Tests