mikrocontroller.net

Forum: Compiler & IDEs FAT16 Problem beim schreiben


Autor: nOOb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich benutze die Fat16 lib von Stephan Busker und habe ein mir sich nicht 
erklärbares Phänomen:


Es wird ein File auf einer SD Karte beschrieben, die am SPI hängt.
MMC Initialisierung gut, auch erste Schreibversuche gut.


Also mein erstes Programm (Atmega128) so ca. so aus (snippet)
int main(void)
{
  sei(); // Interrupt freigeben
  char *teststring = "TEST STRING - TEST STRING\n";
  mmc_init();
  InitFat16();
  File myFile;
  unsigned char filewriting_active=0;
  while(1)
  {
    if(~IO_INPUT & (1 << BUTTON1) && !filewriting_active)
    {
      while(~IO_INPUT & (1 << BUTTON1))
        _delay_ms(100); // warten bis Knopf wieder losgelassen wurde
      
      filewriting_active = 1;
      fopen_((unsigned char*)"test.txt",'a',&myFile);

    }
    else if(~IO_INPUT & (1 << BUTTON2) && filewriting_active)
    {
      while(~IO_INPUT & (1 << BUTTON2))
        _delay_ms(100); // warten bis Knopf wieder losgelassen wurde
      
      filewriting_active = 0;
      fclose_(&myFile);
    }

    if(filewriting_active)
      fputs_(&myFile, teststring);

    _delay_ms(100);
  }

  return (0);
}

*********************************************************



Das Funktioniert tadellos.
Wenn ich jetzt allerdings Code hinzufüge, sind ca. 40 Zeilen, so wird 
der Ausgabestring in der test.txt gelegentlich verzerrt, sodass Zeilen 
geschrieben werden die nicht wir erwartet so:

    TEST STRING - TEST STRING

aussehen, sondern (gelegentlich und unregelmäßig) mal so;

    TEST STRING - TEST STRING,0TEST STRING - TEST STR0NG
    0E,T STRING0 TEST STRING

aussehen.



Jetzt hatt ich schon gedacht, das ich mir den char Zeiger in dem 
zusätzlichen Code verbiege und habe das

      fputs_(&myFile, teststring);

gegen

      fputs_(&myFile, "TEST STRING _ TEST STRING\n");

getauscht, ohne Erfolg mit selbigem Ergebnis.

Compiler meldet, das 12.8% Programmplatz belegt sind und 46.4% Data 
Auslastung

Alles mit AVR-GCC und AVR Studio. Keine Compiler Warnungen (was nix 
heisst schon klar).

Geht mir da irgendwo der interne Ram abhanden?



Gruß
n.

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

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert deine Hardware?
Hast du mal mit dem Oszi deine Pegel auf dem SPI-Bus gemessen?
Hast du da schöne Rechtecke?

> Das Funktioniert tadellos.
> Wenn ich jetzt allerdings Code hinzufüge, sind ca. 40 Zeilen,
> so wird der Ausgabestring in der test.txt gelegentlich verzerrt
Schön wenn wir wissen, wie es funktioniert. Aber viel interessanter sind 
doch die Änderungen, die dazu führen, dass es nicht mehr funktioniert...

Autor: nOOb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, ich geb dir recht, allerdings bin ich grad an der Arbeit und hatte 
das aus dem Kopf geschrieben :-)

Ferner dachte ich, dass eine Änderung, egal wie sie aussihet, nichts mit 
einem:

   fputs_(&myFile,"TEST STRING - TEST STRING\n");

zu tun haben kann.

Ich werde das mal heute Nachmittag nachreichen.

