Forum: Mikrocontroller und Digitale Elektronik Speicher wird überschrieben?!


von Peter M. (allforone)


Lesenswert?

Hallo Freunde,
bei meiner Anwendung wird irgendwie der Speicher überschrieben...
1
// Variablen ---------------------------------------------------------------------------------------
2
static int sbufferpos = 0;
3
byte buffer[33];
4
5
// Prototypen --------------------------------------------------------------------------------------
6
void BefehlsbufferErstellen(int takt);
7
void SendeBuffer(byte b[]);
8
9
// Main --------------------------------------------------------------------------------------------
10
void main(void) {
11
12
    spi_init();
13
    spi_setMode(Master, FallingEdge, LeadingEdge, MSBfirst);
14
    spi_selectChip(true);
15
    BefehlsbufferErstellen(27);
16
    spi_enableInterrupt(true);
17
  
18
      for(;;)
19
      {     
20
          __RESET_WATCHDOG();
21
      }  
22
   } 
23
24
25
// Interruptroutinen ---------------------------------------------------------------------------------
26
__interrupt VectorNumber_Vspi1 void ISR_SPI() {
27
    
28
           if((SPI1S&(SPI1S_SPRF_MASK)) == 0) {
29
           } 
30
           else{
31
              SPI1S;
32
              SPI1D;
33
           }
34
           if((SPI1S&(SPI1S_SPTEF_MASK)) == 0){  
35
           } 
36
           else{
37
                
38
                if(sbufferpos>33) {
39
                 sbufferpos = 0;
40
                 spi_enableInterrupt(false);
41
                } else{
42
                spi_enableInterrupt(false);
43
                SendeBuffer(buffer); 
44
                sbufferpos = sbufferpos + 1;
45
                spi_enableInterrupt(true);
46
                }
47
            }
48
}
49
// Funktionen -------------------------------------------------------------------------------------
50
void SendeBuffer(byte b[]) {
51
52
__RESET_WATCHDOG();
53
spi_sendData(b[sbufferpos]);
54
}

Nach dem sbufferpos auf 20 ist, wird er in der Funktion SendeBuffer() 
überschrieben und erhält dann den Wert 537.

Diese beiden Fehlermeldungen erhalte ich dazu:

Error: At location 031B -
Error: Attempt to use invalid or uninitialized memory


Jemand eine Idee, wie man das beheben kann?

von Peter II (Gast)


Lesenswert?

Jan R. schrieb:
> Jemand eine Idee, wie man das beheben kann?

kann es sein das du in buffer[33] versuchst zu schreiben?

