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
Wer alloziert denn den Speicher, auf den pointer zeigt? (Und wer gibt ihn wieder frei, wenn er nicht mehr gebraucht wird?)
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, ...
Schau mal in Zeile 10 des Interrupts nach, wahrscheinlich liegt da der Fehler.
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
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.
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...
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 :)
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...
> 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 :-)
> 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
Möglicherweise geht Dir einfach nur der RAM aus!?
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.
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, ....
:-) 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.