Nö, unerwartet ist das überhaupt nicht.Zitat von s.frings
Es ist ohne weiteres möglich globale Registervariablen zu verwenden.Zitat von s.frings
Das Problem in deinem Code ist, daß das von dir definierte Register nicht global ist. Damit ein Register global ist, müssen
- in allen Module, die die Registervariable verwenden, diese bekannt gemacht werden. Dazu schreibt man die Register-Definition zweckmässigerweise in einen Header
- alle Module, auch die, welche die Variable nicht verwenden, werden mit -ffixed-* übersetzt (gcc). Für eine 16-Bit Registervariable in R2/R3 also -ffixed-2 -ffixed-3. Beachte, daß Bibliotheken nicht mit diesen Schaltern übersetzt wurden. GCC kann alle Register > 2 explizit verwenden, und die Register 0 und 1 verwendet er implizit. Daher kann innerhalb einer Lib-Routine diese Register verwenden.
Um globle Register, die in ISRs verwendet werden, sicher zu verwenden, gibt es also mehrere möglichkeiten:
- Keine Lib-Funktionen verwenden, d.h. keine explizit in die Quelle schreiben.
- Alle explizit aufgerufenen Lib-Funktionen mit SEI/CLI atomar machen
- Eigene Variante der Libs übersetzen mit -ffixed-* wie benötigt
- Verwendung von prologue-saves, epilogue-restores anpassen (libgcc.S anpassen)
- Libs verwenden und sich mit einem grep o.ö. versichern, daß keine der verwendeten Lib-Funktionen auf die Register zugreift.
- Implizit verwendete Lib-Funktionen sollten unkritisch sein. Ausnahme: prologue_saves, epilogue_restores und evtl das setjmp/longjmp-Zeug
Immerhin hast du durch den "Fehler" ein bisschen mehr über die Arbeitsweise eines Compilers gelernt
Übrigens ist es garnicht sooo viel Arbeit, ein eigenes printf zu schreiben.
Disclaimer: none. Sue me.
Ich breche jedoch auch keinen Zacken aus der Krone, wenn ich anstatt eines Register eine Variable im SRAM verwende. Ganz so Performance-Kritisch ist die Sache nämlich nicht.
Lesezeichen