> if(sbufferpos>33) {
sieht mir sehr danach aus.

von Uwe (Gast)


Lesenswert?

> Nach dem sbufferpos auf 20
Aber Hexadezimal also 0x20. Und nach 0x20 heißt also 0x21=33 dezimal.
Du hast aber ein Array gemacht das 33 groß ist also von 0-32 und mit
> if(sbufferpos>33)
bekommst du ein true erst wenn du schon bei 34 bist.

von Peter M. (allforone)


Lesenswert?

Erstmal vielen Dank für die Antwort.

Der Fehler tritt schon vorher auf.
sbufferpos = 19, dann beim nächsten SendeBuffer() wird sbufferpos = 537.
Dabei bin ich also noch nicht bei buffer[33].

Edit: Gerade eure Antworten erst verstanden...ja die verschiedenen 
Zahlensysteme, ich teste es gleich mal.

Edit2: Habe es gerade getestet und die Bedingung in der Schleife mal auf 
27 gesetzt. Der gleiche Fehler passiert, auch wieder beim gleichen 
CPU-Taktzyklus. Außerdem habe ich geschaut, der Wert 20 der für 
sbufferpos angezeigt wird, ist schon in dezimaler Schreibweise.

von Karl H. (kbuchegg)


Lesenswert?

Nichts desto trotz ist das hier
1
                if(sbufferpos>33) {

der erste Fehler. Also korrigier den mal.

Und damit dir das nicht nochmal passiert
1
                if(sbufferpos > sizeof(buffer) - 1) {
oder
1
                if(sbufferpos >= sizeof(buffer)) {


Und wer weiß, wie oft die die um 1 zu große bufferpos in deinem 
restlichen Programm noch verwendest.

von Peter M. (allforone)


Lesenswert?

Habe es geändert. Aber der Fehler bleibt gleich. Es ist einfach 
mysteriös...

von Karl H. (kbuchegg)


Lesenswert?

Jan R. schrieb:
> Habe es geändert. Aber der Fehler bleibt gleich. Es ist einfach
> mysteriös...

Dann zeig dein Programm und wir helfen dir auch die anderen Stellen zu 
finden, an denen du ausserhalb des (eines anderen) Arrays zugreifst.

von Peter M. (allforone)


Lesenswert?

Ok werde ich machen.
Hier nochmal eine genaue Fehlerbeschreibung:
Erst wird die Interruptroutine öfter hintereinander normal aufgerufen.
Dann ist sbufferpos = 19
Dann wird hier:
1
                if(sbufferpos > sizeof(buffer) - 1) {
2
                 sbufferpos = 0;
3
                 spi_enableInterrupt(false);
4
                } else{
5
                spi_enableInterrupt(false); //GENAU HIER
6
                SendeBuffer(buffer); 
7
                sbufferpos = sbufferpos + 1;
8
                spi_enableInterrupt(true);
9
                }

bei spi_enableInterrupt(false);
plötzlich sbufferpos auf 25 gesetzt.

Dann:
1
void SendeBuffer(byte b[]) {
2
3
__RESET_WATCHDOG();
4
spi_sendData(b[sbufferpos]);
5
6
}

Nachdem __Reset_WATCHDOG(); ausgeführt wurde ist sbufferpos = 537 und 
dann kommt der Fehler von oben:

Error: At location 031B -
Error: Attempt to use invalid or uninitialized memory

von Peter M. (allforone)


Angehängte Dateien:

Lesenswert?

Hier nochmal der komplette Code.

von Patrick M. (op_ruffy)


Lesenswert?

Jan R. schrieb:
> static int sbufferpos = 0;

probier's mit static volatile int sbufferpos = 0;

von NurEinGast (Gast)


Lesenswert?

Deine Funktion  BefehlsbufferErstellen(int takt) wird nirgends benutzt ?
Ist nicht der Grund für Dein Problem - aber bist Du Dir sicher, dass das 
der Sourcecode ist ?

von jibi (Gast)


Lesenswert?

> if(sbufferpos > sizeof(buffer) - 1) {
>                 sbufferpos = 0;
>                 spi_enableInterrupt(false);
>                } else{
>                spi_enableInterrupt(false); //GENAU HIER
>                SendeBuffer(buffer);
>                sbufferpos = sbufferpos + 1;
>                spi_enableInterrupt(true);
>                }
>

kann man vereinfachen zu:
1
spi_enableInterrupt(false); 
2
if(sbufferpos > sizeof(buffer) - 1) {
3
                 sbufferpos = 0;
4
} 
5
  else
6
{
7
   SendeBuffer(buffer); 
8
   sbufferpos++;
9
   spi_enableInterrupt(true);
10
}

von Karl H. (kbuchegg)


Lesenswert?

Patrick M. schrieb:
> Jan R. schrieb:
>> static int sbufferpos = 0;
>
> probier's mit static volatile int sbufferpos = 0;

Das ist schon ein guter Hinweis.
Noch besser ist es allerdings zusätzlich, das hier
1
void SendeBuffer(byte b[]) {
2
3
__RESET_WATCHDOG();
4
spi_sendData(b[sbufferpos]);
5
6
}
zu ändern. Wozu da einen Pointer übergeben, wenn sowieso nur 1 Byte 
gesendet wird?
1
void SendeBuffer(byte b)
2
{
3
  __RESET_WATCHDOG();
4
  spi_sendData(b);
5
}


und beim Aufrufer dann:
1
  ....
2
  SendeBuffer( buffer[sbufferpos] ); 
3
  ....

von Peter M. (allforone)


Lesenswert?

Beide bzw. alle drei Änderungen übernommen.
Fehler bleibt ähnlich, nach ca. 20 Durchläufen der ISR wird sbufferpos 
auf einen sehr myteriösen Wert gesetzt.

Als Fehlercode kommt jetzt:

Error: At location 004F -
Error: Attempt to use unimplemented (--) memory.

von Peter M. (allforone)


Lesenswert?

Einen neuen Aspekte habe ich festgesetllt.
Es wird nicht nur die Variable sbufferpo überschrieben, sondern das 
Array byte buffer[] zuvor auch schon. Langsam bei jedem Interrupt via 
SPI.
Es fängt von hinten an, bis dann irgendwann auch Position 0 
überschrieben wird. Danach wird sbufferpos mit einem komischen Wert 
überschrieben und dann wahrscheinlich oben drüber noch mehr, wodurch der 
Fehler dann letztendlich ausgelöst wird.

von Peter M. (allforone)


Lesenswert?

Ich kann den Post nicht bearbeiten, daher ein weiterer Post.
Ich benutze keine Hardware, sondern einen Simulator am PC.
Eventuell ist das noch ein wichtiges Detail.

Vielleicht ist es ähnlich wie hier beschrieben...
https://community.freescale.com/thread/48121
Was meint ihr?

von Uwe (Gast)


Lesenswert?

Hört sich an als wenn der Stack in deinen Variablenspeicher rein rennt.

von Peter M. (allforone)


Lesenswert?

Wie kann man dieses Problem beheben?

Fehler hat sich verändert zu:
Error: Attempt to execute from unimplemented (--) ROM.

von Peter M. (allforone)


Lesenswert?

Held!!
Du hast Recht. Die Interruptroutine ist rekursiv und ruft sich immer 
wieder selber auf, dadurch wird der Stack zu voll... Danke!! Mal schauen 
wie ich es jetzt umschreibe.

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.