Nabend ! Da die Benutzung von Interrupts beim programmieren vom avr in assembler (von c mal abgesehen, darin programmier ich nicht) einige Fallstricke bereit hält hab ich mal das Internet durchforstet um sicherzugehen das bei meinem programm auch alles klappt ! Und nicht solche blöden Fehler wie "tritt hin und wieder auf" vorkommenen. Also meine Frage: zu beginn der ISR schiebe ich die in der ISR benutzten register auf den stack ! das sind bei mir z.B. r16,r17 das statusregister und das Doppelregister zl und zh. am ende der ISR hole ich sie wieder vom stapel. ich dachte damit wäre alles safe ! doch dann hab ich das gefunden: ---Quote anfang http://www.avr-asm-tutorial.net/avr_de/interrupts/int_ressourcen.html Die oben beschriebene Zugriffssteuerung über eine Interrupt-Blockage mit CLI/SEI ist auf jeden Fall dann zwingend, wenn ein Doppelregister außerhalb von Interrupt-Service-Routinen auf einen neuen Wert gesetzt werden muss und innerhalb von Service-Routinen verwendet wird. Zwischen dem Setzen des einen Bytes des Doppelregisters und des zweiten könnte ein Interrupt zuschlagen und einen völlig verqueren Wert vorfinden. Solche Fehler sind teuflisch, weil es in der Regel korrekt funktioniert und nur alle paar Stunden ein Mal dieser Fall eintritt. So einen eingebauten Bug findet man garantiert nicht, weil er sich so selten in freier Wildbahn in der Schaltung zeigt. Daher sollten folgende Regeln gelten: * Register möglichst klar der alleinigen Verwendung innerhalb und außerhalb von Interrupt-Service-Routinen zuordnen. * Jede gemeinsame Nutzung von Registern intensiv auf mögliche Konflikte hin durchdenken. Vorher denken vermeidet die Fehlersuche hinterher. * Vorsicht bei der gemeinsamen Nutzung von Doppelregistern. Interrupts blockieren! Und hinterher nicht vergessen, sie wieder zuzulassen. ---Quote ende Heißt das ich muß die Interrupts beim Benutzen von Doppelregistern trotzdem deaktivieren ? obwohl ich sie am anfang der ISR auf den stack packe? Hauptprogramm: ldi zl,LOW(UART_RX_STRING) ldi zh,HIGH(UART_RX_STRING) wo ist das problem wenn nach dem laden von zl der Interrupt ausgelöst wird, Z sichert, dann verändert, wiederherstellt und dann im hauptprogramm zh geladen wird ?
> wo ist das problem wenn nach dem laden von zl der Interrupt ausgelöst > wird, Z sichert, dann verändert, wiederherstellt und dann im > hauptprogramm zh geladen wird ? Streiche 'wiederherstellt', dann erkennst Du das mögliche Problem. Alternativ streiche 'sichert, dann verändert, wiederherstellt' und setzte stattdessen 'verwendet', dann tritt das selbe Problem (in die andere Richtung) auf. HTH
ist mir nicht klar sorry :-( ich meine ich hab auch kein problem damit die interrupts einfach zu sperren ! ich wills doch einfach nur verstehen ! :-)) bei manchen 16bit registern versteh ichs ja weil sich der 16bit inhalt verändern kann und dann low und high byte nicht mehr zusammenpassen. Aber in meinem beispiel verändert sich doch die adresse im sram von (UART_RX_STRING) durch den interrupt nicht. zl wurde vor dem IRQ erfolgreich geladen, über die ISR hinweg gesichert per stack. und zh wird nach dem irq geladen. das sollte doch gehen. wie gesagt ich verstehs halt net. ich kanns auch einfach als Tatsache hinnehmen, ich meine im datenblatt steht ja auch nur: It is important to notice that accessing 16-bit registers are atomic operations. If an interrupt occurs between the two instructions accessing the 16-bit register, and the interrupt code updates the temporary register by accessing the same or any other of the 16-bit Timer Registers, then the result of the access outside the interrupt will be corrupted. Therefore, when both the main code and the interrupt code update the temporary register, the main code must disable the interrupts during the 16-bit access. vielleicht findet sich ja ein geduldiger Mensch der mich aufklärt ^^ gruß marco
ok vielleicht nicht grade jetzt ! ich geh jetzt auch nach draußen zum feiern hehe frohes neues
Marco Oklitz schrieb: > wo ist das problem wenn nach dem laden von zl der Interrupt ausgelöst > wird, Z sichert, dann verändert, wiederherstellt und dann im > hauptprogramm zh geladen wird ? Da gibts keine Probleme. Diese Probleme mit 16bit-Zugriffe entstehen, wenn du auf ein nicht sicherbares "Ding" zugreifst, also z.B. eine Speicheradresse oder ein I/O-Register. So als Fallbeispiel: Du hast eine 16 bit Variable im SRAM, die die Overflows eines Timers mitzählt (meinetwegen für ne Uhrzeit). Dann läuft das ganze im Worst case so ab: Im Low Byte steht 0xFF im High Byte 0x04 ld r2, lowbyte ;<- hier kommt der interrupt ld r3, highbyte im Interrupt nach dem Sichern ld r16, lowbyte ld r17, highbyte inc r16 brne kein_high_inc inc r17 kein_high_inc: st lowbyte, r16 st highbyte, r17 Interrupt ende, die REgister werden wieder hergestellt, nicht aber die SRAM-Variablen. Im Hauptprogramm steht dann wegen des Interrupts in r2 = 0xFF und r3 = 0x05 obwohl es eigentlich 0x00 und 0x05 sein sollten. Problematik klar? :-)
dein beispiel ist vollkommen einleuchtend also besteht das problem doch nur dann, wenn ich das was ich ich ein register im hauptprogramm laden will sich während des interrupts ändern könnte oder ändern kann.und nicht durch den stack gesafet werden kann. damit kann ich umgehen, das ist einleuchtend. ich dachte das wäre sowas wie ein grundlegendes problem das das high und low byte immer direkt hintereinander geladen werden muß, weil es sonst zu prozessorinternen problemen führt. das es probleme gibt wenn ich die werte ändere ist klar. danke dir
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.