Forum: Compiler & IDEs FAT16 Problem beim schreiben


von nOOb (Gast)


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)
1
int main(void)
2
{
3
  sei(); // Interrupt freigeben
4
  char *teststring = "TEST STRING - TEST STRING\n";
5
  mmc_init();
6
  InitFat16();
7
  File myFile;
8
  unsigned char filewriting_active=0;
9
  while(1)
10
  {
11
    if(~IO_INPUT & (1 << BUTTON1) && !filewriting_active)
12
    {
13
      while(~IO_INPUT & (1 << BUTTON1))
14
        _delay_ms(100); // warten bis Knopf wieder losgelassen wurde
15
      
16
      filewriting_active = 1;
17
      fopen_((unsigned char*)"test.txt",'a',&myFile);
18
19
    }
20
    else if(~IO_INPUT & (1 << BUTTON2) && filewriting_active)
21
    {
22
      while(~IO_INPUT & (1 << BUTTON2))
23
        _delay_ms(100); // warten bis Knopf wieder losgelassen wurde
24
      
25
      filewriting_active = 0;
26
      fclose_(&myFile);
27
    }
28
29
    if(filewriting_active)
30
      fputs_(&myFile, teststring);
31
32
    _delay_ms(100);
33
  }
34
35
  return (0);
36
}

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



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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

von nOOb (Gast)


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.

von nOOb (Gast)


Lesenswert?