Autor: nOOb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So sieht das ganze komplett aus:
int main(void)
{
  
  sei();
  init();
  hasFix=1;
  DOG_CLR();

  status_record = 0;
  dataRelease = 1;
  TCCR0 |= (1 << CS02) | (1 << CS00);
  TIMSK |= (1 << TOIE0);

  File lFile;

  char datname[12];
  unsigned saveFile=0;
  uint8_t done=0;


  unsigned char x=0;
  unsigned char y=0;
  unsigned char z=0;
  unsigned char v=3;
  
  char hour[3];
  char month[3];
  unsigned char winterzeit=1;
  while (1)
  {
    x=0; y=0; z=0; v=3;
    char incoming[255];
    gps_read(incoming);

    
      
    if(incoming[0] == '$' && incoming[1] == 'G' && incoming[2] == 'P' && incoming[3] == 'G' && incoming[4] == 'G' && incoming[5] == 'A')
      v=1;
    else if(incoming[0] == '$' && incoming[1] == 'G' && incoming[2] == 'P' && incoming[3] == 'R' && incoming[4] == 'M' && incoming[5] == 'C')
      v=0;

    for(x=0; x < 128; x++)
    {  
      if(incoming[x] == 0)
        break;

      if(incoming[x] == ',')
        z++;
    }
  
    if((v==1 && z == 14) || (!v && z == 12) )
    {
  

      if(!v)
      {
        if(incoming[18]=='V')
          hasFix = 0;
        else
          hasFix = 1;

        z = 0;
        y = 0;
        for(x=0; x < 128; x++)
        {  
          if(incoming[x] == 0)
            break;

          if(z == 1 )
          {
            if (y < 2)
              hour[y]=incoming[x];

            gpTime[y] = incoming[x];
            y++;
            if(y == 2 || y==5 )
            {
              gpTime[y] = ':';
              y++;
            }
            
          }
          else if(z == 9)// && incoming[x] != ',')
          {
            if (y > 1 && y < 4 )
              month[y-2]=incoming[x];

            gpDate[y] = incoming[x];
            y++;
            if(y == 2 || y==5 )
            {
              gpDate[y] = '.';
              y++;
            }
            
          } 
          else if(z == 7) // && incoming[x] != ',')
          {
            gpSpeed[y] = incoming[x];
            y++;
          }
          if(incoming[x] == ',')
          {
            z++;
            //if (z==2 || z == 10 || z == 8 )
              y=0;
          }
        }
      
        dtostrf((strtod(gpSpeed, 0) * 1.851), 3, 2, gpSpeed);
        hour[2]='\0';
        month[2]='\0';

        gpTime[8]='\0';
        gpDate[8]='\0';
        gpSpeed[6]='\0';

        unsigned char hr;
        unsigned char mn = atoi(month);

        if (mn > 3 && mn < 11)
          winterzeit = 0;

  

        if (winterzeit)
          hr = atoi(hour) + 1;
        else
          hr = atoi(hour) + 2;

        if (hr > 24)
          hr-=24;
        char ts[3];
        sprintf(ts, "%02d",hr);

        gpTime[0] = ts[0];
        gpTime[1] = ts[1];
    
      }
  
      y=0;
    }  
             


    if (~IO_INPUT & (1 << BT_REC) )
    {
      while (~IO_INPUT & (1 << BT_REC))
        _delay_ms(100);
      
      if(status_record == 0)
      {
        if(mmc_init() != 0)
        {
          DOG_STRING(0, 0, "Karten Fehler!");
          DOG_STRING(0, 1, "ABBRUCH!        ");
          initOK=0;
          _delay_ms(5000);
          DOG_CLR();
        }
        else
        {
          initOK=1;
          InitFat16();
          DOG_STRING(0, 0, "Starte Aufnahme!");
          _delay_ms(500);
          saveFile=0;

          sprintf(datname, "ses_%d.ggp", saveFile);
          
          done=0;

          while (fopen_((unsigned char*)datname,'r', &lFile) && !done)
          {
            fclose_(&lFile);
            saveFile += 1;
            sprintf(datname, "ses_%d.ggp", saveFile);
            if (saveFile >= 254)
            {
              saveFile=0;
              done = 1;
            }
          }
          DOG_CLR();
          DOG_STRING(0, 0, (char*)datname);
          _delay_ms(2000);
          fopen_((unsigned char*)datname,'a',&lFile);

            status_record = 1;
         }

      }
      else if (status_record == 2)
      {
        LED_OFF;
        DOG_STRING(0, 0, "Beende Aufnahme!");
        _delay_ms(500);
        status_record = 0;
        fclose_(&lFile);
        DOG_STRING(0, 0, "                ");
      }        
      
    }
  
    if (~IO_INPUT & (1 << BT_MOD) && status_record == 0)
    {
      while (~IO_INPUT & (1 << BT_MOD))
        _delay_ms(100);

    }

    if (status_record == 2 || status_record == 0)
    {

      if( !y && v!= 3)
      {
        if (status_record == 2)
          fputs_(&lFile, "TEST STRING - TEST STRING - TEST STRING\n", 1);
    
        if(dataRelease)
        {
          DOG_STRING(0,1, gpTime);
          
          DOG_STRING(0,2, gpDate);



        if(hasFix)
            DOG_STRING(9,2, "FIX OK ");
        else
            DOG_STRING(9, 2, "NOK FIX");
        
        if(status_record == 2)
          LED_BLINK;

        DOG_STRING(9,1, gpSpeed);            

        dataRelease = 0;
        }

  
        
      }
    }
    else if (status_record == 1)
    {
      DOG_STRING(0, 0, " Aufnahme aktiv ");
      status_record = 2;
    }
}

Das Programm liest vom UART einkommende Daten von einem Venus6 FLPX, 
diese werden dann geprüft auf Korrektheit und wenn Aufnahme aktiv ist, 
so soll das auf die SD Karte gehämmert werden.

Wie oben beschrieben, ohne die Prüfroutine geht es, mit Prüfroutine 
erscheinen sporadisch "falsche" Zeichen in Output,was aber nicht sein 
kann, da ja der gps output geprüft wird, sollte die Prüfunf fehlschlagen 
so wird auch nichts geschrieben.

In obigem Code Snippet ist dann die Schreibfunktion auch nur mit dem 
"TEST STRING" gedöns ausgeführt, was auch nicht ordentlich funktioniert.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das erste was ich tun würde:
Den Code in Funktionen unterteilen.
In so einer Monsterwurst findet doch kein Mensch mehr Fehler.

Hast du schon alle Arrayzugriffe überprüft, ob du nicht irgendwo hinten 
rausschreibst?

Autor: nOOb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte das vorher in Funktionen hab es wieder alles zusammengepackt 
weil:

der fputs_ Befehl vor Aufruf der Funktionen gut ging, danach sporadisch 
wie beschrieben fehlschlug.


Das erste was ich vermutet hatte war ein Vergleichs Typo, also

incoming[2] = '0' statt incoming[2] == 2

dem war aber nicht so, ausserdem selbst wenn, So wie es jetzt da steht 
(ich schreibe ja einen konstanten String weg) muss es gehen, auch wenn 
ich Array- und, oder Zeigerfehler hätte.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nOOb schrieb:

> dem war aber nicht so, ausserdem selbst wenn, So wie es jetzt da steht
> (ich schreibe ja einen konstanten String weg) muss es gehen, auch wenn
> ich Array- und, oder Zeigerfehler hätte.

Nicht unbedingt.
AUch der Text kommt letztendlich aus dem SRAM. Wenn du einen 
Amoklaufenden Pointer hast, bzw. einen Arrayzugriff out of bounds, 
kannst du dir auch so einen Text zerschiessen.

Autor: nOOb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohh, das war mir gar nicht bewusst, aber es ist natürlich absolut 
logisch. Speicher ist Speicher und bleibt Speicher :-) Ich Dämelack.

Darauf hin hab ich in das Programm einige Überwachungen reingeschrieben 
und auf Array Grenzen explizit geachtet... was soll ich sagen.

Ging dann sofort...



Herzlichen Dank für die Klappse auf den Hinterkopf :-)

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.