mikrocontroller.net

Forum: Compiler & IDEs nur "schrott" nach Variablendeklaration


Autor: Timo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe das Projekt von Simon 
Beitrag "Datenrekorder auf SD-Karte mit mega88" nachgebaut und auf eigene 
Bedürfnisse angepasst. (nur die Main-Routine)

Jetzt gibt es aber in meiner Main-Routine das Problem, dass ich eine 
Variable "sichern" (u08) brauche um einen Zustand zu "merken". 
Deklarieren ok, aber sobald ich diese beschreibe (Wert zuweisen oder 
incrementieren) läuft mein Programm amok, d.h. die gespeicherten Daten 
auf SD haben nichts mehr mit der Realität zu tun!
Ich weiß, das sind dürftige Infos, aber kann man dazu eine 
Fehlerdiagnose geben? Da ich erst seit kurzem mich mit C beschäftige 
gibt es sicher was, dass ich einfach nur übersehen habe.

Der entsprechende Auszug
            //detektiere Schwelle
            u08 sichern=0;
            tx_rdp_Copy=tx_rdp;  // Pointer übernehmen
            
            for (i=0; i<channels; i++) 
            {
              if (((tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1])>SCHWELLWERT_MAX))//||((tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1])<480))
              {
                sichern++;
              }
              tx_rdp_Copy+=2;
              tx_rdp_Copy &= TX_BUF_SIZE-1;
              
            }
Danke vorab!

Timo

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir im C-Lehrbuch deiner Wahl das Kapitel an, in dem die 
Sichtbarkeit/Gültigkeit von Variablen besprochen wird. Also wo es um 
globale und lokale Variablen (static oder auto) geht.

