Forum: Compiler & IDEs Warum muss der Pointer im Interrupt dran glauben?


von hahgeh (Gast)


Lesenswert?

Hallo,

Es geht um ein Programm auf einem LPC2141 compiliert mit arm-gcc.

Ich benutze das USB Interrupt. In einer Endlosschleife frage ich ab, ob 
durch ein Interrupt ein neuer Befehl empfangen wurde, dieser Befehl wird 
dann mittels puts() über UART ausgegeben.

main(){
U8 *zptr;
int cnt;
U8 * pointer;
while(1){
  if(serio_get_command(&pointer)!=2){
    zptr=ans;
    while(*pointer!=EOT){
      putchar(*pointer);
      pointer++;
      cnt++;
    }
  }
}
}

Das Problem:
Wenn in der while-Schleife ein weiteres Interrupt auftritt, ist mein 
pointer an einer ganz anderen Stelle als er sein sollte, und es wird 
zwangsweise Müll ausgegeben.

Mit static U8 * pointer funktioniert alles wunderbar. Aber bei einer 
Interruptroutine ist doch eigentlich kein static notwendig. Dann müßte 
man ja alle Variablen static deklarieren.

Der Pointer oder der Speicherinhalt wird auch nicht im interrupt 
geändert. Das cnt zählt auch ganz normal weiter.

Hab ich vielleicht bei der Interrupteinstellung was falsch gemacht? Ich 
habe mich sehr stark am Beispiel von Martin Thomas orientiert.

MfG hahgeh

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wer alloziert denn den Speicher, auf den pointer zeigt?  (Und wer
gibt ihn wieder frei, wenn er nicht mehr gebraucht wird?)

von hahgeh (Gast)


Lesenswert?

Naja,

der Speicher ein 400-Byte-Feld wird in einer includierten Datei global 
(also static) alloziiert und in einem Interrupt wird darauf zugegriffen, 
aber der Zugriff findet nur außerhalb des 'if' statt. Freigegeben wird 
der Speicher nie denke ich, weil er ja static ist.

Der pointer wird beim Aufruf der serio_get_command() Methode auf den 
Anfang des Feldes gerichtet.

Ich habe zwaar keinen richtigen Debugger aber laut Consolendebug wo ich 
in der inneren Schleife die letzten beiden Stellen des pointer 
ausgegeben habe, zählt er folgender maßen:
02, 03, 04,(hier kommt das Interrupt), 00, 01, 02, ...

von Codesucher (Gast)


Lesenswert?

Schau mal in Zeile 10 des Interrupts nach, wahrscheinlich liegt da der 
Fehler.

von Peter D. (peda)


Lesenswert?

Solange keiner serio_get_command kennt, bleibt das hier ne Raterunde 
ohne Effekt.

Immer diese Krümel-Posterei und alles-aus-der-Nase-ziehen müssen.


Was ist daran so schwer zu verstehen, daß bei Softwareproblemen immer 
etwas fehlerfrei und warnungsfrei compilierbares geschickt werden muß ?


Peter

von hahgeh (Gast)


Angehängte Dateien:

Lesenswert?

Ok, dann schicke ich einfach nochmal alles. Ich dachte nur es handelt 
sich um ein allgemeinen dummen Fehler oder ein bekanntes Problem.

Dazu gehört noch die LPCUSB.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Naja, das ist immer noch kein vollständiges Projekt und damit erst recht 
nicht kompilierbar. Die LPCUSB könnte man sich ja noch besorgen, das 
raubt mir jetzt allerdings zu viel Zeit ;)
Ausserdem erhalte ich als erste Fehlermeldung folgende:
1
make: *** No rule to make target `Utils/swi_handler.S', needed by `Utils/swi_handler.o'.  Stop.
2
3
Compilation exited abnormally with code 2 at Thu Feb 01 10:31:10

Damit ist das Projekt dann erst recht nicht vollständig...

von hahgeh (Gast)


Angehängte Dateien:

Lesenswert?

Oh die swi_handler.S habe ich wohl versehentlich beim manual-clean 
beseitigt.

Ich probiers nochmal...

Jetzt müßte es aber gehen, sogar LPCUSB ist noch dabei :)

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

hahgeh wrote:
>[...]
> Mit static U8 * pointer funktioniert alles wunderbar. Aber bei einer
> Interruptroutine ist doch eigentlich kein static notwendig. Dann müßte
> man ja alle Variablen static deklarieren.
>[...]

Hm, ich kann da jetzt auf Anhieb auch nichts wirklich falsches finden, 
aber für mich hört sich das nach 'nem zerhackten Stack an. Der - in 
diesem Fall - wesentlichste Unterschied zwischen 'U8 * pointer;' und 
'static U8 * pointer;' ist nämlich der, daß das 'static' dafür sorgt, 
daß 'pointer' nicht auf dem Stack landet.