So sieht das ganze komplett aus:
1
int main(void)
2
{
3
  
4
  sei();
5
  init();
6
  hasFix=1;
7
  DOG_CLR();
8
9
  status_record = 0;
10
  dataRelease = 1;
11
  TCCR0 |= (1 << CS02) | (1 << CS00);
12
  TIMSK |= (1 << TOIE0);
13
14
  File lFile;
15
16
  char datname[12];
17
  unsigned saveFile=0;
18
  uint8_t done=0;
19
20
21
  unsigned char x=0;
22
  unsigned char y=0;
23
  unsigned char z=0;
24
  unsigned char v=3;
25
  
26
  char hour[3];
27
  char month[3];
28
  unsigned char winterzeit=1;
29
  while (1)
30
  {
31
    x=0; y=0; z=0; v=3;
32
    char incoming[255];
33
    gps_read(incoming);
34
35
    
36
      
37
    if(incoming[0] == '$' && incoming[1] == 'G' && incoming[2] == 'P' && incoming[3] == 'G' && incoming[4] == 'G' && incoming[5] == 'A')
38
      v=1;
39
    else if(incoming[0] == '$' && incoming[1] == 'G' && incoming[2] == 'P' && incoming[3] == 'R' && incoming[4] == 'M' && incoming[5] == 'C')
40
      v=0;
41
42
    for(x=0; x < 128; x++)
43
    {  
44
      if(incoming[x] == 0)
45
        break;
46
47
      if(incoming[x] == ',')
48
        z++;
49
    }
50
  
51
    if((v==1 && z == 14) || (!v && z == 12) )
52
    {
53
  
54
55
      if(!v)
56
      {
57
        if(incoming[18]=='V')
58
          hasFix = 0;
59
        else
60
          hasFix = 1;
61
62
        z = 0;
63
        y = 0;
64
        for(x=0; x < 128; x++)
65
        {  
66
          if(incoming[x] == 0)
67
            break;
68
69
          if(z == 1 )
70
          {
71
            if (y < 2)
72
              hour[y]=incoming[x];
73
74
            gpTime[y] = incoming[x];
75
            y++;
76
            if(y == 2 || y==5 )
77
            {
78
              gpTime[y] = ':';
79
              y++;
80
            }
81
            
82
          }
83
          else if(z == 9)// && incoming[x] != ',')
84
          {
85
            if (y > 1 && y < 4 )
86
              month[y-2]=incoming[x];
87
88
            gpDate[y] = incoming[x];
89
            y++;
90
            if(y == 2 || y==5 )
91
            {
92
              gpDate[y] = '.';
93
              y++;
94
            }
95
            
96
          } 
97
          else if(z == 7) // && incoming[x] != ',')
98
          {
99
            gpSpeed[y] = incoming[x];
100
            y++;
101
          }
102
          if(incoming[x] == ',')
103
          {
104
            z++;
105
            //if (z==2 || z == 10 || z == 8 )
106
              y=0;
107
          }
108
        }
109
      
110
        dtostrf((strtod(gpSpeed, 0) * 1.851), 3, 2, gpSpeed);
111
        hour[2]='\0';
112
        month[2]='\0';
113
114
        gpTime[8]='\0';
115
        gpDate[8]='\0';
116
        gpSpeed[6]='\0';
117
118
        unsigned char hr;
119
        unsigned char mn = atoi(month);
120
121
        if (mn > 3 && mn < 11)
122
          winterzeit = 0;
123
124
  
125
126
        if (winterzeit)
127
          hr = atoi(hour) + 1;
128
        else
129
          hr = atoi(hour) + 2;
130
131
        if (hr > 24)
132
          hr-=24;
133
        char ts[3];
134
        sprintf(ts, "%02d",hr);
135
136
        gpTime[0] = ts[0];
137
        gpTime[1] = ts[1];
138
    
139
      }
140
  
141
      y=0;
142
    }  
143
             
144
145
146
    if (~IO_INPUT & (1 << BT_REC) )
147
    {
148
      while (~IO_INPUT & (1 << BT_REC))
149
        _delay_ms(100);
150
      
151
      if(status_record == 0)
152
      {
153
        if(mmc_init() != 0)
154
        {
155
          DOG_STRING(0, 0, "Karten Fehler!");
156
          DOG_STRING(0, 1, "ABBRUCH!        ");
157
          initOK=0;
158
          _delay_ms(5000);
159
          DOG_CLR();
160
        }
161
        else
162
        {
163
          initOK=1;
164
          InitFat16();
165
          DOG_STRING(0, 0, "Starte Aufnahme!");
166
          _delay_ms(500);
167
          saveFile=0;
168
169
          sprintf(datname, "ses_%d.ggp", saveFile);
170
          
171
          done=0;
172
173
          while (fopen_((unsigned char*)datname,'r', &lFile) && !done)
174
          {
175
            fclose_(&lFile);
176
            saveFile += 1;
177
            sprintf(datname, "ses_%d.ggp", saveFile);
178
            if (saveFile >= 254)
179
            {
180
              saveFile=0;
181
              done = 1;
182
            }
183
          }
184
          DOG_CLR();
185
          DOG_STRING(0, 0, (char*)datname);
186
          _delay_ms(2000);
187
          fopen_((unsigned char*)datname,'a',&lFile);
188
189
            status_record = 1;
190
         }
191
192
      }
193
      else if (status_record == 2)
194
      {
195
        LED_OFF;
196
        DOG_STRING(0, 0, "Beende Aufnahme!");
197
        _delay_ms(500);
198
        status_record = 0;
199
        fclose_(&lFile);
200
        DOG_STRING(0, 0, "                ");
201
      }        
202
      
203
    }
204
  
205
    if (~IO_INPUT & (1 << BT_MOD) && status_record == 0)
206
    {
207
      while (~IO_INPUT & (1 << BT_MOD))
208
        _delay_ms(100);
209
210
    }
211
212
    if (status_record == 2 || status_record == 0)
213
    {
214
215
      if( !y && v!= 3)
216
      {
217
        if (status_record == 2)
218
          fputs_(&lFile, "TEST STRING - TEST STRING - TEST STRING\n", 1);
219
    
220
        if(dataRelease)
221
        {
222
          DOG_STRING(0,1, gpTime);
223
          
224
          DOG_STRING(0,2, gpDate);
225
226
227
228
        if(hasFix)
229
            DOG_STRING(9,2, "FIX OK ");
230
        else
231
            DOG_STRING(9, 2, "NOK FIX");
232
        
233
        if(status_record == 2)
234
          LED_BLINK;
235
236
        DOG_STRING(9,1, gpSpeed);            
237
238
        dataRelease = 0;
239
        }
240
241
  
242
        
243
      }
244
    }
245
    else if (status_record == 1)
246
    {
247
      DOG_STRING(0, 0, " Aufnahme aktiv ");
248
      status_record = 2;
249
    }
250
}

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.

von Karl H. (kbuchegg)


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?

von nOOb (Gast)


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.

von Karl H. (kbuchegg)


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.

von nOOb (Gast)


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 :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.