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

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.