Speicher wird überschrieben?!

OP #3261978
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?
Gast #3261996
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.
OP #3262003
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.
#3262019
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.
OP #3262105
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
Gast #3262129
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
}
#3262169
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
  ....
OP #3263400
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren