- LiFePO4 Speicher Test         
Ergebnis 1 bis 7 von 7

Thema: Compiler ignoriert volatile ?

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076

    Compiler ignoriert volatile ?

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Mehr "volatile" geht wohl kaum und trotzdem "KLAUT" mir der Compiler meinen Code. Wo muss das "volatile" denn hin, damit der compiler meinen Code NICHT rausschmeisst ?????
    Die Funktion "ShiftOut() " welche ich vom Hauptprogramm aufrufe, wird rausgeschmissen, (wegoptimiert)
    wie kann das denn sein ?????
    Wichtig: ANSI-C tauglich


    Code:
    typedef volatile union
    {
      struct
      {
        int data      : 16;
        int reserved0 : 16;
      } bits;
      U32 value;
    } SSP1DR_TypeDef;
    #define LPC_SSP1DR  (* (SSP1DR_TypeDef *)(0x40030008))
    
    
    typedef volatile union
    {
      volatile struct
      {
        volatile int TFE       : 1;
        volatile int TFN       : 1;
        volatile int RNE       : 1;
        volatile int RFF       : 1;
        volatile int BSY       : 1;
        volatile int reserved0 : 27;
      } bits;
      volatile U32 value;
    } SSP1SR_TypeDef;
    #define LPC_SSP1SR (* (volatile SSP1SR_TypeDef *)(0x4003000C))
    
    
    unsigned char data;
    
    void ShiftOut()
    { 
      while (LPC_SSP1SR.bits.BSY) ;   /* wait until BSY becomes zero */
      LPC_SSP1DR.value = data;        /* shift out the data byte */ 
    }
    
    
    int main(void)
    {
      while (1)
      {
        data = 0xAA;
        ShiftOut();
      }
    }
    Compiler: IAR Embedded Workbench 5.4

    fassungslos...
    Siro

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    42
    Beiträge
    2.009
    Wo in dem Code ist die TestFunc()?
    Da die Funktion nicht aufgerufen wird, kanns sein, dass der Linker die einfach nicht linkt. (Im Stil von "Warum was reinpacken, was eh nicht gebraucht wird?")
    #ifndef MfG
    #define MfG

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Upps, entschuldigt, die funktion heisst natürlich "ShiftOut()" nicht TestFunc
    ich hatte sie testweise umbenannt.
    Ja, das wäre okay, wenn ich die funktion nicht aufrufen würde, dürfte er diese auch entfernen.
    Versuche ergaben, wenn ich dieser funktion einen parameter übergebe, dann lässt der Compiler sie auch drin, mit dem gesamten code.

    so zum Beispiel:

    void ShiftOut(char data)
    {
    while (LPC_SSP1SR.bits.BSY) ; /* wait until BSY becomes zero */
    LPC_SSP1DR.value = data; /* shift out the data byte */
    }

    wenn aber data eine lokale variable ist und nicht übergeben wird, schmeisst der Compiler den gesamten Code raus.
    Wenn ich aber auch die variable data als volatile definieren, dann gehts wieder. Er dürfte doch nichts wegoptimieren, da der Zugriff auf das
    Bit "BSY" sich in einer volatile Strukture befindet. Damit muss er dieses doch erst lesen und darf keine Vorentscheidungen treffen und code wegoptimieren. Ich denke mal ich hab irgendwas falsch definiert in meiner Struktur.

    Siro

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    42
    Beiträge
    2.009
    Mach mal void ShiftOut() zu void ShiftOut(void), ob ers dann drin lässt
    #ifndef MfG
    #define MfG

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    mit dem ShiftOut(void) habe ich eben versucht, aber das ändert auch nichts.

    Ich habe aber völlig neue Erkenntnisse gewonnen: P R O B L E M G E L Ö S T
    Ich habe mal die Optimierungen des Compilers verändert und siehe da:

    bei Optimize "Balanced" geht es.
    bei Optimize "Size" geht es.
    bei Optimize "Speed" geht es nicht.

    Aber geht nicht, stimmt hier nicht so ganz.
    Er hat tatsächlich die Funktion ShiftOut rausgeschmissen, aber ....
    Er hat den Code ohne Funktionsaufruf in die main schleife gepackt.
    Das sieht man aber nicht im Source-Code-Fenster. Man wundert sich nur, warum die funktion niemals
    aufgerufen wird und man dort auch keinen Breakpoint setzen kann.
    Wenn man aber im Fenster des Assemblercodes schrittweise simuliert bzw. sich den Code ansieht,
    wird man feststellen, daß dort der Code direkt eingefügt wurde.
    Jetzt leuchtet es mir auch ein, da er auf "Speed" optimieren sollte, kann er natürlich den
    Unterprogrammaufruf sparen, wenn er den Code gleich in die Main Schleife reinpackt.

    Da muss man erstmal drauf kommen. Absolut verwirrend. Zumal man sich nicht dauernd den
    Assemblercode ansieht, welchen der Compiler erzeugt. Zudem habe ich immer nach dem
    Label ShiftOut gesucht, den gibts aber dann garnicht mehr im Assemblercode.
    Das Problem ist also gelöst...
    Ich danke Dir Jaecko, daß Du mich ermutigt hast da nochmal reinzuschauen,
    obwohl ich hätt eh nicht aufgegeben...

    Fazit: wenn man im C-Source-Code plötzlich keine Breakpoints mehr setzen kann,
    bzw. in der Simulation bestimmte Unterprogramme "scheinbar" nicht mehr aufgerufen werden,
    dann hat der Compiler sicher was "umgebaut" an der Ablaufstruktur.
    Dies sieht man aber nicht im Sorce-Code sondern höchstens im Assembler-Code.

    Mein Code hätte also funktioniert, ich hatte es aber garnicht erst ausprobiert, da mir die Softwaresimulation klarmachen wollte, daß meine funktion nie aufgerufen wird. Warum sollte ich also diese Software downloaden

    Schwere Geburt,
    Siro

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    42
    Beiträge
    2.009
    Ok... stimmt... jetzt wo man's liest, wirds klar. Der Compiler darf natürlich Funktionen als "inline" an die Stelle einfügen, wenn es Sinn macht und die eigentliche Funktion nicht verändert. Ein "volatile" ändert daran nichts.
    Beim GCC gibts aber z.B. das Attribut "noinline" für Funktionen, dann wird dem Compiler hier diese Art der Optimierung verboten.

    In diesem Fall war's anscheinend insgesamt schneller, den Funktionsinhalt direkt aufzurufen, als erst mal in die Funktion und danach wieder zurück zu springen.

    Mit Optimierung Debuggen haut eh nur selten hin; also wenn Breakpoints nicht da oder ganz woanders sind, ist das "normal".
    #ifndef MfG
    #define MfG

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Danke für den Hinweis mit dem noinline.
    Ja, Du hast recht, damit kann man diese Optimierung tatsächlich abschalten.
    Mein Compiler von IAR hat dafür das Attribut --no_inline.
    Habe mir das grad mal duchgelesen. Da wird sogar darauf hingewiesen,
    daß es sehr schwierig mit dem Debuggen werden kann.

    Hier der Ausschnitt aus der Hilfe:
    This optimization, which is performed at optimization level High, normally reduces execution time and increases code size. The resulting code might also be difficult to debug.

    Na da bin ich doch wieder ein ganzes Stück weiter gekommen...
    ein schönes Wochenende allseits.
    Siro

Berechtigungen

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

Labornetzteil AliExpress