Hallo Ich habe in meiner Anwendung(ATMega2560) einige Variablen vom typ int32_t. Diese sind global deklariert: int32_t ActX = 0; int32_t ActY = 0; int32_t ActZ = 0; int32_t DstX = 0; int32_t DstY = 0; int32_t DstZ = 0; int32_t dX = 0; int32_t dY = 0; int32_t dZ = 0; int32_t sX = 0; int32_t sY = 0; int32_t sZ = 0; In einer Timer-ISR(CompareMatchB) rechne ich dann irgendwo: ActX += sX; das geht bis gut solange Actx <= 32536 ist. Wird der Wert überschritten läuft die Anwendung wer weiß wohin. Merkwürdig ist der Wert 32536. Das ist kein besonderer Wert wie 32767, dort könnte man einen Überlauf vermuten. Ändere ich die Deklarationen auf int16_t funktioniert alles. Problem ist aber das meine Werte größer werden können als 65536, deshalb int32_t. Danke für Eure Hilfe Gruß Scotty
Karsten S. schrieb: > In einer Timer-ISR(CompareMatchB) rechne ich dann irgendwo Hast du einen Schutz bei der abfrage eingebaut, damit die ISR die Daten nicht ändert wenn du sie abfragst?
Ich frage ja nicht nur ab, sondern ich will auch ändern. Was meinst Du mit Schutz?
Karsten S. schrieb: > Was meinst Du mit Schutz? Das was im Link steht. Zu Variablen, die aus mehreren Bytes bestehen.
Der GCC führt Rechnoperationen grundsätzlich auf Words aus. Und Words sind beim avr-gcc 16 Bit. Das sorgt für einige gefährliche Situationen. Helfen kann man sich in dem man die Zwischenwerte einer Operation manuell castet.
Anon Y. schrieb: > Der GCC führt Rechnoperationen grundsätzlich auf Words aus. nein auf int - C(++) ist so definiert. > Das sorgt für einige gefährliche Situationen. Helfen kann man sich in > dem man die Zwischenwerte einer Operation manuell castet. ist bei seinem Beispiel aber nicht notwendig. ActX += sX; Das wird mit dem Datentype von ActX gerechnet.
Peter II schrieb: > nein auf int - C(++) ist so definiert. Lassen wir besser die int vs. word Spekulation. Ich bin mir sehr sicher, dass es 16 Bit sind. Die FAQ dazu: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_intpromote
Anon Y. schrieb: > Der GCC führt Rechnoperationen grundsätzlich auf Words aus. So ein Blödsinn, das kann er garnicht. Er muss schon damit vorlieb nehmen, was die Zielarchitektur kann. Und bei einer 8Bit-Zielarchitektur sind das im Allgemeinen auch nur 8Bit-Operationen. Alles, was breiter ist, muss er logischerweise aus den verfügbaren Operationen zusammenbauen. > Das sorgt für einige gefährliche Situationen. Ja. Immer, wenn irgendwas nicht "atomar" bearbeitet werden kann und mehrere Codepfade gleichzeitig (multicore oder multiprocessor) oder zumindest quasi-gleichzeitig (interrupts/multitasking) bearbeitet werden, kann es zu solchen gefährlichen Situationen kommen. > Helfen kann man sich in > dem man die Zwischenwerte einer Operation manuell castet. Nein, das hilft höchstens mal zufällig. Was hingegen sicher hilft, ist, die Zugriffe zwischen den Codepfaden zu synchronisieren. Im Falle AVR mit Interrupts bedeutet das im Kern immer, dass bei Zugriffen aus main() die Interrupts verboten werden müssen, solange die Operation in main() dauert. Zugriffe aus ISRs heraus sind hingegen automatisch geschützt, solange man in den ISRs nicht mit sei() herumhantiert. D.h. für den Fall des TO, dass bezüglich der ISR nur das "volatile" bei der Deklaration der Variablen fehlt. Der Rest des Fehlers steckt in main(). Den dortigen Code hat der TO allerdings nicht gepostet...
Hi, welchen Wert hat sX bei der Addition ? Und was meinst Du mit das Programm läuft irgendwohin ? Ist nur der Inhalt der Variablen ActX anders, als Du erwartest, oder nimmt der Programmablauf wirklich unvorhersehbare Wege ?
Anon Y. schrieb: > Der GCC führt Rechnoperationen grundsätzlich auf Words aus. Und Words > sind beim avr-gcc 16 Bit. C tut zwar so, als ob die Rechnung mindestens in "int" stattfindet. Aber weder muss das im realen Code so sein, noch ist das hier das Problem. > Lassen wir besser die int vs. word Spekulation. Ich bin mir sehr sicher, > dass es 16 Bit sind. Und ich bin mir sehr sicher, dass es per Sprachdefinition "int" ist. Und "int" wiederum mindestens den Wertebereich von 16 Bits umfasst, aber je nach Zielmaschine auch grösser sein kann.
Okay hat sich erledigt. Ich nutze ja auch die Capture-ISR. Im Programmlauf wird dann das ICR1-Register geändert. Dies lief dann über und die andern beiden ISR' wurden nicht mehr ausgeführt. Das passierte genau nach die Variable ActX auf 32536 stand. ActX wurde dann nur noch getestet aber nicht mehr geändert, das passiert normalerweise in der CompareMatchB. Das ICR1 wurde in CompareMatchA geändert. Diese beiden ISR wurden aber nicht mehr angesprungen. Folglich nur noch die Capture-ISR und dort war der Wert bei jedem Aufruf 32536. Grrr. :=( Danke für Eure Hilfe Gruß Scotty
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.