Hallo Ich habe ein Programm in Bascom geschrieben. In dem Programm springe ich per Interrupt in eine ISR. Da die ISR möglichst kurz sein sollte, habe ich die ISR mit "nosave" deklariert, d.h. Bascom speichert keine Register wenn es in die ISR springt. Ich möchte nun die Register, die in der ISR benötigt werden, manuell mit PUSH/POP speichern und wiederherstellen. Jetzt meine Frage: kann ich in Bascom irgendwo nachschauen, welche Register in der ISR belegt werden ?
Michael L. schrieb: > Ich habe ein Programm in Bascom geschrieben. In dem Programm springe ich > per Interrupt in eine ISR. Da die ISR möglichst kurz sein sollte, habe > ich die ISR mit "nosave" deklariert, d.h. Bascom speichert keine > Register wenn es in die ISR springt. Ich möchte nun die Register, die in > der ISR benötigt werden, manuell mit PUSH/POP speichern und > wiederherstellen. > > Jetzt meine Frage: kann ich in Bascom irgendwo nachschauen, welche > Register in der ISR belegt werden ? Wenn man das könnte, dann macht "nosave" keinen Sinn, denn dann kannst du dem Compiler den Job gleich ganz überlassen. Kann man (oder vielmehr: der Compiler) das nicht, dann weiß er es nicht und wird es dir dementsprechend auch nicht sagen können. "nosave" macht nur irgendeinen Sinn, wenn du die ISR in Assembler schreibst. So einfach ist das.
Natürlich geht das, nämlich im Simulator oder AVR Studio Disassembler. Im Simulator werden die Register rot markiert, allerdings wohl nur wenn sich etwas ändert. Im AVR Studio sieht man welche Register in der ISR Benutzt werden. Der Compiler ist dazu zu faul und sichert fast alle Register, fast alle. Beispiel: $asm push R10 push R11 push R16 push R21 push R24 push R25 push R26 push R27 IN R24,$3F PUSH R24 $end Asm hier die ISR $asm POP R24 Out $3f , R24 pop R27 pop R26 pop R25 pop R24 pop R21 pop R16 pop R11 pop R10 $end Asm
Fox Mulder schrieb: > Natürlich geht das, nämlich im Simulator oder AVR Studio Disassembler. > Im Simulator werden die Register rot markiert, allerdings wohl nur wenn > sich etwas ändert. Im AVR Studio sieht man welche Register in der ISR > Benutzt werden. Der Compiler ist dazu zu faul und sichert fast alle > Register, fast alle. Zu faul würde ich so nicht sagen. Das Problem ist halt, wenn in der ISR irgendwelche Dinge aufgerufen werden, die im BASCOM Code einein Einzeiler darstellen. Zb per USART ein Zeichen verschicken. Dann müssen je nachdem ob Hardware-USART benutzt wird oder Software-USART andere Register gesichert werden. Von daher ist das nicht unbedingt trivial durchzuführen, je nachdem wie die BASCOM Internals tatsächlich funktionieren.
vielen dank erstmal Das Problem ist, wenn ich "nosave" weglasse, und das speichern der Register dem Compiler überlasse, kann ich in der ISR nichtmehr auf Variablen zugreifen. Deshalb wollte ich das manuell machen
Karl Heinz Buchegger schrieb: > Zu faul würde ich so nicht sagen. Doch, genauer gesagt es wurde absichtlich weggelassen und "nosave" eingeführt. Die Befehle bedienen sich in allgemeinen immer den selben Registern, allerdings kann man auch eigene Libs einbinden und dort alle möglichen Register verwenden. Daher bliebe nur eine Analyse der ISR, das war dem Entwickler wohl zu aufwendig. Michael L. schrieb: > kann ich in der ISR nichtmehr auf > Variablen zugreifen. Das geht normalerweise ohne Probleme, aber wie so oft, ohne Code bleibt nur die Glaskugel.
Michael L. schrieb: > und das speichern der > Register dem Compiler überlasse, kann ich in der ISR nichtmehr auf > Variablen zugreifen Das halte ich für Unsinn. Warum sollte man dann nicht mehr auf Variablen zugreifen können? Zeig mal den Code, welcher angeblich nicht funktuoiniert. Zur Info: BASCOM kann entweder alle Register sichern oder eben keine. BASCOM besitzt bis heute leider noch keine Registeroptimierung. Deshalb sind viele BASCOM Programme langsamer als ein C Äqivalent, ansonsten macht auch BASCOM effizienten Code. Gruß
BASCOM User schrieb: > BASCOM kann entweder alle Register sichern oder eben keine. Es werden nicht alle Register gesichert, "nur" diese: 0-5, 7, 10-11, 16-31 Naja, sind schon fast alle.
Also hier der Code. Das Ganze ist ein Attiny85 der als I2C Slave arbeitet. Das Start und Ovf interrupt wird verwendet, und dementsprechend gibt es eine Start ISR und eine Ovf ISR. Wenn ich nun im Hauptprogramm irgendwelche Berechnungen durchführen will, kommt manchmal was falsches raus, je nachdem wen gerade ein interrupt dazwischen greift.
habe mal mit dem Simulator versucht die Register ausfindig zu machen. wenn ich in die OVF ISR springe, ändert sich lediglich R16, R20, R23, R24
Michael L. schrieb: > Wenn ich nun im Hauptprogramm irgendwelche Berechnungen > durchführen will, kommt manchmal was falsches raus, je nachdem wen > gerade ein interrupt dazwischen greift. Das klingt aber eher nach einem Problem mit atomarem Zugriff. Interrupts während der Berechnung sperren?
@troll Problem mit atomarem Zugriff ist natürlich auch möglich. Wie meinst du das genau mit dem sperren der interrupts ? einfach vor der berechnung "disable Interrupts" und nach der berechnung "Enable Interrupts" ? wenn jetzt genau während der berechnung ein Interrupt auftreten würde, wird dies erst beim einschalten der Interrupts behandelt ? @Fox Mulder Stack ? wird der nicht von Bascom automatisch definiert ?
Michael L. schrieb: > Wie meinst du das genau mit dem sperren der interrupts ? einfach vor der > berechnung "disable Interrupts" und nach der berechnung "Enable > Interrupts" ? ja. > wenn jetzt genau während der berechnung ein Interrupt > auftreten würde, wird dies erst beim einschalten der Interrupts > behandelt ? Ja. Der Interrupt wird durch setzen des entsprechenden I-Flags (ich rede nicht vom I-Flag in SREG!) gespeichert und nach enable Interrupts (welches das I-Flag im SREG setzt) ausgeführt. Doof ist nur wenn die Berechnung so lange dauert dass der gleiche Interrupt währenddessen mehr als einmal auftritt...
Hallo Habe nun das ganze mit interrupts aus- und einschalten versucht. Habe aber trotzdem gelegentlich eine fehlberechnung. Lasse ich das ein- und ausschalten der interrupts weg, und sichere stattdessen in der ISR die register, habe ich ebenfalls ca. 5% fehlberechnungen. Mache ich beides, interrupts ein- und ausschalten und register sichern, so kommt totaler schrott beim Master an. In meinem testaufbau, schreibt der Master den Wert 4 in den Slave. Der Slave addiert nun den wert mit 20, anschliessend liest der master den wert wieder aus, und sollte somit 24 erhalten. Manchmal kommt statt 24 (&b00011000), der wert 207 (&b11001111) oder 12 (&b00001100) beim master an.
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.