Hi, zusammen, habe ein kleines Problem. In einer Signal-Routine brauche ich einen Zähler, der statisch ist und vorinitialisiert sein soll: static uint16_t counter = 1; Dummerweise ist der bei Programmstart aber eben nicht 1, sondern aktuell 37900, warum auch immer. Im aktuellen Programm ist das nicht so schlimmm, ein zeitgesteuerter Programmteil arbeitet nicht direkt nach dem Einschalten, sondern erst ca. 8 Sekunden später, aber blöd ist das schon und in anderen Projekten undenkbar. Wo liegt da der Fehler und was muss ich anders machen? Danke!
Hallo Dieter! Wo wird denn die Variable deklariert, global oder erst in der ISR? Gruß, Patrick...
Hallo, Patrick, die Variable wird erst in der ISR deklariert. Habe es auch mit anderen ausprobiert, da ist es dasselbe. Kann es sein, dass statische Variablen in ISRs anders behandelt werden? Zur Not kann ich auch eine Init-Routine für jede ISR schreiben und die Variable dann global definieren. Wäre aber nicht so schön. Grüsse, Dieter
Variablen, die erst in einer Funktion deklariert werden, sind ja nicht global zugreifbar. Sie existieren zwar, dürfen aber NUR von der Funktion verwendet werden, die sie angelegt hat. Ich weis jetzt nicht genau, wo Du versuchst, auf diese Variable zuzugreifen, aber es hört sich danach an, als wolltest Du in einem anderen Kontext als der ISR darauf zugreifen! Wenn Du eine globale Variable brauchst, dann muss sie auch global deklariert werden. static sagt nur aus, daß die Variable beim verlassen der Funktion - samt Inhalt - erhalten bleibt. Gruß, Patrick...
P.S.: auch Globale Variablen lassen sich "vorinitialisieren", allerdings macht static int i = 0; keinen Sinn, da sie eh mit 0 initialisiert wird. static int i = 16; macht dagegen schon schon Sinn, wenn man halt i mit einem Startwert von 16 verwenden möchte.
Habe mich wohl falsch ausgedrückt. Ich meinte Folgendes: SIGNAL(xxx) { static uint16_t counter = 1; xxx; } Dabei wird die Variable counter aber NICHT initialisiert. Bei einer "normalen" Funktion wird die Variable beim ersten Aufruf mit dem Wert - hier die 1 - initialisiert. In der ISR bei mir haben die Variable nur irgendwelche wilden Werte, habe das mit mehreren ausprobiert.
Selbstverständlich werden diese Variablen wie alle anderen statischen Variablen initialisiert. Womit hast Du denn festgestellt, daß sie nicht initialisiert würde? Hast Du einen Sourcecode, mit dem man das reproduzieren könnte? Ich sollte mal wieder an Eric Raymonds Artikel erinnern: http://www.catb.org/~esr/faqs/smart-questions.html bzw. dessen deutsche Übersetzung: http://www.lugbz.org/documents/smart-questions_de.html Besonders hier der Abschnitt ``Don't claim you have found a bug.''
Hallo, ich habe in der ISR-Routine die Variable in eine Temp-Variable kopiert und mir auf einem LCD-Display anzeigen lassen. Code werde ich heute abend posten. Und dass der Fehler nicht bei mir liegt, würde ich auch nie behaupten... Habe das jetzt nur zwei Tage lang probiert und bin jetzt wohl problemblind :(
Poste mal den Code, oder zumindest den Teil des Codes, der die beiden Variablen anlegt, den Inhalt kopiert und dann ausgibt.
So, habe mal ein Code-Fragment angehängt: //******************************************** #include <inttypes.h> #include <avr/signal.h> #include <avr/interrupt.h> #include "timer0.h" #include "helper.h" #include "globals.h" #include "keyboard.h" #include "lcd4bit.h" void init_timer0( void ) { TCNT0 = 0x00; OCR0 = 0xFA; TCCR0 |= ( 1<<WGM21 ) | ( 1<<CS01 ); // OutputCompare With Prescaler 8 => 250µs @ 8MHz } // // Timer Interrupt 0 // SIGNAL(SIG_OUTPUT_COMPARE0) { // Output Compare0 Interrupt static uint8_t key_pending; static uint16_t counter = 1, key_counter, test, tt = 422; uint8_t i, key_temp; if( tt != 345 ) { test = counter; tt = 345; } // Increment Counter counter++; // 1s Counter if( counter == 4000 ) { // Update Real Time Clock if( ++clock.second == 60 ) { if( ++clock.minute == 60 ) { if( ++clock.hour == 24 ) { clock.hour = 0; } clock.minute = 0; } clock.second = 0; } counter = 1; } // Keyboard Scan + Debouncing [xxx]; // End Of IRQ } //******************************************** Der Effekt ist, dass aufgrund der Nichtinitialisierung die Tastenfeldabfrage und die Echtzeituhr erst später loslaufen. Im aktuellen Fall ca. 8 Sekunden später, da der Zähler nicht bei 1 startet sondern bei genau 37900.
Ich kann da erstmal keinen offensichtlichen Fehler erkennen. Vielleicht hast Du eine Kollision mit dem Stack? Der Schnipsel genügt leider auch nicht für ein sinnvolles Test-Compile. Davon abgesehen, wenn Du die Variable nicht mit 1 initialisierst, wird sie implizit als 0 initialisiert. Zählweitenbegrenzung stattdessen auf 3999 setzen, schon hast Du 2 Bytes ROM für die Initialwerte gespart. ;-) Andere Falle: eventuell wird Deine ISR auch zu lang? Wenn Du da drin noch keyboard scan + debounce machst, vielleicht bist Du ja schon an Deinen 250 µs ran?
Danke für die Antwort. An eine Stackkollision glaub ich nicht. Ich verbrauche für die Vars und Puffer ca. 500 Byte eines Mega16. Da sollte genug übrig sein. Die ISR ist auch recht kurz. Sie funktioniert ja auch, nur dass sie halt mit einem zu hohem counter-Wert startet und somit erst nach ca. 8 Sekunden das erste Mal in die Echtzeituhr-Routine kommt. Allerdings habe ich es jetzt mit Deinem Tip probiert und die implizite Initialisierung und die Abfrage auf 3999 gemacht - siehe da, es funktioniert! Damit bin ich vorerst glücklich, aber ich wüsste trotzdem, warum es so nicht geht (falls ich mal andere Werte brauch und es nicht umständlich über globale Vars machen möchte). Dankeschön erstmal!
Womit testest Du? Reales Device oder Simulator? Wie erstellst Du die Ladedatei für den Controller bzw. den Simulator? Mir dünkt, daß Du vergißt, die Initialwerte für .data mitzugeben... Die Initialisierung mit 0 funktioniert trotzdem, da die Variable dann im .bss ist und das immer ausgenullt wird beim Programmstart.
Ich benutze eine reale Schaltung. Das Makefile habe ich mit Deinem mfile-Tool erstellt und ich flashe den MC mit Ponyprog (über das Makefile, nach einer hier vor einiger Zeit geposteten Kommandozeile). Ich werde das aber überprüfen, wenn ich am Donnerstag abend zurück bin. Danke schonmal!
Damit sollte eigentlich wirklich alles im grünen Bereich sein. Ggf. würde ich mir das Ganze nochmal komplett angucken, wenn Du gar nicht klarkommst.
P.S. static-Variablen werden nicht auf dem Stack abgelegt. Gruss Christian
Ja, und? Wenn Dein Stack mit dem statisch zugewiesenen Bereich kollidiert, hast Du dennoch `random garbage' in denen drin. Genau darumg ging's ja.
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.