Die Position der Definition (u08 sichern=0;) deutet (#) auf eine auto 
lokale Variable hin. Die Verwendung (sichern++;) und deine Beschreibung 
(um einen Zustand zu "merken) deuten darauf hin, dass du einen 
dauerhaften Speicherplatz willst. Beides beisst sich derzeit.

(#) Tipp: bei Codeausschnitten mindestens die komplette Funktion posten

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

Den Status brauche ich nur in der unmittelbar nachfolgenden if-Abfrage, 
daher ist eine kurze Lebensdauer (nur innerhalb des Main-Blocks) sicher 
angebracht.
Mir scheint es eher so, als ob irgend etwas in Speicher oder Zeiger 
darauf hin verbogen werden - aber das ist mangels ausreichender Kenntnis 
nur eine Deutung....

Timo

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ...tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1]...
ist tx_buf[] ein char-Array?
Falls ja: dann solltest du das auf short casten. Ich bin nicht sicher, 
ob der Compiler das macht (sollte er zwar mit der Konstante 256, aber 
wer weiß)?

> ...tx_buf[tx_rdp_Copy] + 256*(unsigned short)tx_buf[tx_rdp_Copy+1]...
Den Rest macht dann der Compiler...

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest mal den aktuellen Sourcecode posten, bei dem der Fehler 
auftritt. Der Codeauszug oben deckt sich nicht mit deinem ZIP-Archiv.

Autor: Timo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

der Code sollte eigentlich identisch sein - sollte....

Im Anhang wirklich die aktuelle Version.

Nach wie vor gilt der folgende Codeschnipsel als problematisch. Sobald 
die beiden Zeilen auskommentiert sind, läuft das Programm wie vom 
Ursprungsautor gewollt.
u08 sichern=0;
sichern++;
// ********************************************************************************************************            
            //detektiere Schwelle
            u08 sichern=0;
            
            tx_rdp_Copy=tx_rdp;  // Pointer übernehmen
            
            for (i=0; i<channels; i++) 
            {
              if (((tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1])>SCHWELLWERT_MAX))//||((tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1])<480))
              {
                sichern++;
              }
              tx_rdp_Copy+=2;
              tx_rdp_Copy &= TX_BUF_SIZE-1;
              
            }
// *******************************************************************************************************

(der Rest vom Code im Anhang)

Danke!


Timo

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht verwirren lassen. Ich meinte natürlich, diese beiden Zeilen 
auskommentieren

u08 sichern=0;
sichern++;

Danach kommt in meiner Antwort dann der Codeauszug.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Timo
Etwas OT, aber statt deiner selbstgebauten Funktion
   write_number_u32();
könntest du doch
   ltoa();       // long to ascii  verwenden



>Sobald die beiden Zeilen auskommentiert sind
> u08 sichern=0;
Welchen Compiler hast du? Kann der inline Variablendeklarationen 
handhaben? Das ist kein Standard C-Syntax.

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Lothar: ich habe das Programm größtenteils von Simon 
übernommen(Beitrag "Datenrekorder auf SD-Karte mit mega88") und bin noch 
nicht in der Lage, den Code zu optimieren. Ich kämpfe noch (oder schon) 
mit den Erweiterungen. Trotzdem danke für den Hinweis.

Ich nutze das AVR Studio 4.13 SP2 Build 571 mit WinAVR 20080610

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo wrote:
> Nicht verwirren lassen. Ich meinte natürlich, diese beiden Zeilen
> auskommentieren
>
> u08 sichern=0;
> sichern++;
>
> Danach kommt in meiner Antwort dann der Codeauszug.

Kannst du vom Compiler die LSS Dateien mit/ohne obige Zeilen erzeugen 
lassen und posten?

LSS Dateien sind gemischter ASM und C Quellcode. Die Einstellung zur 
Erzeugung der LSS Dateien findest du bei den Projektoptionen von AVR 
Studio.

Autor: Timo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier die LSS-Files. Ich bin mal gespannt, was Du da rauslesen kannst

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Data:        960 bytes (93.8% Full)

Wenn dir da mal nicht einfach nur der Stack überläuft.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo wrote:
> Hier die LSS-Files. Ich bin mal gespannt, was Du da rauslesen kannst

Leider nichts, weil die beiden Dateien nahezu identisch sind.

Unterschiede befinden sich lediglich im Bereich der Debugsymbole aber 
nicht im Bereich des Quellcodes.

Für mich sieht es so aus, als ob beide Male eine Source übersetzt wurde, 
die die untenstehenden Zeilen überhaupt nicht enthält!

Zeilen 524-566 aus main.c:
          else if (channels && sample == channels) {
            adcflag = 0;
            sample = 0;
            if (linebrkneeded) {
              linebrkneeded = 0;
              mmc_write_byte(0x0d);
              mmc_write_byte(0x0a);
            }

// ********************************************************************************************************            
            //detektiere Schwelle
            u08 sichern=0;
            
            tx_rdp_Copy=tx_rdp;  // Pointer übernehmen
            
            for (i=0; i<channels; i++) 
            {
              if (((tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1])>SCHWELLWERT_MAX))//||((tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1])<480))
              {
                sichern++;
              }
              tx_rdp_Copy+=2;
              tx_rdp_Copy &= TX_BUF_SIZE-1;
              
            }
// ********************************************************************************************************

            /*if (time==1)
            {
              for (i=0; i<channels; i++) 
              {
                adc_offset[i*2]=tx_buf[tx_rdp_Copy];
                adc_offset[i*2+1]=tx_buf[tx_rdp_Copy+1];
                tx_rdp_Copy+=2;
                tx_rdp_Copy &= TX_BUF_SIZE-1;
              }
            }*/

            // Schreibe Datenblock
            //if (sichern>0)
            //{
              PORT_LED &= ~PIN_LED;  // kurzer Peak zum "REC"-rausmessen
              PORT_LED &= ~PIN_LED;


Zeilen 3868-3900 aus ...nicht auskommentiert....lss

          else if (channels && sample == channels) {
    157c:  80 91 56 01   lds  r24, 0x0156
    1580:  90 91 61 01   lds  r25, 0x0161
    1584:  88 23         and  r24, r24
    1586:  09 f4         brne  .+2        ; 0x158a <main+0x438>
    1588:  45 c0         rjmp  .+138      ; 0x1614 <main+0x4c2>
    158a:  98 17         cp  r25, r24
    158c:  09 f0         breq  .+2        ; 0x1590 <main+0x43e>
    158e:  5d c0         rjmp  .+186      ; 0x164a <main+0x4f8>
            adcflag = 0;
    1590:  10 92 b1 04   sts  0x04B1, r1
            sample = 0;
    1594:  10 92 61 01   sts  0x0161, r1
            if (linebrkneeded) {
    1598:  22 23         and  r18, r18
    159a:  21 f0         breq  .+8        ; 0x15a4 <main+0x452>
              linebrkneeded = 0;
              mmc_write_byte(0x0d);
    159c:  8d e0         ldi  r24, 0x0D  ; 13
    159e:  7c d2         rcall  .+1272     ; 0x1a98 <mmc_write_byte>
              mmc_write_byte(0x0a);
    15a0:  8a e0         ldi  r24, 0x0A  ; 10
    15a2:  7a d2         rcall  .+1268     ; 0x1a98 <mmc_write_byte>
            }*/

            // Schreibe Datenblock
            //if (sichern>0)
            //{
              PORT_LED &= ~PIN_LED;  // kurzer Peak zum "REC"-rausmessen
    15a4:  28 98         cbi  0x05, 0  ; 5
              PORT_LED &= ~PIN_LED;
    15a6:  28 98         cbi  0x05, 0  ; 5
    15a8:  2e c0         rjmp  .+92       ; 0x1606 <main+0x4b4>


In Zeile 3892 (vor // Schreibe Datenblock) fehlt der komplette 
Anweisungsblock zwischen den beiden // *** oben.

Hast du zum Übersetzen die Optimierung eingeschaltet? tx_rdp_Copy und 
sichern wird ja nur in diesem Block benutzt und der Compiler kann die, 
da hier funktionslos, ersatzlos streichen!

Autor: Timo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich habe nochmals die Sequenz mit "sichern" eingeschalten und 
compiliert. In der LSS-Datei kommt dann der Ausdruck vor.
Der Code jetzt heißt
// ********************************************************************************************************            
            //detektiere Schwelle
            u08 sichern=0;
            
            tx_rdp_Copy=tx_rdp;  // Pointer übernehmen
            
            for (i=0; i<channels; i++) 
            {
              if (((tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1])>SCHWELLWERT_MAX))//||((tx_buf[tx_rdp_Copy]+256*tx_buf[tx_rdp_Copy+1])<480))
              {
                sichern++;
              }
              tx_rdp_Copy+=2;
              tx_rdp_Copy &= TX_BUF_SIZE-1;
              
            }
// ********************************************************************************************************

            /*if (time==1)
            {
              for (i=0; i<channels; i++) 
              {
                adc_offset[i*2]=tx_buf[tx_rdp_Copy];
                adc_offset[i*2+1]=tx_buf[tx_rdp_Copy+1];
                tx_rdp_Copy+=2;
                tx_rdp_Copy &= TX_BUF_SIZE-1;
              }
            }*/

            // Schreibe Datenblock
            if (sichern>0)
            {
              PORT_LED &= ~PIN_LED;  // kurzer Peak zum "REC"-rausmessen
              PORT_LED &= ~PIN_LED;

              while (tx_rdp != tx_wrp) {
                mmc_write_byte(':'); write_number_u32(time);
                for (i=0; i<channels; i++) {
                  mmc_write_byte(9);
                  write_number_u32(tx_buf[tx_rdp]+256*tx_buf[tx_rdp+1]);
                  tx_rdp+=2;
                  tx_rdp &= TX_BUF_SIZE-1;
                }
                
                
                mmc_write_byte(0x0d);
                mmc_write_byte(0x0a);
              }
            }
            else
            {
              // tu was anderes
            }



Inhaltlich nichts geändert zu vorher, außer dass "sichern" ausgewertet 
wird.
Vielleicht kann man jetzt mehr damit anfangen....

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.