HTH...

von Karl H. (kbuchegg)


Lesenswert?

> aber für mich hört sich das nach 'nem zerhackten Stack an.

Ditto.
Beim Durchschauen ist nichts aufgefallen.

zerhackter Stack ensteht meist durch
* Array Zugriff ausserhalb der Array Grenzen (out of bounds)
* Pointer 'in the wood'
* Return type mismatch zwischen Protoyp und tatsächlicher
  Funktion

> ist nämlich der, daß das 'static' dafür sorgt,
> daß 'pointer' nicht auf dem Stack landet.

Und nur um das ganz klar zu stellen:
Auch wenn es scheinbar das Problem beseitigt: Es löst
nicht das Problem. Das Problem ist nach wie vor im Code
nur siehst man es zur Zeit nicht. Aber wie alle Probleme
wartet es nur darauf, erneut zuzuschlagen :-)

von hahgeh (Gast)


Lesenswert?

> zerhackter Stack ensteht meist durch
> * Array Zugriff ausserhalb der Array Grenzen (out of bounds)
> * Pointer 'in the wood'
> * Return type mismatch zwischen Protoyp und tatsächlicher
>   Funktion

Ist damit gemeint, dass solche Fehler in ganz anderen Fehlern in ganz 
anderen Variablen und Funktionen resultieren können?

Ich befürchte mal ja. Dann muss ich wohl nochmal den ganzen Code 
durchforsten, ich hoffe nicht den aus der LPCUSB.

> * Pointer 'in the wood'

Dürfte eigentlich nur gefährlich sein, wenn auf die Stelle wo der 
Pointer hinzeigt auch zugegriffen wird, oder? Ansonsten ist es ja nur 
ein willkürlicher Wert an irgendeiner Speicherstelle, der vor sich 
hinwartet.

> * Return type mismatch zwischen Protoyp und tatsächlicher
>   Funktion

Bei sowas müßte doch eigentlich eine Compilerwarnung kommen.

Danke ersmal

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Möglicherweise geht Dir einfach nur der RAM aus!?

von Stefan (Gast)


Lesenswert?

Wieviele Interrupts kommen denn auf dem fraglichen Interruptvektor an?

In irq.h steht was zu NESTED_INTERRUPT drin. Mir sieht der Code dort so 
aus, als ob, ein Zerschiessen des Stacks verhindert werden soll und ein 
Zerschiessen des Stacks passt gut zu deiner Fehlerbeschreibung.

von Karl H. (kbuchegg)


Lesenswert?

hahgeh wrote:
>> zerhackter Stack ensteht meist durch
>> * Array Zugriff ausserhalb der Array Grenzen (out of bounds)
>> * Pointer 'in the wood'
>> * Return type mismatch zwischen Protoyp und tatsächlicher
>>   Funktion
>
> Ist damit gemeint, dass solche Fehler in ganz anderen Fehlern in ganz
> anderen Variablen und Funktionen resultieren können?

Ja.
Solche Fehler sind extrem unangenehm zu finden.

>> * Pointer 'in the wood'
>
> Dürfte eigentlich nur gefährlich sein, wenn auf die Stelle wo der
> Pointer hinzeigt auch zugegriffen wird,

Ja klar. Das ist damit gemeint

  *pPtr = irgendwas;

und pPtr hat einen völlig falschen Wert.

>> * Return type mismatch zwischen Protoyp und tatsächlicher
>>   Funktion
>
> Bei sowas müßte doch eigentlich eine Compilerwarnung kommen.

Nicht unbedingt. Wenn der Compiler immer nur eines von beiden
sieht, entweder Protoyp oder Funktion, aber nie beides gemeinsam,
....

von hahgeh (Gast)


Lesenswert?

:-) ich habe den Fehler gefunden, danke nochmal.

Und zwar hatte es wirklich etwas Stacküberlauf (zerhackter Stack) und 
Nested Interrupts zu tun.

In dem Startup code sind immer nested interrupts eingestellt. Deshalb 
(so vermute ich) wird während der Abarbeitung des Interrupts in den 
supervisor mode geschaltet.
Für den supervisor mode hatte ich aber nur 128 Byte Stack eingestellt, 
was für diese aufwändige Interruptroutine wohl zu wenig war.
Wenn ich jetzt den Stack für den supervisor mode auf 512 Byte stelle, 
oder den Startupcode so verändere, dass nested interrupts ausgeschaltet 
sind und im irq mode weitergearbeitet wird (welcher sowieso schon 512 
Byte Stack eingestellt hatte), dann funktioniert alles wunderbar.

Vielleicht kann ich ja die Interrupt Routine auch noch etwas optimieren, 
um Speicher zu sparen.

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.